パフォーマンスとコードへの影響を最小限に抑えてソフト削除の実装
-
28-10-2019 - |
質問
幾つかある 似ている 質問 このトピックについては、彼らは本当に私を助けていません。
Stackoverflowのようなソフト削除機能を実装したいと思います。この機能では、アイテムが実際に削除されていないが、隠されているだけです。 SQLデータベースを使用しています。ここに3つのオプションがあります:
Aを追加します
is_deleted
ブールフィールド。- 利点:シンプル。
- 短所:日付記録なし。私に追加するように強制します
is_deleted = 0
すべてのクエリで。
Aを追加します
deleted_date
日付フィールド。これはに設定されていますNULL
削除されていない場合。- 利点:日付があります。
- 短所:それでも私のクエリを乱雑にしています。
上記の両方の場合
- また、これらすべての役に立たない行があるため、パフォーマンスにも影響を与えます。それらはまだインデックスで維持する必要があります。また、のインデックス
deleted
列は、行の非削除(大多数)を取得するときに役に立ちません。完全なテーブルスキャンが必要です。
別のオプションは、削除されたアイテムを保持するために別のテーブルを作成することです。
- 利点:非削除されていない行を照会するときのパフォーマンスの向上。非削除された行で私のクエリに条件を追加する必要はありません。インデックスメンテナンスが簡単です。
- 短所:複雑さ:削除と削除の両方のデータ移行が必要です。新しいテーブルが必要です。参照整合性の処理は困難です。
より良い選択肢はありますか?
解決
キーが数値の場合、キーを無効にすることで「ソフトデレート」を処理します。 (もちろん、IDキーでは機能しません)。コードをまったく変更する必要はなく、-1を掛けることでレコードを簡単に復元できます。
何らかの考えを与える別のアプローチ...キーが英数字の場合、ユニークな「マーカー」文字を準備することで同様のことをすることができます。削除されたレコードはすべてこのマーカーから始まるので、インデックスでそれ自体が終了します。
他のヒント
私は個人的に、削除されたデータにアクセスしたいユーザーや削除されたデータを「復元」することを期待する頻度に基づいて答えを出します。
頻繁にある場合は、「date_deleted」フィールドを使用して、コードのPocoに計算された「iSDELETED」を配置します。
それが決して(またはほとんど)ない場合、履歴テーブルまたは削除されたテーブルは、あなたが説明した利点に適しています。
私は個人的には、参照の完全性に対する潜在的なリスクがあるため、削除されたテーブルをほとんど使用しません(およびISDEletedまたはdate_deletedを選択します)。 A-> bがあり、Bデータベースからレコードを削除します。デザインの選択のために参照の完全性を管理する必要があります。
私の意見では、スケーリングと最終的なテーブル/データベースサイズについて考えるときの最良の方法は、3番目のオプションです。削除されたアイテムの別のテーブルです。このようなテーブルは、最終的にスケーリングをサポートするために別のデータベースに移動できます。
最も一般的な3つのオプションをリストしたことがあると思います。あなたが見たように、それぞれには利点と欠点があります。個人的には、私は物事についてより長い見方をするのが好きです。
呼ばれるフィールドを作成するとしましょう dead
削除された行をマークします。フィールドでインデックスを作成できます dead
偽です。このようにして、ヒント使用インデックスを使用して、非削除された行のみを検索します。
オプションの分析は良いと思いますが、以下にリストしたいくつかの関連ポイントを逃しました。最初の2つのオプションで提案されているように、私が見たほぼすべての実装では、行上のある種の削除またはバージョン化フィールドを使用します。
削除されたフラグで1つのテーブルを使用してください:インデックスがすべて削除されたフラグフィールドを最初に含み、クエリが主にisDeleted = falseタイプ構造を含む場合、パフォーマンスの問題を解決し、インデックスは削除された行を非常に効率的に除外します。削除された日付オプションには、同様のロジックを使用できます。
2つのテーブルを使用します一般に、一部のレポートは削除されたデータを参照する可能性があるため、レポートに大規模な変更を加える必要があります(古い販売数値などが削除された販売カテゴリを参照する場合があります)。これを克服することができます。これは、2つのテーブルから読み取り、アクティブレコードテーブルにのみ書き込むビューを作成できます。