DB設計したいNight #4 そーだいさんと失敗から学びながらDB設計したいnightに行ってきた #dbsekkeinight

DB設計したいNight #4 そーだいさんと失敗から学びながらDB設計したいnightに行ってきました。

dbnight.connpass.com

所感

今回はパネルディスカッション形式でパネラーの失敗事例を題材にトークする感じ。事例を見てすぐに解決策を説明されてて、培ってきた経験とノウハウが圧倒的だなと感じました。短い時間でしたが、学びや刺激がありました。

今回のディスカッションで話していたことは書籍の内容がベースになっているものが多かったです。DB設計は奥が深いっす。まだ読み途中なので引き続き勉強しよう。

失敗から学ぶRDBの正しい歩き方 (Software Design plus)

以下、メモから抜粋。

桁、桁数、フォーマットが想定と違うケース。

  • アプリケーションに合わせたデータとマッピングするテーブルを用意する
  • トリッキーな手段で対応せず基本に忠実に
  • 実際のデータがどうなっているかは意識すること

共通項目が多いが部分的に異なる。STI (継承関係を1テーブルで表すこと) を採用したケース。

  • アプリとDBの親子関係は一致させる必要はない
  • 親子関係を逆転させる (共通テーブルを子にする)
  • typeごとにVIEWを用意する
  • PostgreSQLの継承を使う
  • 最初に小さく作る
    • あとからくっつけるのは簡単
    • 最初から大きく作るとあとから分けるのは大変

  • 共通テーブルのIDと親テーブルのIDx2を持つ関連テーブル
    • 親テーブルのIDの排他を担保するためにCHECK制約を使う
  • 共通テーブルのIDを親テーブルが持つ
  • 共通テーブルにフラグを持たせがち
    • 1つのテーブルに複数のステータスや状態を持たせない
  • 複数のステータスを条件にする場合は別テーブルに分ける
  • その共通項目は本当に共通なのかをよく考える

なんでも一発で取れるVIEWを用意したが、JOINが多すぎてパフォーマンスがわるい。画面などの用途ごとにVIEWを用意したが、VIEWの数が多くなり、VIEW同士のJOINやVIEW間の依存が煩雑になったケース。カラム追加でどこに影響があるか特定するのが困難に。

  • キャッシュ、マテビュー、サマリーテーブル
  • 更新頻度の少ないデータはjsonにしてS3に置いてDBアクセスを減らしたり
  • VIEWからVIEWを作る、2階層のキャッシュはNG
    • 古いキャッシュが残らないように
    • リフレッシュの順序を考慮する必要があったり
  • 最初にしっかり論理設計をしてから物理設計をする
  • VIEWやマテビューを使うときは、設計にミスがありそれをRDBの機能でカバーするということ
    • 可能であれば設計を見直す方がよい

  • VIEWを使うケース
    • リファクタリング時に互換性を保ちたいとき (テーブル分割など)
    • セキュリティ上、見せたくないカラムを隠蔽したいとき
      • 誤って select * ... してセキュアなデータが露出しないように
    • 事前に(複数の)フラグを解決したVIEWを用意したいとき
      • アプリ側で条件を書くと複雑になるため

不要になったカラムは消すか?残すか?

  • 確実に消していいことがわかるなら消す
  • アプリ側で抽象化してあると変更しやすい
    • 算出すればわかるデータはアプリ側で算出する (年齢⇛生年月日から算出)
  • カラムやテーブルに OLD などのプレフィックスを付ける
    • 将来削除されることがわかるようにコメントを残す
  • Oracleではメタデータで設定できる
    • クエリや実行計画、indexに使われなくなる

ログテーブル

  • 最近はS3など他の手段で実現することが多い
  • RDBに入れておくと検索しやすい
  • 不要になったログデータはS3などに退避させて削除する
  • 課金データなど、月単位でパーティションを切って、不要になったらdropする
    • 削除するときにdump取ったりS3に退避したり