「Amazon DynamoDB におけるシングルテーブル vs マルチテーブル設計」を読んだメモ

DynamoDB のテーブル設計は、RDB のそれとは異なる。

テーブル数はなるべく少なくして、非正規化したモデルを設計するべきである。

その背景を深く知るべく、「Amazon DynamoDB におけるシングルテーブル vs マルチテーブル設計」を読んで学んだ内容をまとめてみた。

DynamoDB 特徴

  • 多くのDBは、低レベルなビット操作を抽象化して、柔軟なクエリでデータを操作できるようにしている。
    • この抽象化によって、DBのスケールや使用量の増加によるコスト増を理解しにくくなる。
  • DynamoDB はアプリケーションのスケールに応じたパフォーマンスを実現しようとしている。
  • DynamoDB はパーティショニングによる水平スケーリングでパフォーマンスを担保する。
  • パーティショニング、BTreeは DynamoDB 特有のものではない。
    • 他のDBに比べると、データ構造が剥き出しになっている。
  • 項目の操作には完全一致するプライマリキーを指定するCRUD APIと、パーティションキーを指定した複数件取得操作であるQuery APIが提供される。
  • あらゆる規模で堅実なパフォーマンスを出すために結合、集計は提供されていない。
    • 集計はクエリに関わるレコード数に強く依存し、レコード数は実行前にはわからない。
  • DynamoDB はデータ構造を剥き出しにすることで、パフォーマンスがわかりやすくなっている。
  • 読み込み書き込みのデータサイズ、トラフィック量が予想できれば、コストは計算可能である。
    • この透過的な課金モデルが、シングルテーブル設計を使用する理由の一つである。

シングルテーブル設計のススメ

  • シングルテーブル設計は、単一のサービスに対して適用されるべきである。
  • 筆者の経験則では、RDBMSで頻繁に結合するようなまとめてアクセスされるデータモデルは一つのテーブルに格納するのが良い。
    • そうではない場合は、必要に応じて分離しても良い。
  • シングルテーブルを採用することで、クエリ数を減らせる。
    • RDBMS のような結合されたデータを取得する際には、クエリを複数回発行したのちにアプリケーションで結合しないといけない。
    • DB へのI/Oはアプリケーションの中でも最も遅い処理であるので、非効率的である。
    • テーブルを分離するのではなく、同じパーティションキーを持つ別の性質の項目として一つのテーブルに格納することで、一つのクエリでまとめて取得できる。
  • シングルテーブルを採用することで、更新頻度の異なるデータの読み込み、書き込みを最適化できる。
    • 読み込みはまとめて取得したいが、書き込みは項目を分けて実行するような複数の項目を格納できる。
    • 更新頻度の高い属性を異なる項目として切り分けることで、一度の書き込みのコストを下げられる。
      • 書き込む項目のサイズが大きいほどコストは増加する。
  • シングルテーブルを採用することで運用コストを下げられる。
    • DynamoDB ではテーブルごとに設定、監視、バックアップが必要である。
      • とはいえ、1テーブルに対する運用自体はそこまで重くはない。
    • AWS アカウントごとにテーブル数の上限が設定されているので、大規模なサービスの場合テーブル数の上限に到達する可能性がある。
    • パーティションごとにバーストキャパシティを提供しているので、テーブルのパーティションキーのカーディナリティを高めればスロットリングは起こりづらくなる。

シングルテーブルで困ること

  • DynamoDB Stream のコンシューマの同時起動数は2なので、頻繁にコンシュームが発生するようなデータが一つのテーブルに格納されていると、スロットリングが発生しやすい。
  • オンラインの分析基盤へのエクスポートには不向きである。
    • テーブル内に、append-only なデータとそうではないデータがあった時、そのどちらも完全にエクスポートするのは遅い。
    • append-only なデータを DynamoDB Stream で分析基盤に転送するのは上手く機能する。
    • それぞれのデータを、異なる方法でエクスポートするにはテーブルを分けた方が良い。
      • 頻繁に更新が入るテーブルは完全にエクスポートし、append-only なテーブルはストリーミング処理してエクスポートする。

まとめ

結局のところ、シングルテーブルの利点が重要でなければ、複数テーブル設計を採用しても良い。

ただ、正規化されたモデルを避けることは絶対に正しいので、その点だけはブレてはいけない。