DynamoDB のテーブル設計は、RDB のそれとは異なる。
テーブル数はなるべく少なくして、非正規化したモデルを設計するべきである。
その背景を深く知るべく、「Amazon DynamoDB におけるシングルテーブル vs マルチテーブル設計」を読んで学んだ内容をまとめてみた。
DynamoDB 特徴
- 多くのDBは、低レベルなビット操作を抽象化して、柔軟なクエリでデータを操作できるようにしている。
- この抽象化によって、DBのスケールや使用量の増加によるコスト増を理解しにくくなる。
- DynamoDB はアプリケーションのスケールに応じたパフォーマンスを実現しようとしている。
- DynamoDB はパーティショニングによる水平スケーリングでパフォーマンスを担保する。
- パーティショニング、BTreeは DynamoDB 特有のものではない。
- 他のDBに比べると、データ構造が剥き出しになっている。
- 項目の操作には完全一致するプライマリキーを指定するCRUD APIと、パーティションキーを指定した複数件取得操作であるQuery APIが提供される。
- あらゆる規模で堅実なパフォーマンスを出すために結合、集計は提供されていない。
- 集計はクエリに関わるレコード数に強く依存し、レコード数は実行前にはわからない。
- DynamoDB はデータ構造を剥き出しにすることで、パフォーマンスがわかりやすくなっている。
- 読み込み書き込みのデータサイズ、トラフィック量が予想できれば、コストは計算可能である。
- この透過的な課金モデルが、シングルテーブル設計を使用する理由の一つである。
シングルテーブル設計のススメ
- シングルテーブル設計は、単一のサービスに対して適用されるべきである。
- 筆者の経験則では、RDBMSで頻繁に結合するようなまとめてアクセスされるデータモデルは一つのテーブルに格納するのが良い。
- そうではない場合は、必要に応じて分離しても良い。
- シングルテーブルを採用することで、クエリ数を減らせる。
- シングルテーブルを採用することで、更新頻度の異なるデータの読み込み、書き込みを最適化できる。
- 読み込みはまとめて取得したいが、書き込みは項目を分けて実行するような複数の項目を格納できる。
- 更新頻度の高い属性を異なる項目として切り分けることで、一度の書き込みのコストを下げられる。
- 書き込む項目のサイズが大きいほどコストは増加する。
- シングルテーブルを採用することで運用コストを下げられる。
シングルテーブルで困ること
- DynamoDB Stream のコンシューマの同時起動数は2なので、頻繁にコンシュームが発生するようなデータが一つのテーブルに格納されていると、スロットリングが発生しやすい。
- オンラインの分析基盤へのエクスポートには不向きである。
- テーブル内に、append-only なデータとそうではないデータがあった時、そのどちらも完全にエクスポートするのは遅い。
- append-only なデータを DynamoDB Stream で分析基盤に転送するのは上手く機能する。
- それぞれのデータを、異なる方法でエクスポートするにはテーブルを分けた方が良い。
- 頻繁に更新が入るテーブルは完全にエクスポートし、append-only なテーブルはストリーミング処理してエクスポートする。
まとめ
結局のところ、シングルテーブルの利点が重要でなければ、複数テーブル設計を採用しても良い。
ただ、正規化されたモデルを避けることは絶対に正しいので、その点だけはブレてはいけない。