ある旅行予約プラットフォームが、DynamoDBで予約データを管理している。予約検索には「出発地と目的地の組み合わせで検索」と「出発日時の範囲検索」の2パターンがある。現在のテーブルはパーティションキーにreservationId(UUID)、ソートキーにcreatedAtを使っており、両パターンのクエリはすべてScanになっている。最小限の変更でQueryに切り替えるための設計変更を2つ選択してください。
- A. テーブルをScan+FilterExpressionから、Parallel Scanに変更してセグメント数を増やす
- B. LSIを追加: ソートキーをdepartureDateTimeに変更し、出発日時の範囲検索をサポートする
- C. GSI1を追加: パーティションキーに「出発地#目的地」の複合値、ソートキーにdepartureDateTimeを設定する
- D. テーブルのパーティションキーをdepartureDateTimeに変更し、ソートキーにreservationIdを設定する
- E. GSI2を追加: パーティションキーにdepartureDateYear(出発年)、ソートキーにdepartureDateTimeを設定する
解答と解説を見る
正解: C, E
「出発地と目的地の組み合わせ検索」にはGSI1が最適である。パーティションキーに「route#TYO#NYC」のような複合値を使い、ソートキーにdepartureDateTimeを持つことで、KeyConditionExpressionで出発地・目的地を絞り込み、かつ出発日時の範囲もQueryできる。「出発日時の範囲検索」にはGSI2が適切で、年単位でパーティションを分けることでホットパーティションを避けつつ、その年内の日時範囲クエリが可能になる。Dのテーブルパーティションキー変更はreservationIdによる単件取得(主要アクセスパターン)が破壊されるため既存設計を大幅に壊す。AのParallel ScanはScanのスループットを上げるだけでQueryへの変換はできず、読み取りコストも変わらない。BのLSIはテーブル作成時のみ設定可能でテーブル作成後には追加できず、また同じパーティション内でのみソートキー変更なので「出発地×目的地」のフィルタリングはできない。