DynamoDBでできないこと

Blog

RDBに慣れている身からするとDynamoDBは制約が多いように感じます。

そこで、実務で直面したDynamoDBで「できないこと」を書き出してみます。


1. JOINできない

DynamoDBはRDBとは異なり、データの正規化よりもアクセスパターン最適化のための非正規化が前提となります。
そのため、RDB的な機能である「複数テーブルの結合」はサポートされていません。

例えばユーザー情報と注文情報の結合がしたい場合、DynamoDBでは同一テーブル内に格納する or 複数回のクエリを実行する必要があります。

2. 柔軟な検索ができない

DynamoDBの検索能力は、あらかじめ定義したアクセスパターンに最適化する思想です。

そのため、以下のようなクエリは使用できません。

  • 部分一致検索(LIKE %keyword%
  • OR条件
  • 複数属性を組み合わせたソート

代替手段として、GSI追加・単一テーブルデザイン再設計が必要になります。

3. Sort Key以外への範囲検索ができない

DynamoDBではPKのPrefix検索はできません。

begins_withbetweenが使えるのは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。。