我们的讨论中最近出现了关于如何审核表格的主题......所以我喜欢您对最新方法的看法。我们在数据库中混合使用这两种方法(不是很好),因为每个以前的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)表存储在审计表中。
优点:如果您需要了解特定记录的历史记录,您可以将所有内容放在一个位置。
虽然我没有在这里列出所有这些,但每种方法都有其优点和缺点?
答案 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。
如果审计表中有单独的行,则必须使用“下一行”连接一行来计算差异 - 在某些情况下这可能很棘手......