実際には削除されない「削除済み」レコードのカスケード


8

このシナリオで人々が何をするかについていくつかのアイデアを得ようとしています。テーブルのあるシステムデータベース(SQL Server 2008 R2)があり、すべてのテーブルに "削除済み"と呼ばれるフィールドがあります。レコードが削除された場合は基本的にビットフィールドであり、レコードが0の場合は削除されません。フィールドはnull可能ではなく、そのデフォルトはもちろん0です。

データベースへの実際の削除は許可しないため、これを回避するには、ビットフィールド(Deleted)をtrueに設定します。このアプリケーションでは、次のようなクエリが作成されます。

SELECT blah FROM MyTable WHERE .. AND Deleted=0

基本的に、レコードをフィルタリングして、削除されていない行のみを取得します。私たちの問題は、カスケードする必要がある関連レコードです。人々は何を好むのでしょうか。サーバー側のコードでこれを行うと、レコードを削除したときに、関連するすべてのレコードが削除されます(削除済みビットフィールドがtrueに設定されます)。それとも、これはこのフィールドをチェックし、すべての関連レコードのビットフィールドを1に設定する必要があるトリガーでしょうか。

それとも、私たちは完全に間違った道を進んでいますか?


削除されたビューを使用して、決して画像に入れず、そのビットフィールドでグループ化する
ラチェットフリーク

@ratchetfreak-これは関連するレコードには役立ちません...削除のカスケードをどのように処理しますか?問題が関連付けられている会社のページを想像してください。誰かが会社を削除した場合(Company.Deleted = 1を設定)、その会社に関連付けられている問題をどのように削除しますか?
JonH 2014年

2
それを自動化するのは更新トリガーだけです
ラチェットフリーク

1
@ratchetfreak-それは私の質問のようなものです。更新トリガーを介して、またはサーバー側のコードを介してそれを処理する必要があるのか​​、そしてその理由。私はこれに対する答えを知っています。他の人がソフト削除のために何をしているのかを知りたいと思っていました-どのように関係をソフト削除しますか(カスケード削除は本当に削除せずにあなたを持っています)。
JonH 2014年

2
なぜ関連データを削除する必要があるのですか?関連データの親にアクセスできない場合、どのようにアクセスしますか?
Kevin

回答:


2

ここには良い解決策はありません。データベースは、外部キーによる特別で効率的なカスケード削除を提供しますが、実際の削除が選択肢にない場合は、そのネイティブカスケードを利用できません。

削除が一般的であるかまれな発生であるかに応じて、何かを疑似削除するとき、または追加のクエリまたはトリガーを介してカスケードをすぐにエミュレートするか、または常に常にDBからすべてをフェッチして削除にフィルターをかける方が効率的です。ビジネスロジックのフラグ。

個人的に、私は常に3番目のオプションを使用しました。すべての従属レコードはマスターレコードからのみアクセスできます。これは、そのレコードが一時的に削除された場合は発生しないため、何もする必要はありません。明らかにこれは、データモデルが厳密なツリー(コメントが適用される製品を表示するときにのみ取得される、ユーザー特権が所属するユーザーを管理するときにのみ取得されるなど)の場合にのみ機能します(クエリを実行する可能性がある場所)。すべてのコメントまたはすべての特権レコードは無関心ですが)、これは驚くほど多くのシナリオで機能するようにできることがわかりました。


@キリアン-私はこれが私たちが取らなければならないルートかもしれないと信じています(トリガー)。ただし、チームとして、何をカスケードすべきか、またはすべきでないかについて、ステークホルダーとさらに議論する必要があります。あなたの素晴らしい入力をありがとう。
JonH 2014年

5

私はこれまでに監査テーブルを使用しており、データベースへのすべての変更が監査ミラーテーブルに書き込まれ(挿入/更新/削除)、実際の実際のアイテムはカスケード方式で削除されます。

ミラーテーブルは、「ChangeType」、「User」、「Date」の3つの列が追加された実際のテーブルと同じです。

これには、データを正しく削除できるという二重の利点がありますが、データベースの状態をいつでも再作成でき、アイテムの完全な履歴を文書化できます。

カスケード削除の場合は追加します。通常、クライアントでのカスケード削除を優先します。ユーザーが会社を削除し、それに関連する問題がある場合、サーバーはこれについてあまり賢明にしようとしないでください-会社の削除アクションも削除する必要があります対応するレコード。

これは大手投資銀行の財務管理システム用であり、監査性は重要な機能でした。


これは1つの方法と見なすことができ、私たちはそれを考えましたが、それは金融タイプのシステムに適していると思います。さらに多くのテーブルとリレーションシップを複製する必要があり、コードベースが大幅に増加します。しかし、私はあなたのケースで必要性を見ることができます。
JonH 2014年

監査テーブルが自動的にデプロイされ、同期が保たれている場合、テーブルの複製は問題ではありません。コードと同じように、監査テーブルとライブテーブルを切り替えるためにデータレイヤーにインジェクターを提供するだけでした-すべてのクエリ同じままでした。
Michael

マイケル、このようなプロジェクトの開発者チームの大きさを尋ねても構わないなら、
JonH 2014年

少し前のことなので100%確信はありませんが、開発者4人、テスター3人、アナリスト1人と思います。
Michael

1

delete / undeleteステートメントで明示的に行います。削除をカスケードしたくないシナリオもいくつかあります。

> Update table1 set deleted=@flag where...
> Update table2 set deleted=@flag where...

例えば; 複数の住所を持つ人を考えてみましょう。

人を削除するには、人に削除フラグを設定するだけです。削除をアドレスにカスケードする必要はありません。復元するときに、それらのアドレスを元に戻したいからです。

人が移動したとすると、古いアドレスの削除フラグのみを更新し、他のアドレスと人はそのままにします。したがって、カスケードが常に必要であるとは限らず、シナリオによって異なります。

したがって、モデルの設定方法と削除する内容に応じて、明示的にする必要があると思います。


1
アプリケーションプログラマがテーブル間のすべての関係と、何をカスケードする必要があるかを認識していることを期待するのではなく、データベースによって(トリガーを使用して)整合性を維持するべきではありませんか?

@MichealIT-列を更新するだけなので、データの整合性はありません。あなたは正しいですが、更新がトリガーに入る可能性がありますが、削除操作(SP)で明示的に定義すると、見つけやすくなります。トリガーでは、削除フラグを調べて、それが1であるか0であるかに応じて適切なアクションを実行する必要があります。トリガーロジックは、ストアドプロシージャとは対照的に不明瞭になる傾向があります。
Jon Raynor 2014年

@MichealT-この例では、住所レコードを「削除」する必要がない限り、そのままにしておきます。リレーショナルデータベースの意味では、これらすべてのレコードがまだ存在しているため、リレーショナル整合性を維持しています。それらを除外することを選択するのはビジネスルールです。そしてはい、開発者はこれらすべてのソフト削除がどのように処理されるかをよりよく理解します。
JeffO 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.