DynamoDBでできないこと
RDBに慣れている身からするとDynamoDBは制約が多いように感じます。
そこで、実務で直面したDynamoDBで「できないこと」を書き出してみます。
1. JOINできない
DynamoDBはRDBとは異なり、データの正規化よりもアクセスパターン最適化のための非正規化が前提となります。
そのため、RDB的な機能である「複数テーブルの結合」はサポートされていません。
例えばユーザー情報と注文情報の結合がしたい場合、DynamoDBでは同一テーブル内に格納する or 複数回のクエリを実行する必要があります。
2. 柔軟な検索ができない
DynamoDBの検索能力は、あらかじめ定義したアクセスパターンに最適化する思想です。
そのため、以下のようなクエリは使用できません。
- 部分一致検索(LIKE
%keyword%) - OR条件
- 複数属性を組み合わせたソート
代替手段として、GSI追加・単一テーブルデザイン再設計が必要になります。
3. Sort Key以外への範囲検索ができない
DynamoDBではPKのPrefix検索はできません。
begins_withやbetweenが使えるのはSort Keyのみです。
Partition Keyは完全一致でしか検索できません。
例:
begins_with(PK, "USER#") // 不可能
もしPrefix検索が必要であれば、PK設計やインデックス構成を見直す必要があります。
4. SQL的なページング(OFFSET)ができない
DynamoDBは行番号の概念がないため、以下のようなクエリは使用できません。
LIMIT 10 OFFSET 20
代わりに、前回の読み込み位置を示す LastEvaluatedKey を使用してページングします。
飛びページや最終ページへ直接移動するUXを実装したい場合は、アプリ側でキーを保存・管理する必要があります。
5. 属性名に予約語が使用できない
DynamoDBには、クエリ構文の一部として利用される予約語が存在します。
予約語は内部で特別な意味を持つため、そのまま属性名(カラム名)として使用するとエラーになる場合があります。
例えば Name, Status, Value といった一般的な単語も対象に含まれます。
回避手段としてはExpressionAttributeNames を使用して別名を付与します。
ExpressionAttributeNames: {
"#st": "Status"
}
6. 大量データの一括削除・更新が難しい
DynamoDBは大量データの操作が得意ではありません。
- Scanがパフォーマンス・料金ともに高コスト
- BatchWrite / Transaction に件数制限あり
定期削除が発生するデータは、TTLによる自動削除などを検討する必要があります。
まとめ
DynamoDBは「後からクエリでどうにかする」タイプのデータベースではありません。
そのため以下を明確にできない場合はリスクが高いと言えます。
- どの粒度でデータにアクセスするか
- ソート条件は何か
- 検索条件が将来的に増える可能性はあるか
逆に言えばアクセスパターンが明確で、JOINを必要としないシステムに強いです。
まさに設計がすべてを決めるDB。。