- RDB - DELETE_FLAG を付ける前に確認したいこと。 - Qiita
- 論理削除が云々について - mike-neckのブログ
- Kazuho's Weblog: 論理削除はなぜ「筋が悪い」か
流行っているので乗っかります。
結論
「データ制約の強力さと集合としての表現力を捨てながら、Relational Databaseを使うのはなぜか?」
論理削除フラグのデメリット
大体三つあると考えています。
- ユーザーの言葉でない
- データ制約の弱さ
- 集合として認識できない
ユーザーの言葉でない
私の経験上は、ユーザーから「論理削除」という言葉を聞いたことがありません。 次のような要件は、聞いたことがあります
- 社員が退職(・転属)する
- (売掛金の回収を諦めて)売上を打ち消す
- 「お知らせメッセージ」を公開日がくるまで非表示にする
- 既読メッセージを表示しない
- 保存期間が過ぎたアンケート結果をオペレーターが見れなくする
もしかして「論理削除」は実装パターンではないですか? ユーザーが「消す」と言ったのは「データベース上のレコードを削除する」ことでしょうか? ユーザーが「消す」と言った時、反射的に「消すよりは、削除フラグを立てた方が何かあった時に安心」と考えませんでしたか?
もうちょっとだけ、ユーザーがやりたいことを理解できそうです。
データ制約の弱さ
次のテーブルがあったとします。
名前 | 番号 | 生死 |
---|---|---|
惣流・アスカ・ラングレー | 3rd | |
綾波レイ | 1st | |
綾波レイ | 1st | 死亡 |
綾波レイ | 1st | 死亡 |
データ制約上、次のような問題があります。
- (よく使う)生きている適格者の取得時にwhere句で生死を絞りこみが必要
- 番号にuniq制約がつけられない
これはアプリケーションカバーします。
- レコード追加時に生きている適格者の番号が重複しないようにチェックする
- レコード取得時はwhere句で生死を絞りこむ
- (または)レコード取得時は「生きている適格者ビュー」を使う
- レコード取得時に生きている適格者の番号が重複していないかチェックする
さらにデータメンテナンスでカバーします。
「運用でカバー」は、本当に困った時だけにしたいものです。
集合として認識できない
多くの人は、生きている適格者と死んだ適格者が混じっているテーブルを集合として認識できません。 別のテーブルに分けると、集合として認識できます。
生きている適格者
名前 | 番号 |
---|---|
惣流・アスカ・ラングレー | 3rd |
綾波レイ | 1st |
死んだ適格者
名前 | 番号 | 死亡日 |
---|---|---|
綾波レイ | 1st | x月x日 |
綾波レイ | 1st | x月x日 |
テーブルに入っているレコードが推測しやすくなります。
デメリットにならない条件
上記のデメリットが成り立たない時、論理削除フラグは有効です。
- ユーザーが「消した」データに興味がない
- アプリケーションの作成工数や運用工数が、データ設計工数より低い
- (論理削除フラグに慣れた)複雑な集合を認識できるメンバーでチームを作る