導入
「アクセスが急増するかもしれない」「スキーマを固定したくない」「単一桁ミリ秒の応答が欲しい」という要件には、RDBMSではなく DynamoDB が答えになります。設計の考え方がRDSとは根本的に違う点を押さえます。
説明
Amazon DynamoDB は、フルマネージドのNoSQL(キーバリュー/ドキュメント型)データベースです。テーブルの容量をAWSが自動的にスケールし、単一桁ミリ秒の応答速度を維持します。
テーブル設計の核となるのがキー設計です。
| キー | 役割 |
|---|---|
| パーティションキー(PK) | データの格納先パーティションを決める。ハッシュ分散の基準 |
| ソートキー(SK・任意) | 同じPK内でのデータの並び順・範囲検索の基準 |
RDBMSのように後から自由にJOINやWHEREで検索できるわけではなく、アクセスパターンを先に設計してからテーブル構造を決める必要があります。
キャパシティモードも設計上の重要な選択です。
| モード | 特徴 | 向いているケース |
|---|---|---|
| オンデマンド | リクエスト数に応じて自動課金・自動スケール | トラフィックが読めない・スパイクが多い |
| プロビジョンド | 読み書きキャパシティを事前に確保(Auto Scaling併用可) | トラフィックが予測可能・コストを抑えたい |
検索の柔軟性を補うのがセカンダリインデックスです。
- GSI(グローバルセカンダリインデックス):PK・SKを元テーブルと別に定義でき、後から追加もできる
- LSI(ローカルセカンダリインデックス):PKは元テーブルと同じでSKだけ別に定義。テーブル作成時にしか追加できない
flowchart LR
Table["DynamoDBテーブル<br/>PK: UserId / SK: OrderDate"] --> GSI["GSI: PK違いの検索軸を追加"]
Table --> LSI["LSI: 同じPKで別のソート順"]
SAAではこう問われる:「予測不能なトラフィックでも自動スケールしたい」→ オンデマンドモード。「決まったパターンでコストを最適化したい」→ プロビジョンド+Auto Scaling。「別の切り口でも検索したい」→ GSI追加。
具体例
フードデリバリーアプリの「注文テーブル」をDynamoDBで設計します。RDBMSと発想が逆なのがポイントです。
- まずアクセスパターンを先に決める … 「ユーザーの注文履歴を新しい順に見たい」が主。→ パーティションキー=
UserId、ソートキー=OrderDate。これで「あるユーザーの注文を日付順に」が高速に引ける。 - キャパシティモードを負荷で選ぶ … 深夜0時のクーポン配布で注文が読めないスパイクを起こす。→ オンデマンドモードで自動スケール。もし平常時が安定していてコスト重視なら、プロビジョンド+Auto Scalingもあり。
- 別の切り口で検索したくなったら … 運営が「配達員ごとの注文一覧」も見たくなった。しかし主キーは
UserIdなので引けない。→DeliveryIdをキーにしたGSIを後から追加。
ここでRDBMS脳のまま「テーブルを正規化してJOINで配達員別を出す」を選ぶと不正解。DynamoDBはアクセスパターンありきで設計し、新しい検索軸はGSIで足す——この発想の転換がSAAで問われます。
読んでみよう
DynamoDBの問題は「RDBMSの発想で正規化・JOINしようとする誤答」を誘う選択肢が定番です。DynamoDBはアクセスパターンありきの設計であることを常に思い出してください。