使用表审计以获得表的“快照”

时间:2012-01-11 21:31:23

标签: sql sql-server sql-server-2008 auditing

我需要针对以下问题的解决方案:

我将在SQL Server 2008中有一个表,它将每天更改。这是一张小桌子,最多可能有5000行,大约有5个字段。

客户端需要能够以给定时间点的方式查看表中的所有数据。例如,“告诉我2周前表中所有数据的样子”。

有人提到用http://autoaudit.codeplex.com/审核表格可以解决这个问题。

我的问题:

  1. 这个问题的解决方案是否涉及简单的审计?
  2. 如果是这样,那么我将如何使用审计来解决这个问题呢?
  3. 对于这种挑战,是否已经存在不同的解决方案,以便我不必重新发明轮子?

4 个答案:

答案 0 :(得分: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
)

答案 1 :(得分:1)

您还可以将历史记录直接存储在表格中。您添加activedate和inactivedate列。如果您不关心插入或更改的时间,则使用日期列而不是日期时间。

如果在现有系统上完成此操作,请更改表的名称。您编写的视图仅显示当前处于活动状态的记录,并将其命名为旧表的调用(因此所有旧代码都不会中断)。

如果这是一个新系统,请使用上面提到的列创建表,并仍然编写一个只获取活动记录的视图。这将使您的开发人员能够始终如一地使用活动视图,这样他们就不会忘记在想要显示当前数据时过滤记录。

您将不得不改变通常执行更新记录过程的方式(我在一个而不是触发器中执行此操作),以便在更新记录时,将其置于当前记录中的非活动日期并添加新的一个。使用而不是触发器删除记录而不是删除记录来执行相同操作。如果这是一个新进程,您可以跳过teh触发器,只需编写执行相同操作的更新,并在您想要删除时更新到非活动日期字段。但是,我发现在确保数据完整性方面,触发器更加可靠。我个人会做而不是触发器和tehn让开发人员在用户界面中编写正常的更新和删除。这将确保所有chagnes都得到妥善处理,无论它们来自GUI还是来自SSMS中的特殊更新。

然后你用日期参数编写一个存储过程来返回日期输入中活动的数据(如果日期输入早于您开始执行此操作的数据,则可能需要一些特殊代码来处理),然后在GUI表单,供用户查看截至某个日期的数据。

答案 2 :(得分:1)

您可以将表格设为"temporal tables"

这里发生的是唯一的“真实”表是保存历史记录的表。但是,对于大多数意图,您还可以使用与原始表完全相同的方式处理索引视图。由于它是索引视图,因此您可以添加性能所需的任何其他索引。

插入/更新/删除性能有一个开销(但是对于任何基于触发器的解决方案都有。)

它很容易支持您要求的“时间点”访问(通过UDF)。

如果您有任何想要添加或解释的内容,请告诉我 - 我在几个月前撰写了这篇文章(以及后续文章),但之后对于下一步要添加的内容不知所措

答案 3 :(得分:-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

您可以根据需要制作任意数量的快照。所以我的建议是创建一个创建每日快照的脚本或任务,并将日期附加到快照名称。这样,您就可以在服务器上看到所有快照。

需要注意的重要事项:快照是只读的。