🧩

テーブル設計: statusカラムから生じる技術的負債とその解決策①

2024/04/25に公開
1

概要

こういうテーブルを見たことはないだろうか。

statusごとに、nullable, not nullカラムが混在しているクレイジーなテーブルである。

どんなときに、値が入るねん!と不安にさせてくる。
どの現場にも存在して、もはや既視感すらある。

このテーブルの問題点とその解決案を説明していきたい。

登壇しました
https://speakerdeck.com/rsugi/statuskaramukarasheng-ziruji-shu-de-fu-zhai-tosonojie-jue-ce

対象読者

  • テーブル設計を学んでいる方
  • 技術的負債を解消したい方

いいね!してね

この記事の事例は必要に応じて今後追記していく予定です!
「新しい事例が知りたい」「他の事例も知りたい」と思った人は、ぜひこの記事にいいね👍してください。筆者のモチベーションにつながります!

それでは以下が本編です。

結論

✅テーブルに状態を持たせない(statusカラムをつけない)、ロングタームイベントパターンでテーブルを分割する。
https://dbdiagram.io/d/[sample1]-long_term_eventmember_status-66460b45f84ecd1d225cbbdb


テーブルの数は多いけど、シンプルで可読性が高い

解説は別記事
https://zenn.dev/rsugi/articles/886fabb1a8dc03

説明すること

  • statusカラムの問題点
  • 解決案

statusカラムの問題点

❌テーブルにnullableなカラムが混在してしまう

カラムの値を参照する前に、まずstatusを参照して条件を分岐する
その後に値のnullチェックをしながらロジックをつくる。

そして、クソコードとの戦いが始まる、、!

エンジニアとして様々な案件にjoinしてきた。
アプリケーションの設計以前にテーブル設計がおかしいケースが多い。

statusカラムがあってそれに依存するカラムが別テーブルに切り出されている場合もほぼ同じぐらいキツかった。

同様の事例1: 削除フラグ
https://speakerdeck.com/soudai/delete-flag?slide=17

同様の事例2: クソコードUserクラス
https://speakerdeck.com/minodriven/kusokododong-hua-userkurasu-dekao-eruji-shu-de-fu-zhai-jie-xiao-falseguan-dian?slide=7

❌履歴が残らない

「失敗から学ぶrdbの正しい歩き方」の「失われた事実」の章を読んでほしい。
この章では「状態を更新したら更新前のカラム値は消えてしまう」ことを指摘している。
https://speakerdeck.com/soudai/learn-from-failure-1?slide=17

※対応する履歴テーブルを作るのは面倒。できればやりたくない

解決案

再掲:解説は別記事
https://zenn.dev/rsugi/articles/886fabb1a8dc03

✅statusごとにテーブルを分ける

  • テーブルに状態を持たせてはならない。

✅nullカラム, updatedAtを排除する

できるだけnot nullなカラムとする。

再度結論

✅テーブルに対応するルールや制約がシンプルにする
状態ごとにテーブルを分ける
テーブルごとに(バリデーションなどの)ロジックを切り出せる。
(原則)Not nullな値のみが存在する。
ロジックがシンプルになる。

✅テーブル運用がしやすい
テーブルのカラム数が少なくなる。
(原則)Not nullなのでindexが効きやすくなる。

※ステータスの変更量はそんなにないのでデータ量を心配しなくても良さそう(増えたら削除すればよい)
※粒度が細かすぎたら、テーブル統合できる(テーブル分離よりラクにできる)

✅履歴が残る
イベントを全てINSERTしてレコードを生成するため、履歴が残る。
「事実を残す」という目的を達成できる。

まとめ

「テーブルに状態を持たせるな!」と言うが、

「じゃあどうすればいいねん?」と思っていた。

その疑問に対する答えが出たので記事にした!

この記事が参考になった方は、ぜひこの記事にいいね👍してください。筆者のモチベーションにつながります!

引用

ミノ駆動さんの「クソコード動画「Userクラス」で考える技術的負債解消の観点」:
https://speakerdeck.com/minodriven/kusokododong-hua-userkurasu-dekao-eruji-shu-de-fu-zhai-jie-xiao-falseguan-dian?slide=7

曽根壮大さんの「失敗から学ぶrdbの正しい歩き方」:
https://speakerdeck.com/soudai/learn-from-failure-1

kawasimaさんの「イミュータブルデータモデル」:
https://scrapbox.io/kawasima/イミュータブルデータモデル

https://note.com/tsusowake/n/nddbee3c181c4

Discussion