3

5 つの異なるテーブルに分割されたエンティティがあります。これらのテーブルのうち 3 つのレコードは必須です。他の 2 つのテーブルのレコードはオプションです (エンティティのサブタイプに基づきます)。

テーブルの 1 つがエンティティ マスターに指定されます。他の 4 つのテーブルのレコードは、マスターからの一意の ID をキーとしています。

更新/削除トリガーが各テーブルに存在し、レコードの変更後、(トリガー内の削除されたテーブルから) 履歴が関連する履歴テーブルに保存されます。各履歴テーブルには、関連するエンティティ フィールドとタイムスタンプが含まれています。

したがって、ライブ レコードは常にライブ テーブルにあり、履歴/変更は履歴テーブルにあります。履歴レコードは、タイムスタンプ列に基づいて並べ替えることができます。明らかに、タイムスタンプ列は履歴テーブル間で関連付けられていません。

さて、より難しい部分です。

  1. レコードは、最初は 1 つのトランザクションで挿入されます。1 回のトランザクションで 3 つまたは 5 つのレコードが書き込まれます。
  2. 個々の更新は、5 つのテーブルのいずれかまたはすべてに対して発生する可能性があります。
  3. すべてのレコードは、単一のトランザクションの一部として更新されます。ここでも、1 回のトランザクションで 3 つまたは 5 つのレコードが更新されます。
  4. 番号 2 は複数回繰り返すことができます。
  5. 番号 3 は複数回繰り返すことができます。

アプリケーションは、単一のトランザクションとしてのみ書き込まれたレコードに基づいて、ある時点の履歴エントリのリストを表示することになっています (ポイント 1、3、および 5 のみ)。

現在、タイムスタンプ データのみに基づいて履歴レコードを取得するアルゴリズムに問題があります。

トランザクションに関する追加情報を保持する HISTORYMASTER テーブルを追加すると、問題が部分的に解決されるようです。すべてのトランザクションの前に、新しいレコードが HISTORYMASTER に追加されます。新しい HISTORYMASTER.ID は、トランザクション中に各エンティティ テーブルに保存されます。特定の HISTORYMASTER.ID (タイムスタンプ順) の最初のレコードを選択することで、特定の時点の履歴を取得できます。

複数のテーブルにまたがるエンティティの AFTER (UPDATE, DELETE) TRIGGER に基づいて監査テーブルを管理する最適な方法はありますか?

4

3 に答える 3

1

あなたの HistoryMaster は、私たちのシステムの 1 つで複数の関連アイテムの履歴に対処した方法に似ているようです。関連するすべての変更をヒストリー テーブルにハングアップする単一のポイントを持つことで、ヒストリー マスターをハブとして使用し、関連情報を添付するビューを簡単に作成できます。また、監査が望ましくない履歴にレコードを作成しないようにすることもできます。

私たちの場合、プライマリ テーブルは EntityAudit と呼ばれ (エンティティは保持される「プライマリ」アイテムでした)、すべてのデータは Audit に関連する EntityHistory テーブルに格納されていました。私たちの場合、ビジネス ルールにデータ レイヤーを使用していたので、監査ルールをデータ レイヤー自体に挿入するのは簡単でした。すべての変更がそのデータレイヤーを使用する場合に限り、データレイヤーはそのような追跡に最適なポイントだと思います。個別のデータ レイヤーを使用する (またはまったく使用しない) 複数のアプリケーションがある場合、マスター レコードを作成するためのトリガーがほぼ唯一の方法であると思われます。

監査で追跡する追加情報がない場合(たとえば、メイン テーブルにないものなど、変更を行ったユーザーを追跡します)、「プライマリ」レコード自体に追加の監査 ID を配置することを検討します。あなたの説明は、個々のテーブルへのマイナーな変更に関心があることを示しているようには見えませんが、エンティティ セット全体を更新する変更のみに関心があるようです (ただし、読み逃す可能性があります)。ただし、マイナーな編集を気にしない場合にのみそうします。私たちの場合、関連するレコードも含めて、すべての変更を追跡する必要がありました。

Audit/Master テーブルを使用すると、ソース テーブルと比較して履歴テーブルに最小限の変更を加えるという利点があることに注意してください。データベース)。

于 2009-01-26T16:47:08.357 に答える
0

TimeStamp / RowVersion データ型の列をエンティティ マスター テーブルに追加して、すべての監査レコードをそれに関連付けることはできますか?

ただし、「子」テーブルのいずれかへの更新では、Master エンティティ テーブルを更新して、TimeStamp/RowVersion を強制的に変更する必要があります:(

または、関連するレコードのいずれかが変更されるたびに更新する GUID をそこに貼り付けます。

大声で、Master Entity IDとレコードの「バージョン番号」-TimeSTamp/RowVersion、GUI​​D、増分番号、または他の何か。

于 2009-02-15T23:35:06.390 に答える
0

これは、アプリケーション スタックの最下位レベルであるデータベースで「抽象的な」監査イベントをキャプチャしようとする兆候だと思います。

可能であれば、ビジネス層で監査イベントをトラップすることを検討してください。これにより、行ごとではなく、論理トランザクションごとに履歴を取得できます。日付/時刻は、行ごとに異なる可能性があり、同時 (または間隔が狭い) トランザクションでも同じになる可能性があるため、このような問題の解決には信頼できません。

ただし、DBトリガーでこれを行う方法を尋ねたことは理解しています。SQL Server についてはわかりませんが、Oracle ではDBMS_TRANSACTION.LOCAL_TRANSACTION_IDシステム パッケージを使用して現在のトランザクションの ID を返すことでこれを克服できます。同等の SQLServer 値を取得できる場合は、これを使用して、現在のトランザクションのレコード更新を 1 つの論理パッケージに結び付けることができます。

于 2009-02-26T06:29:02.817 に答える