@ledsun blog

無味の味は佳境に入らざればすなわち知れず

論理削除フラグという名の死亡フラグ

流行っているので乗っかります。

結論

「データ制約の強力さと集合としての表現力を捨てながら、Relational Databaseを使うのはなぜか?」

論理削除フラグのデメリット

大体三つあると考えています。

  1. ユーザーの言葉でない
  2. データ制約の弱さ
  3. 集合として認識できない

ユーザーの言葉でない

私の経験上は、ユーザーから「論理削除」という言葉を聞いたことがありません。 次のような要件は、聞いたことがあります

  • 社員が退職(・転属)する
  • 売掛金の回収を諦めて)売上を打ち消す
  • 「お知らせメッセージ」を公開日がくるまで非表示にする
  • 既読メッセージを表示しない
  • 保存期間が過ぎたアンケート結果をオペレーターが見れなくする

もしかして「論理削除」は実装パターンではないですか? ユーザーが「消す」と言ったのは「データベース上のレコードを削除する」ことでしょうか? ユーザーが「消す」と言った時、反射的に「消すよりは、削除フラグを立てた方が何かあった時に安心」と考えませんでしたか?

もうちょっとだけ、ユーザーがやりたいことを理解できそうです。

データ制約の弱さ

次のテーブルがあったとします。

名前 番号 生死
惣流・アスカ・ラングレー 3rd
綾波レイ 1st
綾波レイ 1st 死亡
綾波レイ 1st 死亡

データ制約上、次のような問題があります。

  • (よく使う)生きている適格者の取得時にwhere句で生死を絞りこみが必要
  • 番号にuniq制約がつけられない

これはアプリケーションカバーします。

  • レコード追加時に生きている適格者の番号が重複しないようにチェックする
  • レコード取得時はwhere句で生死を絞りこむ
  • (または)レコード取得時は「生きている適格者ビュー」を使う
  • レコード取得時に生きている適格者の番号が重複していないかチェックする

さらにデータメンテナンスでカバーします。

  • 重複レコードを発見したら、アプリケーションのバグなのかデータメンテナンスのミスなのか切り分けます。ソースコードやログとにらめっこする
  • 重複レコードを発見したら、SQL文を発行してレコードを修正する

「運用でカバー」は、本当に困った時だけにしたいものです。

集合として認識できない

多くの人は、生きている適格者と死んだ適格者が混じっているテーブルを集合として認識できません。 別のテーブルに分けると、集合として認識できます。

生きている適格者

名前 番号
惣流・アスカ・ラングレー 3rd
綾波レイ 1st

死んだ適格者

名前 番号 死亡日
綾波レイ 1st x月x日
綾波レイ 1st x月x日

テーブルに入っているレコードが推測しやすくなります。

デメリットにならない条件

上記のデメリットが成り立たない時、論理削除フラグは有効です。

  • ユーザーが「消した」データに興味がない
  • アプリケーションの作成工数や運用工数が、データ設計工数より低い
  • (論理削除フラグに慣れた)複雑な集合を認識できるメンバーでチームを作る