136

論理的な削除は良いアイデアですか、それとも悪いアイデアですか?

データベース内のレコードを実際に削除する代わりに、単に としてフラグを立てIsDeleted = true、レコードの回復時に としてフラグを立てることができますFalse

これは良い考えですか?

レコードを物理的に削除してからアーカイブ データベースに移動し、ユーザーがレコードを元に戻したい場合は、ソフトウェアがアーカイブ内のレコードを探して再作成する方がよいでしょうか?

4

15 に答える 15

100

一般に、それは悪い考えだと私は言います(おそらく、いくつかの例外を除いて)。

まず、データベースを定期的にバックアップする必要があります。そのため、DELETE によってデータが永久に失われるような状況に陥ることはありません (もちろん、追加したばかりのデータを削除する場合を除きます)。

第二に、このようなソフト削除は、WHERE IsDeleted = falseこのテーブルのすべてのクエリに句を含める必要があることを意味します (これらのテーブルを結合している場合はさらに悪化します)。ここでの間違いは、削除されたレコードが再び表示されることにユーザーまたはテスターが気付くとすぐに検出されますが、これには時間がかかる場合があります。また、開発者が COUNT(*) クエリから WHERE 句を省略するのは簡単で、発見するのにさらに時間がかかる可能性があります (私は、これが何年も発生している 1 つのプロジェクトに取り組んでいました。多くのレコードが「削除」されたことはありません)。 、したがって、合計は予想に近く、誰も気付かなかった)。

最後に、論理的な削除は人工的なキーを持つテーブルでは機能しますが、自然の主キーを持つテーブルでは機能しない可能性があります (たとえば、社会保障番号をキーとするテーブルから誰かを「削除」します。彼を追加し直す必要がありますか? 「複合主キーに IsDeleted を含める」と言わないでください)。

設計レビューでは、開発者がコストとメリットを認識していることを示し、この方法で論理的な削除を行う優れた理由を提示することを期待しています。「なぜそれをしないのですか?」は立派な理由ではありません。

于 2010-03-31T01:51:56.180 に答える
93

潜在的なデータ損失を回避することは決して悪い考えではありません。

私はいつも論理的に削除します。データベースから 1 つまたは複数のレコードをスクラブする必要がある場合、私は通常、ソフト削除とレコードの「ごみ箱」を空にする 2 段階のプロセス、またはドキュメント レコードを削除できるドキュメント管理スタイルのアプローチのいずれかを採用します。削除され、ハード削除の前に承認プロセスが行われます。

于 2010-03-31T01:24:04.243 に答える
32

状況によります。何かを本当に削除することが法的に要求される状況を見ることができました。誰かが自分の社会保障番号をシステムから完全に削除するように要求した可能性があります。または、1 つのレコードに統合したい重複レコードがあるかもしれません。重複を削除フラグでぶら下げたままにしておくことは、有利ではないかもしれません。

技術的な欠点も 1 つあります。カスケード削除を行うことはできません。カスケード削除では、削除されたデータへの参照が自動的に消去され、外部キー違反が防止されます。これは必ずしも大きな問題ではありませんが、心に留めておくべきことです。

そうでなければ、それは良い考えだと思います。

于 2010-03-31T01:29:25.603 に答える
24

ソフト削除を使用する場合は、is_deleted フィールドではなく、deleted_date フィールドを使用することをお勧めします。ビットフィールドだけでなく、素敵な追加データが得られます。

于 2010-04-01T13:02:23.583 に答える
20

論理的な削除の主な問題の 1 つは、不要なデータがデータベースのパフォーマンスに影響を与える可能性があることです。数年前、私のクライアントの 1 人が、すべてのデータベース アイテムに対して論理的な削除を行うように要求しました。それに対する私の解決策は、現在実行中のテーブルに残すのではなく、すべての「削除された」アイテムをバックアップ テーブルに移動することです。

于 2010-03-31T01:31:39.660 に答える
17

無効な削除が絶対に壊滅的であり、回復が簡単であるべき場合は、良い考えです。また、これまでのすべてを追跡したい場合や、「削除」が実際には「非表示」を意味するだけの場合も、これは良い考えです。つまり、状況次第です。

于 2010-03-31T01:25:06.943 に答える
9

私は「それについて政治的に正しい」ようにしようとはしません。論理的な削除を推奨している場合は、脳の検査を受ける必要があります。

1) まず、テーブル内の行を削除しないことで正確に何を達成していますか? 将来、これらの行にアクセスできるようになるという事実だけですよね? では、アーカイブ テーブルを作成してそこに行を移動してみませんか? それの何が悪いの?

2) 論理的な削除を使用すると、is_active で不要なクエリを作成したり、タイムスタンプ列でクエリを作成したりします。単純なクエリを作成する場合、これは無駄です。はい、それはビューで動作しますが、ビューは追加の付属物ではありませんか? すべてのビューは追加の SQL であり、追加のパフォーマンス コストであり、商用 RDBMS ではすべてがテーブルのみです。テーブルの上にクエリを書く方法がわからないという事実を除けば、ビューには魔法のようなものは何もありません。

3) はい、ビューまたは MV で動作します。しかし、本番環境でクエリが FTS を実行しているのを見たことがありますが、すべてがまだ機能しています! 最新のハードウェアと堅牢なソフトウェアの驚異。しかし、それではそれも正しくありません。したがって、同じ論理で、機能するからといって、それが正しいとは限りません

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) 余分なものを追加したり、心配したりする必要はありません。

  1. アプリケーション ロジックがよりシンプルに
  2. データベースが小さい
  3. あなたのクエリはより高速です

データと関連する部分をアーカイブするだけで、うまくいくはずです。

于 2012-03-05T10:04:56.207 に答える
8

ソフト デリートを使用すると、アプリケーションが使用するデータベース アカウントから特権を取り消すこともできます。 DELETE

于 2010-03-31T01:27:47.687 に答える
5

ソフト削除が必要な場合があります。たとえば、Productsテーブルを参照するInvoiceテーブルがあるとします。特定の製品で請求書を作成した後は、その製品を削除することはできません(RIが正しく設定されている場合は、削除できません)。

この特定のシナリオでは、請求書を削除したくないと想定しています。実際の会社では、過去の財務データを削除したくないと思われます。

他にも、ビジネスなどの理由でチェーンの上位の依存関係を削除できないことの副作用として、一部のデータを削除できない場合が多くあります。

于 2010-03-31T01:36:25.777 に答える
4

それはデータに依存します。法的/監査上の要件により、一部のデータは削除できません。

一方、ソーシャル ネットワーキング サイトでは、連絡先情報、写真、メッセージなど、関連するすべてのデータを含むアカウントを削除するオプションを提供する必要があります。Facebook などのように、そうでない場合は本当に面倒です。

于 2010-03-31T01:33:01.977 に答える
4

Oracle では、作成した recycle_bin テーブルに主キーを追加してから、行レベルのセキュリティ ポリシーを追加すると、行がごみ箱にあるときにすべてのクエリからの値を抑制でき、ごみ箱から pk を削除すると、すべてのデータを自動的に復元します。ロジックに対応するために他のクエリを変更する必要はありません。

于 2010-04-23T01:53:16.080 に答える
3

ただし、削除された行を除外できるようにクエリとインデックスを更新する必要があるため、コストがかかります。

フラグを切り替える代わりに、別の「ゴミ箱」テーブルに移動してください。

また、削除のみをカバーしているため、これは部分的な解決策にすぎないと言えますが、行を更新すると、古い値が上書きされます。

一般に、本当に必要でない限り、何も削除しないでください。最近のディスク容量は安価です。もちろん、制限はあります。法的に消去しなければならないデータもあれば、それほど重要ではないデータもあります。また、古いデータをオンラインで同じテーブル (どこかのアーカイブ) に保持する必要がない場合もあります。も機能します)。

于 2010-03-31T01:30:12.957 に答える
1

セントを追加するだけです。私は常にソフト削除します。パフォーマンスは低下しますが、ごくわずかです。コストについて考えてみてください。顧客が、自分でさえ覚えていない特定のアクションを実行した後、ソフトウェアが機能しなくなったことについて苦情を言った場合です。まあ、これは大げさな例かもしれませんが、何がうまくいかなかったのか、誰が何をしたのか、何が前に何が挿入されたのかを知ることはできません。そんな時はこれが重宝します。この機能は監査目的で便利であり、多くの顧客がこの種の監査レポートを要求しています。

また、ほとんどのワークフロー ベースのアプリケーションでは、ソフトウェアの機能/要件として、顧客が作業項目に対して実行される「アクション」に関心を持っています。どの値が割り当てられ、誰がそれを処理したかなど。

于 2010-03-31T05:54:47.707 に答える
0

私は論理的な削除のファンです。主にカスケード削除を防ぐためです。ただし、子オブジェクトを選択している場合は、親 (およびすべての親) オブジェクトに結合して、それらのいずれも削除されないようにするための追加のコードが必要です。または、論理的な削除をカスケードすることもできますが、後でそれらを復元したい場合、既に削除された子とカスケードのために削除された子がわからない場合があります。

さらに、各オブジェクトのリビジョンの日時とリビジョンのユーザー名を保持しているため、最後に誰がそれを変更 (またはソフト削除) したかがわかります。次に、監査証跡のために、元のテーブルへの各 UPDATE の後に挿入される *History (CustomerHistory のような) テーブルを作成します。このようにして、オブジェクトが変更またはソフト削除された後、誰がアクションを実行したか、およびオブジェクトの最後の既知の状態を記録します。

于 2010-03-31T02:40:42.567 に答える
0

次の広範なシナリオで論理的な削除が発生しました。

ケース 1: ユーザー/コードの可視性からレコードを削除しますが、DB レベルでレコードを保持します。これは、ビジネスがそのレコードを持っていることを知ることに関心があるためです。
これらの要件は主にビジネスによって左右されます。通常は、データベースに以前のレコードを保持し、変更が行われるたびに新しいレコードを作成するという法的要件 (@joshperry や @armandino のシナリオなど) が中心になります。この時点で、CASE 2 を見て、IsDeleted フラグを設定する前に要件を満たしているかどうかを評価します。

ケース 2: 記録の進化を追跡するための監査証跡 - データベース内の記録の監査証跡を維持するためのまともな記事がオンラインにたくさんあります

HTH。

于 2010-03-31T02:41:52.543 に答える