审核触发器:使用INSERTED或DELETED系统表

时间:2009-09-25 17:17:47

标签: sql-server-2005 audit auditing audit-tables

我们的讨论中最近出现了关于如何审核表格的主题......所以我喜欢您对最新方法的看法。我们在数据库中混合使用这两种方法(不是很好),因为每个以前的DBA都做了他/她认为正确的方法。所以我们需要改变它们以遵循任何一种模型。

CREATE TABLE dbo.Sample(
Name VARCHAR(20),
...
...
Created_By VARCHAR(20),
Created_On DATETIME,
Modified_By VARCHAR(20),
Modified_On DATETIME
)

CREATE TABLE dbo.Audit_Sample(
Name VARCHAR(20),
...
...
Created_By VARCHAR(20),
Created_On DATETIME,
Modified_By VARCHAR(20),
Modified_On DATETIME
Audit_Type VARCHAR(1)  NOT NULL
Audited_Created_On DATETIME
Audit_Created_By VARCHAR(50)
)

方法1:仅在审计表中存储从主表中替换/删除的记录(使用系统表DELETED)。因此,对于主表中的每个UPDATE和DELETE,正在替换的记录被INSERTED进入审计表,其中'Audit_Type'列为'U'(对于UPDATE)或'D'(对于DELETE)

INSERT未经审核。对于任何记录的当前版本,您始终可以查询主表。对于历史,您查询审计表。

优点:看似直观,存储以前版本的记录 缺点:如果您需要知道特定记录的历史记录,则需要将审计表与主表连接。

Appraoch 2:在审计表中存储进入主表的每条记录(使用系统表INSERTED)。

对主表进行INSERTED / UPDATED / DELETED的每条记录也存储在审计表中。因此,当您插入新记录时,它也会插入到审计表中。更新后,新版本(来自INSERTED)表存储在Audit表中。删除时,旧版本(来自DELETED)表存储在审计表中。

优点:如果您需要了解特定记录的历史记录,您可以将所有内容放在一个位置。

虽然我没有在这里列出所有这些,但每种方法都有其优点和缺点?

2 个答案:

答案 0 :(得分:4)

我会选择:

  

Appraoch 2:在审核表中存储进入主表的每条记录   (使用系统表INSERTED)。

每个项目还有一行真的会杀死数据库吗?这样你就可以完成整个历史。

如果您清除行(范围都超过X天),您仍然可以判断某些内容是否已更改:

  • 如果存在审核行(未清除),您可以查看相关行是否已更改。
  • 如果项目没有审计行(所有被清除)没有任何更改(因为任何更改写入审计表,包括全新项目)

如果你选择Appraoch 1:并清除一个范围,那么告诉新的插入与清除所有行的插入将很难(需要记住清除日期)。

答案 1 :(得分:0)

我们使用的第三种方法是仅审核有趣的列,并在每行中保存“新”和“旧”值。

因此,如果您有“名称”列,则审计表将具有“name_old”和“name_new”。

在INSERT触发器中,“name_old”设置为空/空,具体取决于您的首选项,“name_new”是从INSERTED设置的。 在UPDATE触发器中,“name_old”是从DELETED设置的,而“name_new”是从INSERTED设置的 在DELETE触发器中,“name_old”从DELETED设置,“new_name”设置为blank / null。

(或者对所有情况使用FULL联接和一个触发器)

对于VARCHAR字段,这可能看起来不是一个好主意,但对于INTEGER,DATETIME等,它提供的好处是很容易看到更新的差异。

即。如果您的真实表中有一个数量字段并将其从5更新为7,那么您将拥有审计表:

quantity_old  quantity_new
           5             7

您可以轻松计算出特定时间内数量增加了2。

如果审计表中有单独的行,则必须使用“下一行”连接一行来计算差异 - 在某些情况下这可能很棘手......