データベースとDynamo DBの設計手法が全然違うので言語化してみる。また、設計時は最小限でいいので、必ず技術検証しつつ設計に問題なさそうか確認してから行うこと。
レビュワー頼りだとかなり痛い目を見る(認識のズレ・そもそも実装できない)ので要注意。
言語化する前に、まずは用語の確認から。
用語集
- PK (Primary Key):項目を一意に識別する主キー。DynamoDBではパーティションキー (Partition Key)を指す場合が多い。 (docs.aws.amazon.com)
- SK (Sort Key):同一PK内で並び順/グルーピングを与えるソートキー。範囲取得に利用。 (docs.aws.amazon.com)
- GSI (Global Secondary Index):テーブルとは別のPK/SKで高速クエリを可能にするグローバル二次インデックス。 (docs.aws.amazon.com)
- LSI (Local Secondary Index):同一PKで別のSKを張るローカル二次インデックス。 (docs.aws.amazon.com)
- TTL (Time to Live):期限切れアイテムの自動削除機能。ログ/一時データに有効。 (docs.aws.amazon.com)
- ACID:Atomicity/Consistency/Isolation/Durability。RDBのトランザクション特性。
- JOIN:複数テーブルの行をキーで結合して結果セットを作るSQL操作。
- ER (Entity-Relationship):エンティティと関係を図式化するモデリング手法。
- Global Tables:DynamoDBのマルチリージョン複製機能。 (docs.aws.amazon.com)
前提
- RDBは「正規化→関係(ER)→JOINで再構成」
- データ整合性・柔軟な集計・標準SQLが強み
- スキーマ中心思考
- DynamoDBは「アクセスパターン起点→非正規化→キー設計&インデックスで取りに行く」
- 単一/少数テーブル、複合キー、GSI、局所性の確保がコア
- 水平スケールと低レイテンシが強み(docs.aws.amazon.com)
一覧比較(設計観・操作・運用)
| 観点 | Relational Database | DynamoDB |
|---|---|---|
| 設計の出発点 | 正規化・エンティティ/関係の同定。重複排除と参照整合性を最優先。(docs.aws.amazon.com) | アクセスパターン(どんなクエリを最速/最安で出すか)からキー・項目配置を決める。(docs.aws.amazon.com) |
| スキーマ | 厳格スキーマ(列定義)。変更はマイグレーション。(Amazon Web Services, Inc.) | 柔軟スキーマ(属性は可変)。ただし設計は厳格:キー/インデックスが本質。(docs.aws.amazon.com) |
| データ配置 | 正規化&JOINで再構成。(docs.aws.amazon.com) | 非正規化して関連データを近接配置(同一PK+SKでソート)。(docs.aws.amazon.com) |
| テーブル数 | 正規化に応じて複数テーブル。 | 単一または少数テーブルが原則(例外:高ボリューム時系列等)。(docs.aws.amazon.com) |
| クエリ手段 | SQL(JOIN/集計/副問い合わせ)。 | PK/SK、GSI/LSIで取り出し。スキャンは最終手段。(docs.aws.amazon.com) |
| リレーション表現 | 外部キー+JOIN。 | 隣接リスト/複合キーで1:N, N:Nを表現(アクセスに最適化)。(docs.aws.amazon.com) |
| スケーリング | 垂直/一部水平。シャーディングは重作業。(docs.aws.amazon.com) | 自動水平スケール(パーティション分散)。ホットパーティションを避けるキー設計が重要。(docs.aws.amazon.com) |
| トランザクション | ACIDが標準。 | TransactWrite/Readあり(制約は考慮)。ユースケースで使い分け。※ドキュメント外周知 |
| グローバル展開 | レプリケーション構築が重い。 | Global Tablesでマルチリージョン複製(容量整合など設計要)。(docs.aws.amazon.com) |
| 代表的な強み | アドホック分析、複雑JOIN、厳密整合性。 | 低レイテンシ/超高スループット、可用性、運用の軽さ、コスト予測。(docs.aws.amazon.com) |
| 代表的な落とし穴 | 正規化過多でクエリ遅延、スキーマ変更コスト。 | アクセス未定義のまま設計、低カーディナリティPK、無闇なスキャン/巨大アイテム。(docs.aws.amazon.com) |
設計プロセス(RDB版)
大まかにこんな感じ。
- ① ユースケース/制約(整合性/分析/レポート)を整理
- ② エンティティ・属性・関係 → 正規化(第3正規形目安)(docs.aws.amazon.com)
- ③ 主キー/外部キー/制約 → インデックス設計
- ④ 代表クエリの実行計画とコストを検証
- ⑤ マイグレーション/運用設計(バックアップ、リカバリ、監視)
設計プロセス(DynamoDB版)
大まかにこんな感じ・・・?
- アクセスパターン列挙(画面/API単位で“取りたい形”をリスト化)(docs.aws.amazon.com)
- 項目グルーピング:関連データは同一PKに寄せ、SKで時系列/種類を並べる(局所性を最大化)。(docs.aws.amazon.com)
- 主キー設計:高カーディナリティのPKで負荷分散、SKは並びを活用。(docs.aws.amazon.com)
- GSI設計:必要最小限でSparse Index(日本語だと疎インデックスというらしい。わかりづらい)を活かし、インデックス過負荷を回避。(docs.aws.amazon.com)
- 単一テーブル指向:タイプ識別子(
PK=USER#123,SK=ORDER#2025-10-31等)で多エンティティ共存。(docs.aws.amazon.com) - ホットパーティション対策:書き込みシャーディング/ランダム化/時間窓分割などを検討。(docs.aws.amazon.com)
- サイズ&TTL:大きいバイナリはS3参照、時限データはTTLで自動削除。(docs.aws.amazon.com)
これは実際に検証が必要なので、一旦言語化だけしておく。
典型ユースケースでの思考法
- 「ユーザー詳細+直近注文一覧」
- RDB:
JOIN users x orders、索引で最適化。(docs.aws.amazon.com) - DynamoDB:
PK=USER#<id>に注文アイテムを同居、SKをORDER#<ts>で降順取得。必要ならGSI1にstatusを貼る。(docs.aws.amazon.com)
- RDB:
- 多対多(タグ付け等)
- RDB:中間テーブル。
- DynamoDB:隣接リストで双方のエッジを格納し、必要な向きに最短クエリ。(docs.aws.amazon.com)
- 時系列
- RDB:パーティショニングや集計テーブル。
- DynamoDB:SKの先頭を時刻に、範囲取得を高速化。高ボリュームはテーブル分離も検討。(docs.aws.amazon.com)
どちらを選ぶのか?意思決定の指針
- 未知の分析/多彩なクエリが多いRDB優位(後から取りたい切り口が増える)。(Amazon Web Services, Inc.)
- アクセスパターンが明確で低遅延・超スケール必須→ DynamoDB優位(読み書き性能と可用性、コスト最適)。(docs.aws.amazon.com)
- グローバル低遅延やサーバーレス指向→ DynamoDB + Global Tables/DAX等を検討。(docs.aws.amazon.com)
自分向け: DynamoDBの設計チェックリスト
主要画面/APIごとにキー1本で取れるか?(スキャン禁止)(docs.aws.amazon.com)
PKのカーディナリティは十分か?ホット回避はできるか?(docs.aws.amazon.com)
GSIは目的別に最小限になっているか?Sparse Indexでコスト抑制できているのか?(docs.aws.amazon.com)
単一/少数テーブルでデータ局所性を確保できてる?(docs.aws.amazon.com)
大きな属性は外出し(S3使う)、TTLで寿命管理できてる?(docs.aws.amazon.com)
参考(AWS公式)
- DynamoDB ベストプラクティス(キー/インデックス/時系列/サイズ)(docs.aws.amazon.com)
- NoSQL設計の基本(アクセスパターン、局所性、テーブル数)(docs.aws.amazon.com)
- 高カーディナリティPK・Sparse GSI・隣接リスト等の指針(Prescriptive Guidance)(docs.aws.amazon.com)
- RDBの基礎・違いの総覧(What is RDB / Relational vs Non-Relational)(Amazon Web Services, Inc.)
- スケーリング比較(RDB vs DynamoDB)(docs.aws.amazon.com)
TomoMemo.dev