3

次の問題の解決策が必要です。

毎日変更される SQL Server 2008 にテーブルがあります。これは、最大で 5000 行と 5 フィールド程度の小さなテーブルです。

クライアントは、テーブル内のすべてのデータを特定の時点の状態で表示できる必要があります。たとえば、「2 週間前のテーブルのすべてのデータがどのように見えたかを示してください」。

http://autoaudit.codeplex.com/でテーブルを監査すると、この問題が解決するだろうと誰かが言っていました。

私の質問:

  1. 簡単な監査を伴うこの問題の解決策はありますか?
  2. もしそうなら、この問題を解決するために監査をどのように使用しますか?
  3. この種の課題に対して、車輪を再発明する必要がないように、別の解決策が既に存在していますか?
4

4 に答える 4

2

トリガーによって操作される監査テーブルを用意します。何かのようなもの:

create table YourAuditTable
(
    -- all of your source table's columns
    CreateDate datetime not null,
    DeleteDate datetime null
)
go

トリガーは次のようになります。

create trigger AuditYourTable
on dbo.YourTable
after insert, update, delete
as

    if exists(select * from inserted)
    begin
        if exists(select * from deleted)
        begin
            -- this is for an update
            update YourAuditTable
            set DeleteDate = getdate()
            where YourIDCol in (select YourIDCol from deleted)
        end 

        -- this is just for an insert
        insert into YourAuditTable
        select *, getdate() as CreateDate
        from inserted
    end
    else
    begin
        -- this is just for a delete
        update YourAuditTable
        set DeleteDate = getdate()
        where YourIDCol in (select YourIDCol from deleted)
    end

go

これにより、ある時点で監査テーブルにクエリを実行できます。つまり、DATEDIFF行がその特定の時点より前に作成され、その後に削除された (またはまったく削除されなかった) かどうかを判断するために使用します。

編集

特定の時点のデータについて監査テーブルをクエリするには、次のようにします。

select *
from YourAuditTable
where CreateDate <= @PointInTimeDateTime
and
(
    DeleteDate is null or
    DeleteDate > @PointInTimeDateTime
)
于 2012-01-11T21:43:06.990 に答える
1

履歴をテーブルに直接保存することもできます。activedate列とinactivedate列を追加します。挿入または変更の時刻を気にしない場合は、日時の代わりに日付列を使用してください。

これが既存のシステムで行われる場合は、テーブルの名前を変更してください。現在アクティブなレコードのみを表示するビューを作成し、古いテーブルが以前呼び出されていた名前を付けます(したがって、すべての古いコードが壊れることはありません)。

これが新しいシステムの場合は、上記の列を使用してテーブルを作成し、アクティブなレコードのみを取得するビューを作成します。これにより、開発者はアクティブビューを一貫して使用できるようになるため、現在のデータを表示するときにレコードをフィルタリングすることを忘れないでください。

レコードの更新プロセスを通常行う方法を変更する必要があります(トリガーの代わりにこれを行います)。これにより、レコードが更新されたときに、現在のレコードに非アクティブな日付が追加され、新しい日付が追加されます。トリガーの代わりにレコードを使用して削除する場合も同じようにして、レコードを削除するのではなく非アクティブ化します。これが新しいプロセスである場合は、トリガーをスキップして、同じことを行う更新と、削除するときに提出された非アクティブな日付への更新を書き込むことができます。ただし、データの整合性を確保するという点では、トリガーの方が信頼性が高いと思います。私はトリガーの代わりに個人的に行い、開発者がユーザーインターフェイスで通常の更新と削除を記述できるようにします。これにより、GUIからのものであれ、SSMSのアドホックアップデートからのものであれ、すべてのチャグが適切に処理されるようになります。

次に、日付パラメータを使用してストアドプロシージャを記述し、日付入力でアクティブなデータを返します(日付入力が、これを開始したデータよりも早い場合は、処理するための特別なコードが必要になる場合があります)。次に、GUIフォームでこれを使用します。特定の日付のデータを表示するユーザー。

于 2012-01-11T22:33:44.210 に答える
1

テーブルを「一時テーブル」として実装できます。

ここで何が起こるかというと、「実際の」テーブルは履歴を保持するテーブルだけです。ただし、ほとんどの場合、元のテーブルとまったく同じ方法で処理できるインデックス付きビューもあります。また、これはインデックス付きビューであるため、パフォーマンスのために必要なインデックスを追加できます。

挿入/更新/削除のパフォーマンスにオーバーヘッドがあります (ただし、トリガーベースのソリューションにはオーバーヘッドがあります)。

(UDF を介して) 要求している「特定の時点」のアクセスを簡単にサポートします。

これについて追加または説明したいことがあれば、私に知らせてください - 私は記事 (およびフォローアップ) を数か月前に書きましたが、次に何を追加するかについての蒸気/アイデアを使い果たしました.

于 2012-01-12T07:46:04.253 に答える
-1

これは MS SQL 用です。(また、特定の日付のデータを表示する必要がある場合にのみ機能します。より正確な時点にドリルダウンする必要がある場合は、監査テーブルの回答を使用してください。)

テーブルが非常に小さいため、MS SQL が提供するスナップショット機能を使用するのが最善です。

データベースのスナップショットを作成するには:

CREATE DATABASE YourDB_Snapshot_DateStamp ON
( NAME = YourDB_Data, FILENAME = 
'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Data\YourDB_Snapshot_DateStamp.ss' )
AS SNAPSHOT OF YourDB;
GO

このページを参照してください: http://msdn.microsoft.com/en-us/library/ms175876.aspx

必要な数のスナップショットを作成できます。したがって、私のアドバイスは、毎日のスナップショットを作成し、日付をスナップショット名に追加するスクリプトまたはタスクを作成することです。このようにして、サーバー上ですべてのスナップショットを表示できます。

重要な注意事項: スナップショットは読み取り専用です。

于 2012-01-12T07:20:59.600 に答える