0

データベースに監査ログを実装しているので、すべてに CreatedAt 列と RemovedAt 列があります。ここで、オブジェクト グラフのすべてのリビジョンを一覧表示できるようにしたいと考えていますが、そのために考えられる最善の方法は、共用体を使用することです。一意の CreatedAt ID と RemovedAt ID をすべて取得する必要があります。

州のある国のリストを取得している場合、ユニオンは次のようになります。

SELECT c.CreatedAt AS RevisionId from Countries as c where localId=@Country
UNION
SELECT p.CreatedAt AS RevisionId from Provinces as p 
INNER JOIN Countries as c ON p.CountryId=c.LocalId AND c.LocalId = @Country
UNION
SELECT c.RemovedAt AS RevisionId from Countries as c where localId=@Country
UNION
SELECT p.RemovedAt AS RevisionId from Provinces as p 
INNER JOIN Countries as c ON p.CountryId=c.LocalId AND c.LocalId = @Country

より複雑なクエリの場合、これは非常に複雑になり、パフォーマンスが非常に低下する可能性があるため、誰かがより良いアプローチを考えられるかどうかを確認したかった. これは MSSQL サーバーにあります。

これはfrom句で使用されており、実際のデータはこれに結合することから得られるため、すべてを単一のリストに含める必要があります。

4

3 に答える 3

1

別の方法は、次のような監査ログを作成することです。

AuditLog table
    EntityName varchar(2000),
    Action varchar(255),
    EntityId int,
    OccuranceDate datetime

ここで、EntityNameはテーブルの名前(例:Contries、Provinces)、Actionは監査アクション(例:Created、Removedなど)、EntityIdは元のテーブルの変更された行の主キーです。

テーブルに対して実行される各アクションで、テーブルの同期を維持する必要があります。これを行うには、いくつかの方法があります。

1)AuditTableに行を追加する各テーブルでトリガーを作成します
。2)アプリケーションから、repectivetablesに変更が加えられるたびにAuditTableに行を追加します。

このソリューションを使用すると、監査でログのリストを取得するのは非常に簡単です。

元のテーブルから列を取得する必要がある場合は、次のような結合を使用することもできます。

select *
from 
    Contries C 
    join AuditLog L on C.Id = L.EntityId and EntityName = 'Contries'
于 2008-10-21T08:01:24.513 に答える
1

ほとんどの場合、既にソリューションを実装していますが、いくつかの問題に対処する必要があります。アレリスのソリューション、またはその派生物を検討することをお勧めします。

  • あなたのテーブルには、「removed at」フィールドがあります。そのフィールドがアクティブである (入力されている) 場合、技術的にはデータは存在しないはずです。または、実装によって削除のフラグが立てられている可能性があります。これにより、ログが中断されます。それ削除されたら。
  • レポート期間中に複数の更新があるとどうなりますか -- 以前のログ エントリは上書きされます。
  • 別のログを持つことで、ログ情報のアーカイブが可能になり、更新/編集サイクルとは異なるログ分析サイクルを設定できます。
  • 元のソース データに戻れるようにするために必要な「リンク」フィールドを追加するか、説明を十分に冗長にします。

    ログに含まれるフィールドは自由ですが、Aleris のソリューションは直接的です。アクション テーブルを作成し、アクション テーブルへのリンクとして、フィールド タイプを varchar から int に変更する場合があります。これにより、開発者は標準化されたアクションを実行するようになります。

    それが役に立てば幸い。

  • 于 2008-11-11T01:31:24.250 に答える
    0

    おそらくクロスジョインと合体でそれを行うことができますが、パフォーマンスの観点からは、ユニオンの方がおそらく優れています。ただし、それぞれをテストしてみることができます。

    SELECT
         COALESCE(C.CreatedAt, P.CreatedAt)
    FROM
         dbo.Countries C
    FULL OUTER JOIN dbo.Provinces P ON
         1 = 0
    WHERE
         C.LocalID = @Country OR
         P.LocalID = @Country
    
    于 2008-10-21T15:45:16.527 に答える