56

現在プロジェクトに取り組んでおり、大多数のユーザー(ユーザーロール)に対してソフト削除を実装する必要があります。is_deleted='0'データベース内の各テーブルにフィールドを追加し'1'、特定のユーザーロールが特定のレコードの削除ボタンを押した場合にフィールドを設定することにしました。

今後のメンテナンスのために、各SELECTクエリにはレコードが含まれていないことを確認する必要がありますwhere is_deleted='1'

ソフト削除を実装するためのより良い解決策はありますか?

更新:アプリケーションデータベース内のすべてのテーブル/フィールドへの変更(フィールド、古い値、新しい値、時間、ユーザー、IP)を追跡する監査データベースがあることにも注意する必要があります。

4

14 に答える 14

101

削除が行わdeleted_atれた日時を含む列に寄りかかります。次に、削除に関する無料のメタデータを少し取得します。行を取得するだけの場合SELECTWHERE deleted_at IS NULL

于 2008-09-16T00:50:42.990 に答える
54

WHERE IS_DELETED='0'句を含むビューに対してすべてのクエリを実行できます。

于 2008-09-16T00:49:19.310 に答える
22

カラムを持つことis_deletedはかなり良いアプローチです。Oracleの場合、パフォーマンスをさらに向上させるために、列にリストパーティションを作成してテーブルをパーティション化することをお勧めしis_deletedます。次に、削除された行と削除されていない行は物理的に異なるパーティションに配置されますが、透過的になります。

その結果、次のようなクエリを入力すると

SELECT * FROM table_name WHERE is_deleted = 1

次に、Oracleは「パーティションプルーニング」を実行し、適切なパーティションのみを調べます。内部的にはパーティションは別のテーブルですが、ユーザーとしては透過的です。パーティション化されているかどうかに関係なく、テーブル全体を選択できます。ただし、Oracleは必要なパーティションのみを照会できます。たとえば、1000行is_deleted = 0と100000行がありis_deleted = 1、テーブルをで分割するとしますis_deleted。今、条件を含めると

WHERE ... AND IS_DELETED=0

その場合、Oracleは1000行のパーティションのみをスキャンします。テーブルがパーティション化されていない場合、101000行(両方のパーティション)をスキャンする必要があります。

于 2008-09-16T01:01:14.727 に答える
15

テーブルが大きく、パフォーマンスが問題になる場合は、いつでも「削除済み」レコードを別のテーブルに移動できます。このテーブルには、削除時刻、レコードを削除したユーザーなどの追加情報があります。

そうすれば、プライマリテーブルに別の列を追加する必要はありません

于 2008-09-16T00:49:49.217 に答える
15

悲しいことに、最善の対応は、ソフト削除で何を達成しようとしているのか、およびこれを実装しているデータベースによって異なります。

SQL Server では、(必要な粒度に応じて) SMALLDATETIME または DATETIME 型の deleted_on/deleted_at 列を使用し、その列を null 可能にするのが最善の解決策です。SQL Server では、行ヘッダー データにテーブル内の各列の NULL ビットマスクが含まれているため、列に格納されている値をチェックするよりも IS NULL または IS NOT NULL を実行する方がわずかに高速です。

大量のデータがある場合は、データベース自体、2 つの個別のテーブル (Products と ProductHistory など)、またはインデックス付きビューを使用して、データのパーティション分割を検討する必要があります。

is_deleted や is_archive などのフラグ フィールドは 1 つの意味しか持たないため、通常は避けます。null 許容の deleted_at、archived_at フィールドは、あなた自身と、あなたのアプリケーションを継承する人にとって、追加のレベルの意味を提供します。また、意味を把握するにはビットマスクがどのように構築されたかを理解する必要があるため、疫病のようなビットマスク フィールドは避けます。

于 2008-09-16T12:47:20.113 に答える
12

これは、必要な情報とサポートするワークフローによって異なります。

次のことができるようになりますか?

  • (削除される前に)どのような情報があったか知っていますか?
  • いつ削除されたか知っていますか?
  • 誰がそれを削除したか知っていますか?
  • 彼らがそれを削除したときに彼らがどのような能力で行動していたか知っていますか?
  • レコードの削除を取り消すことができますか?
  • いつ削除されなかったかわかりますか?

レコードが4回削除および削除解除された場合、それが現在削除されていない状態にあることを知っていれば十分ですか、それともその間に何が起こったのか(連続する間の編集を含む)を伝えたいですか?削除!)?

于 2008-09-16T00:57:24.003 に答える
10

一意性制約違反の原因となるソフト削除されたレコードに注意してください。DBに一意の制約のある列がある場合は、以前のソフト削除されたレコードがレコードの再作成を妨げないように注意してください。

サイクルについて考えてみましょう。

  1. ユーザーの作成(login = JOE)
  2. ソフト削除(削除された列をnull以外に設定します。)
  3. (再)ユーザーを作成します(login = JOE)。エラー。LOGIN=JOEはすでに取得されています

login = JOEはすでにソフト削除された行にあるため、2番目の作成は制約違反になります。

いくつかのテクニック:1。削除されたレコードを新しいテーブルに移動します。2.loginおよびdeleted_atタイムスタンプ列全体で一意性の制約を作成します

私自身の意見は、新しいテーブルに移動するための+1です。すべてのクエリ(すべての開発者)で* AND delete_at = NULL *を維持するには、多くの規律が必要です。

于 2011-05-04T14:16:18.183 に答える
5

ジムが言ったように、削除されたデータを別のテーブルに移動し、いつ、なぜ、誰によって削除されたかを記録すると、パフォーマンスが確実に向上します。

すべてのクエリに追加すると、クエリが大幅に遅くなり、テーブルにあるインデックスの使用が妨げられます。可能な限り、テーブルに「フラグ」を付けないようにしてください。where deleted=0

于 2008-09-16T00:57:50.757 に答える
2

どの製品については言及していませんが、SQL Server 2008 と postgresql (およびその他の製品と確信しています) では、フィルター処理されたインデックスを作成できるため、is_deleted=0 のカバリング インデックスを作成して、この特定のアプローチの欠点を軽減できます。 .

于 2008-09-16T14:15:30.400 に答える
1

私がプロジェクトで使用するのは、statusInd tinyint not null default 0 column です。statusInd をビットマスクとして使用すると、データ管理 (削除、アーカイブ、複製、復元など) を実行できます。これをビューで使用して、消費するアプリケーションのデータ配布、公開などを行うことができます。ビューに関するパフォーマンスが懸念される場合は、小さなファクト テーブルを使用してこの情報をサポートし、ファクトを削除し、リレーションを削除し、呼び出した削除を許可します。

適切にスケーリングし、データ セントリックであるため、データ フットプリントをかなり小さく保ちます。代替手段、テーブル、トリガーを使用すると、必要に応じて機能する場合と機能しない場合があるオーバーヘッドがあります。

SOX 関連の監査では、ケースで役立つフィールド以上のものが必要になる場合がありますが、これは役立つ場合があります。楽しみ

于 2008-09-16T05:31:44.153 に答える
0

チェックするビュー、関数、またはプロシージャを使用しますis_deleted = 0。つまり、他の理由で後でテーブルを変更する必要がある場合に備えて、テーブルを直接選択しないでください。

is_deletedそして、より大きなテーブルの列にインデックスを付けます。

すでに監査証跡があるため、削除日の追跡は冗長です。

于 2008-09-16T03:25:48.247 に答える
0

ステータス列を保持することを好むので、いくつかの異なる構成、つまり公開、非公開、削除、needsAproval に使用できます...

于 2008-09-16T01:09:30.370 に答える
0

他のスキーマを作成し、データ スキーマにすべて付与します。新しいスキーマに VPD を実装して、すべてのクエリに、削除されていない行のみを選択できる述語が追加されるようにします。 http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/cmntopc.htm#CNCPT62345

于 2011-06-27T11:15:50.090 に答える
-1
@AdditionalCriteria("this.status <> 'deleted'")

これをあなたの上に置きます@entity

http://wiki.eclipse.org/EclipseLink/Examples/JPA/SoftDelete

于 2014-05-21T14:26:36.643 に答える