DB設計アンチパターン集
ここでは、実務で遭遇しやすい設計アンチパターンを「何が問題か」「どう直すか」の形でまとめます。設計レビューの観点として利用できます。
1. 月別12カラムを横持ちする
売上集計(商品ID, 1月売上, 2月売上, ... 12月売上)
- 問題: 拡張しづらく、集計SQLが複雑化する
- 改善:
月次売上(商品ID, 対象年月, 売上金額)の縦持ちにする
2. 状態フラグを乱立させる
is_active, is_deleted, is_locked, is_temp ...
- 問題: 矛盾状態が生まれやすい(例: 有効かつ削除済み)
- 改善:
状態コードを1列に集約し、遷移ルールを定義する
3. 汎用マスタ1枚化
master(code_type, code, name, value1, value2 ...)
- 問題: 制約が弱く、ドメインルールをDBで表現できない
- 改善: ドメインごとにテーブルを分割し、制約を明確化する
4. EAV(属性名・値)を乱用する
entity_attr(entity_id, attr_name, attr_value)
- 問題: 型保証ができず、検索・集計が重くなる
- 改善: 頻出項目は通常列で持ち、可変項目だけ限定的にEAV化する
5. 履歴を上書きして消す
- 問題: 「いつ、いくらだったか」が追跡不能になる
- 改善: 履歴テーブルや有効期間(開始日/終了日)を設ける
6. 外部キーを貼らない
- 問題: 孤児データが発生し、アプリ依存でしか整合性を守れない
- 改善: FK制約を設定し、削除時ルール(CASCADE/RESTRICT)を明示する
7. NULLの意味が混在する
- 問題: NULLが「未入力」「対象外」「不明」のどれか判別できない
- 改善: 状態列を分離し、NULLの意味を1つに限定する
回避の原則
- 増える可能性がある軸(年月、タグ)は列ではなく行で持つ
- 意味が異なるデータは別テーブルに分離する
- 整合性はアプリだけでなく DB制約で守る
- 将来変更のシナリオを前提にモデルを設計する
アンチパターンは「今すぐ動く」設計として採用されがちです。短期実装と長期保守のどちらを優先するかを意識して選択してください。