Amazon DynamoDBのテーブルにおいて、パーティションキーが `UserId` に設定されています。新たに「`EmailAddress` を使ってユーザーを高速に検索(Query)したい」という要件が追加されました。この要件を満たすための最適なアプローチと、その仕様に関する説明として正しいものはどれですか?
解説
正解は「EmailAddressをパーティションキーとするGlobal Secondary Index (GSI) を作成する。GSIへのデータ同期は非同期で行われるため、結果整合性(Eventually Consistent)となる」です。DynamoDBでは、ベーステーブルのキー(今回は `UserId`)以外の属性で効率的にQueryを実行するためにGSIを使用します。GSIはベースと異なるパーティションキーを設定できるため要件に最適です。ただしデータ同期は非同期で行われるため、読み取りは常に結果整合性となります。他の選択肢について、GSIは強力な整合性をサポートしません。LSIはテーブル作成後に後付けできず、ベースと同じパーティションキーが必要です。`Scan`による全件検索はデータ量に比例してパフォーマンスが低下しコストも増大するため実務では避けます。プライマリキー以外の属性で高速検索するにはDynamoDBはKVS(キーバリューストア)の性質上、「指定したキーに一致するデータを取得する」のは得意ですが、RDBのように任意の属性で柔軟に検索するのは苦手です。インデックスなしで検索しようとすると Scan でテーブルの全データを読み込むことになり、データ増加に伴いパフォーマンスが破綻します。そこでGSIが活躍します。GSIを作成すると、内部的に「指定した別の属性(今回は EmailAddress)をパーティションキーとする目次用の裏テーブル」が自動構築されます。これにより、本来のキー以外でも低コストで高速な Query 操作が可能になります。LSIとGSIの違いと「結果整合性」の注意点もう一つのインデックスであるLSI(Local Secondary Index)との違いも、実務でよく問われるポイントです。GSI: パーティションキーを自由に変更可能。テーブル稼働後でも追加・削除できる。読み取りは結果整合性のみ。LSI: ベーステーブルと同じパーティションキーが必須。テーブル作成時にしか作れない。強力な整合性での読み取りが可能。実務で最も注意すべきは、GSIが結果整合性(Eventual Consistency)である点です。ベーステーブルへのデータ書き込み直後にGSIから検索すると、わずかな同期遅延により最新データが取得できない可能性があります。「登録直後にEmailで検索する」ような要件では、この遅延を考慮し、重要な読み取りは必ずベーステーブルのキー(UserId)で行うなどの設計が求められます。