web-dev-qa-db-ja.com

参照整合性でデータベースをアーカイブするシステムの設計

非常に大規模なOracleデータベースがあり、多くのテーブルと数百万の行があります。一部の行をエンドツーエンドで削除する必要があります。つまり、テーブルから行を削除する場合、最初に子テーブル内の対応するすべてのレコードを削除し、親テーブルエントリの削除中に制約違反エラーなしに削除が行われるようにする必要があります。

例として:

Table A defines dependency over Table B and Table C (means Table A has foreign key constraint on Table B and Table C).
Table B defines dependency over Table C and Table D.

私はこのような特定の順序で行を削除したいのですが:

テーブルA <=テーブルB <=テーブルC <=テーブルD

私は2つのアプローチを考え出しました:

  1. 親テーブルのrowIDを取得し、データ全体をJSON形式でアーカイブし、cascadeオプションを使用してエントリを削除し続けるサービスAPIを使用します。

  2. その他のオプションは、削除された値を保存するためにトリガーと一緒にカスケード付き削除を使用することです。

データがフェッチされたら、類似のアーカイブされたテーブルTable_A_archived、Table_B_archivedなどにデータを配置したいと考えています。または、ファイルでフェッチできる場合も問題ありません。

初期のアプローチに関する考えは非常に価値があります。誰かがこのようなことを以前にしたことがあるなら、彼らの経験から学ぶのは素晴らしいことでしょう。

ちなみに、これはライブデータベースであり、私は不合理なことを行うことはできません(製品にプッシュする前にテストできることは明らかです:))。また、削除/アーカイブは時間だけに基づくものではありません。

前もって感謝します!

3

データをアーカイブテーブルに移動すると、「ライブテーブル」内のデータ量は減りますが、データベース全体のサイズは減りません。したがって、それが目的の場合は、必要に応じて簡単に圧縮できるファイルを使用してください。

ただし、後でアーカイブデータをクエリできるようにする必要があり、データベースのサイズが実際に問題ではない場合は、アーカイブテーブルの方が適しています。

トリガーの使用は、本番プロセス中にアーカイブプロセスを同期的に実行する必要がある場合にのみ意味があります(たとえば、通常の本番環境でデータにDELETEコマンドを発行するたびに、関連するレコードをすぐにアーカイブする必要がある場合)。一方、アーカイブプロセスが非同期プロセスになるように設計されている場合、おそらく勤務時間後に実行され、アーカイブするデータを識別するためのタイムスタンプフィルターを使用する場合、トリガーを使用する必要はありません。代わりに、いくつかの一括削除を使用してアーカイブプロセスを設計できます。これは、レコードを次々に削除するよりもはるかに高速です。

2
Doc Brown

アーカイブテーブルを使用し、トリガーを使用してレコードをアーカイブテーブルにアーカイブします。これらのトリガーは、テーブル定義からプログラムで生成できます。

次に、カスケードオプションを使用してレコードを削除するだけで、アーカイブが自動的に作成されることがわかります。

2
Ben