プロジェクトでは、エンティティのすべてのリビジョン (変更履歴) をデータベースに保存する必要があります。現在、これに関して 2 つの設計提案があります。
例: 「従業員」エンティティの場合
デザイン1:
-- Holds Employee Entity
"Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"
-- Holds the Employee Revisions in Xml. The RevisionXML will contain
-- all data of that particular EmployeeId
"EmployeeHistories (EmployeeId, DateModified, RevisionXML)"
デザイン2:
-- Holds Employee Entity
"Employees (EmployeeId, FirstName, LastName, DepartmentId, .., ..)"
-- In this approach we have basically duplicated all the fields on Employees
-- in the EmployeeHistories and storing the revision data.
"EmployeeHistories (EmployeeId, RevisionId, DateModified, FirstName,
LastName, DepartmentId, .., ..)"
これを実行する他の方法はありますか?
「デザイン 1」の問題は、データにアクセスする必要があるたびに XML を解析する必要があることです。これによりプロセスが遅くなり、リビジョン データ フィールドに結合を追加できないなどの制限も追加されます。
「デザイン 2」の問題は、すべてのエンティティのすべてのフィールドを複製する必要があることです (リビジョンを維持するエンティティは約 70 ~ 80 個あります)。
ベストアンサー1
ここで問うべき重要な質問は、「誰が / 何が履歴を使用するのか」ということだと思います。
主にレポート作成や人間が判読できる履歴を目的としている場合は、過去にこのスキームを実装したことがあります...
「AuditTrail」というテーブル、または次のフィールドを持つテーブルを作成します...
[ID] [int] IDENTITY(1,1) NOT NULL,
[UserID] [int] NULL,
[EventDate] [datetime] NOT NULL,
[TableName] [varchar](50) NOT NULL,
[RecordID] [varchar](20) NOT NULL,
[FieldName] [varchar](50) NULL,
[OldValue] [varchar](5000) NULL,
[NewValue] [varchar](5000) NULL
次に、テーブルを更新または挿入するたびに設定される「LastUpdatedByUserID」列をすべてのテーブルに追加できます。
次に、すべてのテーブルにトリガーを追加して、発生する挿入/更新をキャッチし、変更されたフィールドごとにこのテーブルにエントリを作成します。テーブルには更新/挿入ごとに「LastUpdateByUserID」も提供されるため、トリガーでこの値にアクセスし、監査テーブルに追加するときに使用できます。
RecordID フィールドを使用して、更新するテーブルのキー フィールドの値を保存します。結合キーの場合は、フィールド間に '~' を使用して文字列を連結するだけです。
このシステムには欠点があると思います。頻繁に更新されるデータベースではパフォーマンスが低下する可能性がありますが、私の Web アプリでは書き込みよりも読み取りの方がはるかに多く、パフォーマンスはかなり良好のようです。テーブル定義に基づいてトリガーを自動的に書き込むための小さな VB.NET ユーティリティも作成しました。
ちょっとした考え!