2012-01-11 8 views
3

私は次の問題の解決策が必要です。テーブルのスナップショットを使用するためにテーブル監査を使用する

SQL Server 2008に毎日変更されるテーブルがあります。たぶん5,000行、おそらく5フィールドの小さなテーブルです。

クライアントは、指定された時点での表のすべてのデータを表示する機能が必要です。たとえば、「2週間前にすべてのデータがテーブルに表示されたことを表示する」

誰かがhttp://autoaudit.codeplex.com/でテーブルを監査するとこの問題を解決すると述べました。

私の質問:

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

答えて

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を使用して、指定された時点より前に行が作成されたかどうかを判断し、その後に削除されるかどうか(まったく削除されないかどうか)を指定します。

EDIT

時間データにポイントの監査テーブルを照会するには、次の

select * 
from YourAuditTable 
where CreateDate <= @PointInTimeDateTime 
and 
(
    DeleteDate is null or 
    DeleteDate > @PointInTimeDateTime 
) 
+0

ありがとうございます!特定の日付にテーブルにあったデータを見るためにこれをどのようにクエリするのですか? –

+0

@I__私の編集をチェックしてください。そのクエリはあなたのために働くはずです。 –

+0

これは信じられないほど単純で驚くほど完璧な解決策です。ありがとうございました –

1

また、あなたのテーブルに直接履歴を保存することができます。 activedateカラムとinactivedateカラムを追加します。挿入または変更の時間を気にしない場合は、datetimeではなくdateカラムを使用します。

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

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

通常、更新レコードの処理方法を変更する必要があります(トリガーではなく、これを実行します)。レコードが更新されると、現在のレコードの非アクティブな日付に配置され、新しいもの。レコードを削除するのではなく、そのレコードを非アクティブにするには、トリガーの代わりに「」を使用して削除と同じ操作を行います。これが新たなプロセスである場合は、トリガーをスキップして、delteしたいときに入力された非アクティブな日付と同じことと更新を行う更新を書き込むことができます。しかし、データの完全性を保証する上で、トリガーはより信頼できます。私は個人的にはトリガーの代わりに、開発者はユーザーインターフェースで通常の更新と削除を書くことができます。これは、GUIから来たものであろうと、SSMSの特別なアップデートから来たものであろうと、すべてのシャングが適切に処理されるようにします。

次に、日付入力でデータをアクティブに戻すために日付パラメータを持つストアドプロシージャを作成します(これを実行したデータより日付入力が早い場合は特別なコードが必要です)。ユーザが特定の日付のデータを見るためのGUIフォーム。

+0

ありがとうございます!これはスーパースーパーに役立ちます。これはまだ存在しないと私はゼロから実装しているという前提であなたの答えを更新してください。それは私にとって大変役に立つでしょう –

-1

これはMS SQL用です。 (正確な時点にドリルダウンする必要がある場合は、spesic日付のデータを表示する必要がある場合にのみ機能します)

表が小さいほど、 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

あなたはできるだけ多くのスナップショットを作成することができます。だから私のアドバイスは、毎日のスナップショットを作成し、スナップショット名に日付を追加するスクリプトやタスクを作成することです。この方法で、すべてのスナップショットをサーバー上に表示できます。

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

1

テーブルを"temporal tables"として実装できます。

ここで起こるのは、「本当の」唯一のテーブルは履歴を保持するテーブルだということです。しかし、インデックス付きのビューも用意されています。ほとんどの場合、元のテーブルとまったく同じ方法で扱うことができます。また、索引付けされたビューであるため、パフォーマンスのために必要な索引を追加できます。

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

あなたが求めている「ポイントインタイム」アクセスを(UDFを介して)簡単にサポートします。

これを追加したり、説明したいことがあれば、私に知らせてください - 私はかなりの数ヶ月前に記事を書いていますが、追加するものは何もない次。

+0

それはかなり素晴らしい解決策のように見えます!!!!!!!!!実装が簡単ですか? –

+0

は簡単に実装できますか? –

+0

@I__ - それを実装する際に問題はありませんでした。 「簡単」は定量化するのが難しい。 –

関連する問題