削除フラグっているの?いらないの?

  • きん
    きん システムちーむ
  • このエントリーをはてなブックマークに追加
削除フラグっているの?

ご無沙汰しております。きんです。
当社のシステムちーむでは、gitやjavascriptなど
各担当を決めて情報収集行い、
そして専門的な知識を身に付けていこうという取り組みを行っております。
きんはせっかくMySQL担当になったにも関わらず、
全く貢献できていない…というか
そもそも、MySQLって、あれでしょ?
DBなんだからデータ入れておけばいいんでしょ。的な、
DBAの方々が聞いたら往復ビンタを食らわしたくなるような知識しか持ち合わせていなかったため、
もう一度基礎からきちんと勉強することに致しました。
今日はその第一回目、テーマは「削除フラグは必要か」とさせて頂きます。

削除フラグとは

削除フラグとは、実際にはデータを消さずに、
削除されたとみなすフラグの事である。
cakeでいうところのdeletedカラム。
デフォルト0で削除しましたの時に1を立てるアレ。
laravelの場合はdeleted_atで削除日時を入れるんだけど。

スーパーアナログ人間の元デパート店員が、
0以下の知識をひっさげて教育訓練校の門を叩いた時には、

「なにがなくてもデルフラグ!
ガチでデータ消しちゃったら何かあったときに困るから!
とりあえず1立てときゃいいから!そーゆーもんだから!」

と習ったので、そーゆーもんだと思って育ちました。

しかし、ぼんやりしているうちに
いつの間にか若さはじける20代は終わりを告げ、
はっとして周りを見渡してみると、
単純にそーゆーもんでもないと気づかされたのです。

では、なぜ削除フラグを使用するのか?
その利点を考えてみます。

削除フラグの利点

  • 何かのミス?などで削除された場合の復旧が簡単。
  • 削除データ一覧なんていうページも作れる。なんならそこから削除取り消しなんて操作を盛り込む事も楽勝。
  • DELETEよりUPDATEの方が処理が早い

などでしょうか?
これだけ見てみると理にかなっているような気がしますけどね。

でもまぁ、削除されてもデータが残っている事を知っているのは
データベースの中身を覗ける人だけなので、
実際のユーザーにとっては、削除はやっぱり削除なのであり、
はたしてこの論理削除というものをユーザーがどれほど理解し、
ありがたく思っているのかは不明な所ではあります。

有識者の方々のご意見

有識者の方々のご意見をネットで探してみました。

調べはじめてみるとこの議論、
一部界隈で1年前くらいに流行ったみたいですね。
完全に流行に乗り遅れておりまして、お恥ずかしい。。。

意見の片寄りがあるかと思いますが、
リンクからリンクへとたどって収集した資料ですので、ご理解下さい。

PHPerに知ってほしいRDBの事 Version 2.0

  • 関連テーブルがたくさんある場合にWHERE deleted = 0であふれかえる
  • Unique制約が使えなくなる
  • 正しいデータを取ってくるために、たくさんの関連テーブルの参照が必要で、バグの温床になる

上記のような観点から、削除フラグは必要最低限以外に使用せずに
削除用テーブルを別途作ったらどうか。
ただしこの方法には注意が必要で、
トリガーでひっぱってくる場合は、
テーブルの仕様変更に注意しないと、トリガーが腐る。

ちなみに、このスライドでは、このほかにも
statusやほかのフラグなどもテーブルでは持たせずに、
事実のみを保存するべきだと書かれています。

SQLアンチパターン幻の26章「とりあえず削除フラグ」

SQLアンチパターン幻の26章「とりあえず削除フラグ」

カラムにNULLが入ると、インデックスを使えないデメリットがある。
つまりdeleted_atでデフォルトはNULLで削除日時を挿入することによって
削除とみなすという仕様の場合は、
deleted_atをインデックスとして使用できなくなってしまう。

または、そもそも削除も更新もしない。
「削除」が本当に必要なのか?
お客様は本当に「削除」と言っているのか。
「フラグ」ではなく状態遷移で考える方がまし …status VARCHAR(20) NOT NULL DEFAULT ‘NEW’, …

それでもよく考えた末の削除フラグならOK。
「とりあえず」な思考停止はNG。

MySQLで論理削除と正しく付き合う方法

そもそもWEBサービスで削除が少ない。
削除にDELETEトリガーで
アーカイブ用のテーブルに追い出すときれいだけど、
ADD COLUMNなどトリガー腐らせてしまう心配がある。

運営のみ閲覧可能フラグとかユーザー非表示フラグと考え方を変える。

削除フラグを使用するのであれば、
全てのセカンダリーインデックスの先頭に削除のカラムが存在しなくてはならない。

DELETE_FLAG を付ける前に確認したいこと。

DELETE_FLAG を付ける前に確認したいこと。

本当に削除フラグでの対応が適切なのか確認する必要がある。

  • 論理削除した行を参照するタイミング
  • 論理削除した行を復活させる事があるか
  • 論理削除した行は最終的にどうなるのか
  • 他の状態は存在しないのか

思考停止の削除フラグではなく、
総合的に判断して本当に論理削除が適切な方法か見極める。

論理削除が云々について


とあるレコードが削除された時に、その関連テーブルはどうする?
というデータの遡及に関しては、
論理削除だけではなく、DELETEされたデータに関しても当てはまる。
UPDATE文は履歴系テーブルの扱いづらさを無視する操作なので、
「CRUD」の「U」と「D」いらない。

結局、削除フラグは不要?

上記掲載させて頂いた資料の中でだいたい一致していた点は、
利点欠点を理解し、熟考した上でDELETEフラグを使用するのであれば、それは否定しない。
とりあえず論理削除のカラム用意しておけばいいんでしょ?
の姿勢が害悪なのだそうです。
あぁ、まったく耳が痛くなるばかり。
生まれてこの方、
デルフラグは付けておけば世の中安心だと思っていましたから。

「そうするもの。」を捨てて、もう一度見直す姿勢が大切だと、
気づかせてくれる良いきっかけとなりました。
結局の所、いる・いらないは、ケースバイケースって事ですかね(逃)

このエントリーをはてなブックマークに追加

きんが最近書いた記事

WRITERS POSTS もっと見る

他にもこんな記事が読まれています!

  • WEB
  • マーケティング
  • サーバー・ネットワーク
  • ライフスタイル
  • お知らせ