データモデリング
SQL が教えた癖でエンティティごとに 1 テーブルへ正規化し、子の行が親でキー付けされていないテーブルを出荷する。その結果、必要な画面はフル Scan になる。移行コストはプロダクトが本番に出てから降りかかる。
DynamoDB のモデリングはアクセスパターンから始まる。機能が必要とする読み書きを列挙し、それを満たすキーと GSI を設計する。シングルテーブル設計は、パターンが重なるときに多くのエンティティ型を 1 テーブルに詰める。それはトレードオフだ。このセクションはそのパターンと、複数テーブルの方が安く作れて運用できるケースの両方を教える。
このセクションで身につくこと
- キーより先にアクセスパターンを書き出し、各パターンを
QueryかGetItemに対応づけられる。 - エンティティ接頭辞、オーバーロードされたキー、ホットな部分集合向けのスパース GSI を備えたシングルテーブルレイアウトを設計できる。
- 別テーブルが 1 テーブルの複雑さに勝つときを見分けられる。
- すべてのアイテムに
type属性を付け、非正規化したコピーをファンアウト更新で同期させ続けられる。
読む順番
- データのモデル化方法:ワークシート(アクセスパターンを入れ、キー設計と GSI を出す)。
- シングルテーブル設計:メンタルモデル(1 テーブル、多数のエンティティ型、同居のためのキー選択)。
- シングルテーブルにしないとき:重い分析、無関係なエンティティに対する単純な CRUD、そして独立してスケールしたり障害を起こしたりするエンティティ。
- type 属性:各アイテムのエンティティに名前を付け、コードが混在した
Queryを振り分け、GSI を絞り込み、後でデータを分割できるようにする。 - 非正規化:2 ホップ目を避けるためにフィールドを複製する。更新で何を失うかを知る。
- シングルトンアイテム:機能フラグや設定のようなアプリ全体の状態を保持する、固定キーの 1 アイテム。
シングルテーブル設計が輝くのは、1 回の Query が親とその子を返すときだ。例えば
PK = WS#acme が、ワークスペースのレコード、そのドキュメント、それらのコメントをソート順で返すときである。
2 つのサービスが無関係なドメインを所有し、新機能のたびに別のオーバーロード GSI が要るときは失敗する。シングルテーブル設計を使うべきでないときは、複数テーブルの方が良い選択になるケースを扱う。
非正規化は表示用フィールドを、それを表示する行(多くの場合は子)へ複製し、一覧画面が 2 ホップ目を要しないようにする。トレードオフは書き込みのファンアウトだ。ブログの著者名を変えると、その名前をコピーしたすべての投稿に触れることになる。
シングルトンアイテムは 1 つの定数キー(PK = SETTINGS#APP、SK = FLAGS#V1)の下に置かれ、アプリ全体のフラグや設定を保持する。GetItem で読み、キャッシュし、カウンターのような高頻度の書き込みはそこに置かない。
DynoTable で試す
AWS に触る前にキーをスケッチする。無料のシングルテーブル設計プランナー はアクセスパターンの一覧を PK/SK 配置、GSI 提案、サンプルアイテム、CreateTable
JSON に変える。テーブルを作成し、サンプルアイテムをいくつか追加して、それらがコレクションにどう着地するかを DynoTable で眺める。
キーが満たさないパターンには、SQL Workbench が境界づけられた読み取りの上で、フィルターと集約(GROUP BY、COUNT、SUM)をクライアント側で実行する。その JOIN は別々のテーブルをまたいで機能する。探索に使い、本番の読み取りパスには使わないこと。Workbench の実行、編集、書き込みのステージングは有料プランで、閲覧とキーによるクエリは無料だ。
DynoTable をダウンロードして、ライブテーブルに対してこれらのレイアウトをモデル化し、閲覧しよう。