ソフト削除は良いアイデアですか、悪いアイデアですか?
データベース内のレコードを実際に削除する代わりに、IsDeleted = true
としてフラグを立てるだけで、レコードの回復時にFalse
としてフラグを立てることができます。
これはいい考えですか?
レコードを物理的に削除してからアーカイブデータベースに移動し、ユーザーがレコードを元に戻したい場合、ソフトウェアはアーカイブ内のレコードを検索して再作成する方が良いでしょうか?
一般的には(おそらくいくつかの例外を除いて)悪い考えだと言います。
まず、データベースを定期的にバックアップする必要があります。そのため、DELETEのためにデータが永久に失われるような状況に陥ってはなりません(もちろん、追加したばかりのデータを削除する場合を除きます)。
2番目に、このようなソフト削除は、このテーブルのすべてのクエリにWHERE IsDeleted = false
句を含める必要があることを意味します(これらのテーブルを結合している場合は、さらに悪化します)。ここでの間違いは、ユーザーまたはテスターが削除されたレコードが再び表示されることに気づくとすぐにキャッチされます。これには時間がかかる場合があります。また、開発者はCOUNT(*)クエリからWHERE句を簡単に省略できますが、これは発見にさらに時間がかかる場合があります(私はこれが何年も発生していたプロジェクトに取り組みました;多くのレコードが「削除」されたことはありません、合計が予想に近かったため、誰も気づきませんでした)。
最後に、ソフト削除は人為的なキーを持つテーブルでは機能しますが、潜在的に自然な主キーを持つテーブルでは機能しません(たとえば、社会保障番号をキーとするテーブルから誰かを「削除」します-彼を再び追加する必要がありますか?「IsDeletedを複合主キーに含める」と言わないでください。).
設計レビューでは、開発者がコストとメリットの認識を示し、この方法でソフト削除を実行するexcellent理由を提示することを期待します。 「なぜnotするのですか?」優れた理由ではありません。
潜在的なデータ損失を避けることは決して悪い考えではありません。
私は常にソフト削除します。データベースで1つ以上のレコードをスクラブする必要がある場合、通常、2段階のソフト削除プロセスを使用してから、レコードの「ごみ箱」を空にするか、ドキュメントレコードができるドキュメント管理スタイルのアプローチを使用します。古くなってから、完全削除の前に承認プロセスを経てください。
それは状況に依存します。何かを本当に削除することが法的に義務付けられている状況を見ることができました。誰かがあなたの社会保障番号をあなたのシステムから永久に削除することを要求したかもしれません。または、単一のレコードに統合する重複レコードがある場合があります。削除されたフラグで複製をぶら下げておくのは有利ではないかもしれません。
技術的な短所も1つあります。カスケード削除を実行できないため、削除されたデータへの参照が自動的に消去され、外部キーの違反が防止されます。これは必ずしも大きな問題ではありませんが、心に留めておくべきことです。
それ以外の場合は、良いアイデアだと思います。
一時的な削除を使用する場合は、is_deletedフィールドではなく、deleted_dateフィールドを使用することをお勧めします。ビットフィールドだけでなく、追加のデータを取得できます。
ソフト削除の主な問題の1つは、これらの不要なデータがdbのパフォーマンスに影響を及ぼす可能性があることです。数年前、クライアントの1人がすべてのデータベースアイテムでソフト削除を要求しました。これに対する解決策は、すべての「削除された」アイテムを現在実行中のテーブルに残すのではなく、バックアップテーブルに移動することです。
無効な削除が完全に壊滅的であり、回復が簡単な場合、およびその場合は良い考えです。また、これまでに行われたすべてを追跡したい場合、「削除」は実際には「非表示」のみを意味することをお勧めします。意味、それは状況次第です。
「それについて政治的に正しい」ことをしようとはしません。ソフトデリートを提唱している場合は、脳の検査を受ける必要があります。
1)まず、テーブルの行を削除しないことで、正確に何を達成しますか?将来、いつかそれらの行にアクセスできるという事実だけでしょうか?では、なぜアーカイブテーブルを作成して、そこに行を移動しないのでしょうか。何が悪いの?
2)ソフト削除では、is_activeに不要なクエリを作成するか、タイムスタンプ列にクエリを作成します。単純なクエリを作成する場合は無駄です。はい、ビューで機能しますが、ビューは追加の付属物ではありませんか?すべてのビューは余分なSQL、余分なパフォーマンスコストであり、商用RDBMSではすべてがテーブルのみです。テーブルの上にクエリを書く方法がわからないという事実を除けば、ビューについて魔法のようなことは何もありません。
3)はい、ViewまたはMVで動作します。しかし、その後、実稼働環境でFTSを実行するクエリを見てきましたが、すべて正常に機能しています!最新のハードウェアと堅実なソフトウェアの驚異。しかし、それでもそれは正しくありません。したがって、同じロジックで、それが機能するからといって、それがRIGHTであるという意味ではありません
4)ソフト削除の複雑さは、単純な選択で止まることはありません。
A)UNIQUE制約があるとします。ここで、行をソフト削除しますが、UNIQUE制約を持つ列はまだあります。同じデータを再び追加したい場合は、追加の「トリック」なしでそれを行うことはできません。
B)テーブルAからテーブルBへの関連付けがあり、テーブルAから何かをソフト削除する場合、テーブルBの独立したクエリがその事実を処理することを保証する必要があります。典型的な詳細ページがいくつかのdetail_idで機能していたとします。
これでmaster_idが一時的に削除されましたが、そのmaster_idのdetail_idを持つパーマリンクはどこにでもあります。 master_idで完全削除を行うと、それらの詳細は単に存在しません。現在、ソフト削除ではそれらはまだ存在しており、master_idがソフト削除モードになっているという事実に注意する必要があります。
単純なTable_A.is_active = 0または1ステージで停止しません。
5)完全削除は簡単かつ適切です。
A)誰も余分なものを追加したり、どこにでも心配する必要はありません。
データと関連する部分をアーカイブするだけで、うまくいくはずです。
また、ソフト削除を使用すると、アプリケーションで使用されるデータベースアカウントから revokeDELETE
特権を取得できます。
場合によっては、ソフト削除が必要です。たとえば、製品テーブルを参照する請求書テーブルがあるとします。特定の製品で請求書を作成すると、その製品を削除することはできません(また、RIが正しく設定されている場合は許可されません)。
この特定のシナリオでは、請求書を削除することは決してないと想定していますが、実際の会社では、履歴財務データを削除することはおそらくないでしょう。
ただし、ビジネスなどの理由で削除できないチェーン上の依存関係の副作用として、一部のデータを削除できない場合も多くあります。
oracleでは、作成するrecycle_binテーブルに主キーを追加し、行レベルのセキュリティポリシーを追加すると、行がごみ箱にあるときにすべてのクエリの値を抑制でき、ごみ箱からpkを削除できますすべてのデータを自動的に復元します。ロジックに合わせて他のクエリを変更する必要はありません。
データに依存します。法律/監査の要件により、一部のデータは削除できません。
一方、ソーシャルネットワーキングサイトshouldは、連絡先情報、写真、メッセージなどを含むすべての関連データを含むアカウントを削除するオプションを提供します。フェイスブック。
ただし、削除された行を除外するにはクエリとインデックスを更新する必要があるため、コストがかかります。
フラグを切り替える代わりに、別の「ゴミ箱」テーブルに移動してください。
また、削除のみを対象とするため、これは部分的な解決策にすぎないと言うこともできますが、行を更新すると、古い値はまだ上書きされます。
一般的に、本当に必要な場合を除き、何も削除しないでください。最近のディスク容量は安価です。もちろん、制限があり、消去する法的拘束力のあるデータがあり、本当にそれほど重要ではないデータがあり、おそらく古いデータをオンラインで同じテーブルに保存する必要はありません(どこかのアーカイブ動作します)。
1セント追加するだけです。私は常にソフト削除します。ただし、パフォーマンスは低下しますが、ごくわずかです。顧客が、自分でさえ思い出せない特定のアクションを実行した後に機能しなくなったソフトウェアについて不平を言うとき、コストについて考えてください。まあ、これは太った例かもしれませんが、何が間違っていたのか、誰が何をしたのか、前に何があったのか、その後に何が挿入されたのかは決してわかりません。その場合、これは便利です。この機能は監査目的に便利であり、多くの顧客がこの種のレポートの監査を要求しています。
また、ほとんどのワークフローベースのアプリケーションでは、顧客が作業項目で実行される「アクション」に関心を持っていることがソフトウェア機能/要件として提供されます。どの値が割り当てられ、誰が処理したかなど。
私はソフト削除のファンです。主にカスケード削除を防ぎます。ただし、追加のコードが必要なので、子オブジェクトを選択している場合、親(およびすべての親!)オブジェクトに結合して、それらが削除されないようにします。または、ソフト削除をカスケードすることもできますが、後で復元したい場合、どの子がすでに削除されていて、どの子がカスケードのために削除されたかがわからない場合があります。
さらに、各オブジェクトの改訂日時と改訂ユーザー名を保持するため、誰が最後に変更(またはソフト削除)したかがわかります。次に、監査証跡のために、元のテーブルに対するUPDATEのたびに挿入される* History(CustomerHistoryなど)テーブルを作成します。このようにして、オブジェクトが変更またはソフト削除された後、アクションの実行者とオブジェクトの最後の既知の状態の記録があります。
次の広範なシナリオでソフト削除が発生しました。
ケース1:レコードをユーザー/コードに表示されないように削除しますが、ビジネスがレコードを持っていることを知りたいので、DBレベルでレコードを保持します。
。この時点で、ケース2を見て、IsDeletedフラグを設定する前に要件を満たしているかどうかを評価します。
ケース2:記録の進化を追跡するための監査証跡-データベースに記録の監査証跡を保持するためのオンラインで多数の記事があります
HTH。