DynamoDB の GSI と LSI
グローバルセカンダリインデックス (GSI) もローカルセカンダリインデックス (LSI) も、
テーブルのキーではない属性で Query できるようにします。両者は互換ではありません —
その違いが、どちらのパターンにどちらが必要かを決めます。
重要な違い
| GSI | LSI | |
|---|---|---|
| パーティションキー | **任意 の属性 | テーブルと 同じ** |
| ソートキー | 任意の属性 | 任意の属性 |
| 作成できる時期 | いつでも | テーブル作成時のみ |
| 整合性 | 結果整合性のみ | 強い整合性が利用可能 |
| キャパシティ | 独自 | テーブルと共有 |
| 書き込み伝播 | 非同期(結果整合性) | 同期(アトミック) |
| テーブルあたり最大数 | 20(既定、引き上げ可) | 5(ハード) |
| 10 GB パーティション上限 | なし | あり(PK ごと) |
経験則
- 異なるパーティションキー が必要(例: 注文を
customerではなくstatusで 検索)? その場合は GSI が必要です — LSI は再パーティションできません。 - 同じパーティション内での2つ目のソート順 が必要 — LSI はテーブルの パーティションキーをそのまま保ち、別の ソート キーだけを差し替えます — それを あらかじめ決め、強い整合性のある読み取りが欲しい? その場合は LSI が合います。
選択は1つの問いに帰着します — どちらのキーを変えるのか:
異なるパーティションキーは GSI を強制し、同じパーティションでの別のソートキーは LSI が合う唯一のケースです。
実際には、ほとんどのチームがほぼ GSI だけを使います。後から追加でき、独立して スケールし、10 GB のパーティション上限の対象でもないからです。1つの GSI のキーを オーバーロードして複数のパターンに使ってください — シングルテーブル設計 を参照。
Scan をなくすために GSI を追加するなら、それが 独自 の 読み取り/書き込みキャパシティを持つことを忘れないでください。その追加コストを 料金計算ツール で見積もり、 DynoTable を試して コミット前にインデックスの射影属性を確認してください。