3

最近在我们的讨论中出现了如何审计表的话题……所以我喜欢你对解决这个问题的最佳方法的看法。我们在我们的数据库中混合了这两种方法(这并不好),因为每个以前的 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,被替换的记录被插入到审计表中,其中 'Audit_Type' 列作为枯萎的 'U' (用于 UPDATE )或 'D' (用于 DELETE)

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

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

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

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

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

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

4

2 回答 2

4

我会去:

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

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

如果您清除行(范围都早于 X 天),您仍然可以判断某些内容是否发生了变化:

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

如果您使用 Appraoch 1: 并清除一个范围,则很难(需要记住清除日期)告诉新插入与清除所有行的位置。

于 2009-09-25T17:44:49.673 回答
0

我们经常使用的第三种方法是只审核感兴趣的列,并在每一行上保存“新”和“旧”值。

所以如果你有你的“name”列,审计表就会有“name_old”和“name_new”。

在 INSERT 触发器中,“name_old”根据您的偏好设置为空白/null,“name_new”是从 INSERTED 设置的。在 UPDATE 触发器中,“name_old”从 DELETED 设置,“name_new”从 INSERTED 在 DELETE 触发器中,“name_old”从 DELETED 设置,“new_name”设置为空白/空。

(或者您对所有情况都使用 FULL join 和一个触发器)

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

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

quantity_old  quantity_new
           5             7

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

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

于 2009-09-25T17:29:15.053 回答