この記事でわかること
- DynamoDBにおける「アクセスパターン設計」の考え方
- アクセスパターンの洗い出し手順(実務で使える順番)
- そのままコピペで使える洗い出しテンプレ(Markdown)
- 「最初から完璧に設計できない」問題への向き合い方
前提:DynamoDB設計で一番大事なこと
DynamoDBは、RDBのように「テーブル構造を決めてからクエリを書く」設計思想ではなく、
「どう取得するか(アクセスパターン)」を先に決めてから、キー設計(PK/SK)へ落とすのが推奨される。
根拠(ソース)
- AWS公式ドキュメント(Best Practices / Design patterns)
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/best-practices.html - AWS Database Blog(Single-table design 関連)
https://aws.amazon.com/jp/blogs/compute/creating-a-single-table-design-with-amazon-dynamodb/
なぜアクセスパターン設計が必要なのか
DynamoDBでは以下が「後から簡単には変えられない」要素になる。
- Primary Key(パーティションキー / ソートキー)
- LSI(ローカルセカンダリインデックス)
- Query前提のデータ構造(キーの並び・プレフィックス設計など)
したがって、設計の最初に「どんな取得が必要か」を言語化しないと、
後工程で Scan に寄ったり、破壊的変更(テーブル作り直し)になりやすい。
設計フロー
- ユースケースを洗い出す(画面/API視点)
- アクセスパターンに落とす(取得条件・並び順・想定件数)
- PK / SK を設計する(Query/GetItemに乗る形)
- 必要に応じて GSI / LSI を検討する
この記事では 1〜2 を扱う。
ステップ1:ユースケースを洗い出す(画面/API視点)
最初はDBのことを忘れて「何が欲しいか」を列挙する。
例(ユーザーと投稿があるサービス):
- ユーザー詳細を表示したい
- ユーザー一覧を表示したい
- 特定ユーザーの投稿一覧を表示したい
- 特定ユーザーの最新投稿を1件だけ取得したい
- 投稿詳細を表示したい
ポイント:
ここでは「どうやって取るか」ではなく「何を取るか」だけを書く
ステップ2:ユースケースをアクセスパターンへ変換する
ユースケースを「DBアクセス」として具体化する(取得条件・並び順・件数)。
例:
| No | アクセス内容 | 取得条件 | 並び順 | 想定件数 | 備考 |
|---|---|---|---|---|---|
| 1 | ユーザーをIDで取得 | userId | - | 1 | GetItem想定 |
| 2 | ユーザー一覧取得 | - | createdAt(降順) | 10〜100 | Query想定 |
| 3 | ユーザーの投稿一覧 | userId | createdAt(降順) | 数十 | Query想定 |
| 4 | ユーザーの最新投稿取得 | userId | createdAt(降順) | 1 | Query + Limit |
| 5 | 投稿をIDで取得 | postId | - | 1 | GetItem想定 |
GetItem / Query を意識する
アクセスパターンを洗い出す段階で、ざっくり以下を意識するとブレにくい。
-
GetItem
- キー(PK、必要ならSK)を完全一致で指定
- 返るのは基本1件
- 「詳細表示」に向く
-
Query
- PKは必須(※テーブルまたはインデックスのPK)
- SKでソートや範囲指定ができる
- 「一覧」「時系列」「絞り込み」に向く
この時点で、一覧が多いなら「Query前提のキー設計」が必要だと判断できる。
アクセスパターン洗い出しテンプレ(コピペ用)
以下をそのまま貼り付けて使う。
テンプレ(最小版)
| No | ユースケース | 取得条件 | 並び順 | 想定件数 | 備考 |
|---|---|---|---|---|---|
| 1 | |||||
| 2 | |||||
| 3 |
アクセスパターン一覧(実務テンプレ)
前提
- 想定スケール(ユーザー数/データ件数):
- 想定トラフィック(ピークRPS/平均RPS):
- 1リクエストあたりの返却件数(目安):
- 単一テーブル設計を検討するか:
- 強い整合性(Strongly consistent read)が必要な箇所:
| No | ユースケース | API/画面 | 取得条件 | フィルタ条件 | 並び順 | 想定件数 | 更新頻度 | 一貫性要件 | 優先度 | 備考 |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | ユーザー詳細 | GET /users/{id} | userId | - | - | 1 | 中 | 強/結果整合 | 高 | GetItem想定 |
| 2 | ユーザー一覧 | GET /users | - | status=active | createdAt(降順) | 10〜100 | 低 | 結果整合 | 中 | Query想定 |
| 3 | 投稿一覧 | GET /users/{id}/posts | userId | - | createdAt(降順) | 数十 | 中 | 結果整合 | 高 | Query + SK時系列 |
| 4 | 最新投稿 | GET /users/{id}/posts/latest | userId | - | createdAt(降順) | 1 | 中 | 結果整合 | 中 | Query + Limit=1 |
| 5 | 投稿詳細 | GET /posts/{id} | postId | - | - | 1 | 中 | 強/結果整合 | 高 | GetItem想定 |
よくある勘違いと対策
勘違い:最初から全アクセスパターンを完璧に決めないといけない
対策:まず「確実に必要なアクセス」を優先度つきで固め、後から増えるものは段階的に対応する。
※段階的対応の典型:
- 新しい取得軸が増えた → GSI追加を検討
- 取得の形が増えすぎた → テーブル分割を検討
(ただし、設計の方向性は公式の設計指針を参照すること)
チェックリスト
- Scan前提になっていないか?
- 「一覧」「時系列」があるのに GetItem で済ませようとしていないか?
- 並び順(昇順/降順)を要件として明文化できているか?
- 返却件数の上限(ページング想定)を書けているか?
- 「後で使うかも」でアクセスパターンを増やしすぎていないか?
まとめ
- DynamoDBの設計は「アクセスパターンの言語化」から始める
- 取得条件・並び順・想定件数を書くだけで、キー設計(PK/SK)の方向性が見える
- テンプレを埋めることで、チーム内の認識齟齬も減らせる