私はSOでいくつかの質問を読みました(例えばこれです) を参照してください。
挙げられた提案のいくつかは気に入りました。私は長い間、多くのテーブルを修正したい(必要)と思っていましたが、なかなか実行できませんでした。私はプログラマーですが、データベースに関する簡単な作業しか経験したことがないので、これを実際にどのように行うのか疑問に思っていました。
私は SQL 構文の実際の解決策を求めているのではありません。最終的には自分で解決できるでしょう (または、時期が来たら SO を投稿します)。私が求めているのは、何億ものレコードを「修正」した場合に、どのように実行するか、また、パフォーマンス上の潜在的な問題が発生する可能性があるかについて、皆さんにコメントしていただくことです。または、以下の例に基づいている限り、その他の提案でも構いません。
簡単な例を挙げます。
Person
------------------------------------------------
ID UINT NOT NULL,
PersonID UINT NOT NULL,
Name VARCHAR(200) NOT NULL,
DOB DATE NOT NULL,
Email VARCHAR(100) NOT NULL
Audit
------------------------------------------------
ID UINT NOT NULL,
UserID UINT NOT NULL, -- Who
TableName VARCHAR(50) NOT NULL, -- What
OldRecID UINT NOT NULL, -- Where
NewRecID UINT NOT NULL,
AffectedOn DATE NOT NULL, -- When
Comment VARCHAR(500) NOT NULL -- Why
TableName が文字列の場合、Audit テーブルを他のテーブル (Person など) にリンクする方法がわかりません。
また、次の 3 つの GUI を入力する必要があると仮定します。
- 特定の人物IDの完全な記録
- すべての人物をリストするテーブルビュー(ID別)
- 各エントリの下に各人の改訂情報 (各人の改訂回数、改訂日、改訂コメントなど) が最新の改訂順に表示され、表示されるビュー。
1 と 2 を実現するには、Person テーブルまたは Audit テーブルをクエリする方がよいでしょうか。
3 を達成するには、いわゆるデータベース エキスパートがすべてのレコードを取得してソフトウェアに渡して処理するだけでしょうか、それとも PersonID と影響日でグループ化するのでしょうか。これは通常、1 つのクエリで処理されるのでしょうか、それとも複数のクエリで処理されるのでしょうか。
ベストアンサー1
私は長年にわたりさまざまな監査スキームを実施してきましたが、現在は次のようなものを実装する予定です。
Person
------------------------------------------------
ID UINT NOT NULL,
PersonID UINT NOT NULL,
Name VARCHAR(200) NOT NULL,
DOB DATE NOT NULL,
Email VARCHAR(100) NOT NULL
Person_History
------------------------------------------------
ID UINT NOT NULL,
PersonID UINT NOT NULL,
Name VARCHAR(200) NOT NULL,
DOB DATE NOT NULL,
Email VARCHAR(100) NOT NULL
AuditID UINT NOT NULL
Audit
------------------------------------------------
ID UINT NOT NULL,
UserID UINT NOT NULL, -- Who
AffectedOn DATE NOT NULL, -- When
Comment VARCHAR(500) NOT NULL -- Why
現在のレコードは常に Person テーブルにあります。変更があった場合は監査レコードが作成され、古いレコードが Person_History テーブルにコピーされます (ID は変更されず、複数のバージョンが存在する可能性があることに注意してください)。
監査 ID は *_History テーブルにあるため、必要に応じて複数のレコードの変更を 1 つの監査レコードにリンクできます。
編集:
各基本テーブルに個別の履歴テーブルがなく、同じテーブルを使用して古いレコードと「削除された」レコードを保持する場合は、レコードにステータス フラグを付ける必要があります。これの問題は、現在のレコードをクエリするときに非常に面倒なことです。信じてください、私はこれをやったことがあります。