よくある「削除フラグ」の問題点
ちなみに、「削除フラグ」だけなく「退会フラグ」、「課金状態」など類似の状況が度々業務システムでは発生しますので読み替えていただければと思います。
「削除されたデータ」と「削除されてないデータ」が同じテーブルに混在することになりどれが正しいデータなのかわからなくなる。
クエリが複雑化する。
SQLで取り出すのにいちいち全てに削除フラグの条件をつけないといけなくなる。
いちいち、有効なデータを判定するために別のテーブルをJOINして削除フラグが立っていないデータ化まで確認しなければならなくなる。
アプリケーションの仕様変更時に影響範囲が広くなりバグの温床になります。
例えば以下のようなSQLです。結合する都度削除フラグを条件に付けないといけなくなってしまい何が何だかわからなくなってしまいます。
1 2 3 4 5 |
select * from テーブル1 INNER JOIN テーブル2 on テーブル1.id = テーブル2.テーブル1のid and テーブル2.削除フラグ = 0 where テーブル1.削除フラグ = 0 |
削除とか更新のトランザクションをしっかりしないとデータが重複する。
UNIQUE制約や外部キー制約も削除フラグのせいで付けられなくなる。
削除フラグが立っている、立っていないで同じ人が二人いることになってしまうため。
また、外部キー制約を付けられないことでデータの整合性も担保できなくなりアプリケーションの参照、更新の動作で思わぬバグが発生する可能性が出てきます。
カーディナリティが低くなり、INDEXも効かなくなる。
削除フラグでは0と1の2種類しかなく重複データが発生し検索時に参照するため必ずON句やWHERE句に指定するためインデックスが効かずボトルネックの原因になります。
もし、対応する場合は複合インデックスを使わざる追えずDB運用が複雑化します。
問題の本質
テーブルに「削除」という状態をもたせてしまっている点。(別に削除じゃなくてもユーザーの状態(入会、退会)などでも起こり得ます。)
対策
データは物理削除し、事実のみ保存することが重要。削除したデータなどは削除用の別テーブルに保管する運用にします。
ただし
以下の条件を満たしていれば削除フラグを持たしても良いでしょう。
- 対象のテーブルが小さくINDEXが不要
- そのテーブルが関連するテーブルの親になることがなくデータを取得する際にJOINの対象になることがない。
- UNIQUE制約や外部キーが不要
この記事へのコメントはありません。