問題タブ [soft-delete]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
sql - パフォーマンスとコードへの影響を最小限に抑えて論理的な削除を実装する
このトピックに関する同様の 質問がいくつかありますが、実際には役に立ちません。
アイテムが実際には削除されずに隠されている、StackOverflow のようなソフト削除機能を実装したいと考えています。SQL データベースを使用しています。3 つのオプションがあります。
is_deleted
ブールフィールドを追加します。- 利点: シンプル。
- 短所:日付記録がない。
is_deleted = 0
すべてのクエリに a を追加する必要があります。
deleted_date
日付フィールドを追加します。これはNULL
、削除されていない場合に設定されます。- メリット:日付あり。
- 短所: まだクエリが雑然としています。
上記の両方について
- これらの無駄な行がすべてあるため、パフォーマンスにも影響します。それらは引き続きインデックスで維持する必要があります。
deleted
また、削除されていない (大部分の) 行をフェッチする場合、列のインデックスは役に立ちません。全表スキャンが必要です。
もう 1 つのオプションは、削除されたアイテムを保持する別のテーブルを作成することです。
- 利点: 削除されていない行をクエリするときのパフォーマンスが向上します。削除されていない行に対するクエリに条件を追加する必要はありません。インデックスのメンテナンスが容易になります。
- 短所: 複雑さ: 削除と復元の両方にデータ移行が必要です。新しいテーブルが必要です。参照整合性は扱いが難しくなります。
より良いオプションはありますか?
mysql - ユーザーテーブルをソフト削除しますか?または別の選択肢はありますか?
ソフト削除に関する賛否両論の記事をすべて読んで頭が回転している。しかし、これを達成するために私が知っている唯一の方法は次のとおりです。
外部キーとユーザー情報(履歴データ)を維持するユーザーが削除/非アクティブになった場合でも、コメント、添付ファイル、ストーリーテーブルに外部キーがあります。このコメントなどを書いたのは彼であることがまだ確認できるように。
他の情報:
非アクティブ化されたユーザーはログインできず、リストに含まれません。
ただし、ソフト削除を使用する場合、そのテーブルをクエリするたびにSQLステートメントのWHEREに列を追加するのはあまり適切ではありません。
何をすべきか?あなたたちがいくつかの入力を与えることができることを願っています。
注:私はmysqlとRORを使用しています
c# - DbContext Set()からソフト削除を除外します
IsSoftDeleted
このDbSetからアイテムをフィルタリングするにはどうすればよいですか?
方法
モデル
編集:表示するのを忘れたからWhatever
派生BaseEntity
indexing - ソフト削除 - IsDeleted フラグを使用するか、別のジョイナー テーブルを使用しますか?
論理的な削除にフラグを使用する必要がありますか、それとも別の結合テーブルを使用する必要がありますか? どちらがより効率的ですか? データベースは SQL Server です。
背景情報
しばらく前に、DB コンサルタントが来て、データベース スキーマを調べました。レコードをソフト削除すると、適切なテーブルの IsDeleted フラグが更新されます。フラグを使用する代わりに、削除されたレコードを別のテーブルに保存し、結合を使用することをお勧めします。私はその提案をテストしましたが、少なくとも表面的には、余分なテーブルと結合はフラグを使用するよりも高価に見えます。
初期テスト
このテストを設定しました。
Example と DeletedExample の 2 つのテーブル。IsDeleted 列に非クラスター化インデックスを追加しました。
次の削除された/削除されていない比率で 100 万件のレコードをロードして、3 つのテストを行いました。
- 削除済み/非削除済み
- 50/50
- 10/90
- 1/99
結果 - 50/50
結果 - 10/90
結果 - 1/99
データベース スクリプト、参照用、例、DeletedExample、および Example.IsDeleted のインデックス
php - Doctrine2+状態パターンとしてのソフト削除
Doctrine2のドキュメントによると、ソフト削除の動作は状態パターンとしてより適切に実装する必要がありますが、その実装の例は提供していません。
状態パターンを使用してソフト削除動作を実現するにはどうすればよいですか?
entity-framework - Entity Framework Code First Soft Delete 遅延読み込み
だから私はEntity Framework Code Firstを使用しています(したがって.edmxはありません)ソフトデリートを行うためのbool IsEnabledを持つ基本エンティティクラスがあります
リポジトリ パターンを使用しているため、リポジトリに対するすべてのクエリを IsEnabled で除外できます。
ただし、リポジトリを使用して IsEnabled である MyType を取得するたびに、MyType.Items を遅延読み込みすると、Items を有効にできない可能性があります。
おそらくEF Fluentを使用して、テーブルでフィルタリングを行う方法を説明する方法はありますか?
アップデート:
Dbset がある場合
DbContext に DbSet をフィルター処理するように指示する方法はありますか?
ruby-on-rails - Rails - アクティブおよび非アクティブ データのソフト削除またはアーカイブ
論理的な削除とアーカイブについて多くのことを読み、すべての長所と短所を見てきました。どのアプローチが自分の状況に最も適しているかについて、私はまだ混乱しています。投稿とコメントの概念を使用して、もう少し簡単に説明できるかどうかを確認します
投稿は「削除」されますが、アプリケーションの管理者ではなく、たとえば RSS フィードから引き続きアクセスできる投稿が必要です。
論理的な削除に関する頭痛の種をよく耳にしますが、私のアプリケーションにとってはそれが最も理にかなっているかもしれないと考えており、アーカイブを使用すると複数のクエリを実行する必要があると感じています
@$$ でどちらがより効率的か、より苦痛になるかはわかりません。考えや例?この例はばかげているように聞こえるかもしれませんが、どちらに進むべきかを判断するために使用できる複数の状況を考えようとしています。
database-design - カスケードリカバリに関する共通属性のソフト削除
ソフト削除に付随して一般的に使用されるフィールドのタイプは何ですか?これらのいずれか、他に?
私が尋ねる理由は、ソフト削除を使用する場合でも、整合性を維持するためにカスケードを実装する必要があるためです。ただし、本当のトリックはカスケード削除ではなく、かなり簡単です。
The trick is cascade restoring
。カスケード削除では、ソフト削除シナリオでは、フラグが何であれ、リレーショナルグラフのすべてのレコードに削除済み、非アクティブのフラグが付けられます。おそらく違いは、datedeletedをnullからの値に変更することです。カスケード復元では、レコード参照を評価して、それらが削除された理由が、復元、再アクティブ化、削除解除されたレコードに関連するカスケード削除の結果であるかどうかを確認する必要があります。
保存されたデータに関して、カスケード復元操作はどのように処理されますか?
sql - 元の情報を保持しながら、論理的な削除で論理的な一貫性を維持する
以下のような構造の非常に単純な tablestudents
があり、主キーはid
です。このテーブルは、頻繁に結合される約 2,000 万行のテーブルの代役です。
ボブが生年月日を変更したい場合、いくつかの選択肢があります。
students
新しい生年月日で更新します。長所: 1 つの DML 操作。このテーブルには、1 回の主キー検索で常にアクセスできます。
悪い点:ボブが自分の誕生日を 1990 年 4 月 6 日だと思っていたという事実を忘れてしまった
列 をテーブルに追加し
created date default sysdate
、主キーを に変更しますid, created
。すべては次のupdate
ようになります。次に、最新の情報が必要なときはいつでも次のことを行います (Oracle ですが、質問はすべての RDBMS を表します)。
良い点:情報を失うことはありません。
欠点:データベース全体に対するすべてのクエリには、少し時間がかかります。テーブルが指定されたサイズである場合、これは問題ではありませんが
left outer join
、一意のスキャンではなく範囲スキャンを使用して 5 番目になると、効果が現れ始めます。別の列を追加する
deleted date default to_date('2100/01/01','yyyy/mm/dd')
か、または過度に早い、または未来的な日付が好きです。主キーを次のように変更しid, deleted
ますupdate
。現在の情報を取得するクエリは次のようになります。
良い点:情報を失うことはありません。
欠点: 2 つの DML 操作。すべてのクエリで一意のインデックス スキャンではなく、追加コストまたは範囲スキャンを使用してランク付けされたクエリを使用する必要があります。
2番目のテーブルを作成し、
student_archive
すべての更新を次のように変更します。良い点:情報を失うことはありません。
欠点: 2 つの DML 操作。すべての情報を取得したい場合は、使用する必要が
union
あるか、追加のleft outer join
.完全を期すために、恐ろしく非正規化されたデータ構造を持っています
id, name1, dob, name2, dob2...
。
情報を失いたくなく、常に論理的な削除を行う場合、番号 1 はオプションではありません。5 番は、価値以上の問題を引き起こしているため、安全に破棄できます。
オプション 2、3、および 4 には、それに付随するマイナス面が残っています。私は通常、オプション 2 とそれに付随する恐ろしい 150 行 (適切な間隔) の複数のサブ選択結合を使用することになります。
tl;drここで「建設的ではない」投票のライン近くでスケートをしていることに気づきましたが、
データを削除せずに論理的な一貫性を維持するための最適な(特異な!) 方法は何ですか?
私が文書化した方法よりも効率的な方法はありますか? このコンテキストでは、「DML 操作が少ない」および/または「サブクエリを削除できる」ことを効率的と定義します。(もし)答えるときにもっと良い定義を思いつくことができれば、どうぞお気軽に。