审计表:每个表的每个字段还是一个表?

29

我的项目除了审计字段外一切都很好。在我们的想象宇宙中,只有插入和更新受到审计。

我提出了一个类似于下面例子的表:

但是我的团队并不认同我的想法,他们在每个表上都添加了一个列来跟踪更新或插入时间。当我问“为什么?”时,他们告诉我这是他们工作中跟踪数据的方式。

最终,我放弃了并在每个表上都放置了这些字段,因为除了我之外的整个团队都要求这样做。

例如:

他们的方法

Table Customer
+-------------+-------------+-----+--------------------------------+-------------+
| Name        | LastName    | ... | LastModification (Audit Field) | User        |
+-------------+-------------+-----+--------------------------------+-------------+
| varchar(30) | varchar(50) | ... | datetime                       | varchar(30) |
+-------------+-------------+-----+--------------------------------+-------------+

我的方法

Table Customer
+-------------+-------------+-----+
| Name        | LastName    | ... |
+-------------+-------------+-----+
| varchar(30) | varchar(50) | ... |
+-------------+-------------+-----+

Table Audit
+-----------+------------+--------+------+-------------+
| TableName | TableField | Action | User | DateAndTime |
+-----------+------------+--------+------+-------------+

那么问题是:

哪种设计更好,一个保存交易历史记录的表格还是每个表格都有一个字段?(各自的利弊)


1
在他们的解决方案中,他们只维护具有最后更新时间的行的单个副本,还是维护多个版本的行? - Larry Lustig
@LarryLustig:复制?他们只是在表中添加了一列。根本不是副本。只是一个最后修改的字段。 - razpeitia
“their”方法提供了基于每行的语义审计,而“your”方法仅在每个表格上执行此操作。 - Sam
1个回答

45
哪种设计更好,一个保留交易历史记录的表格还是每个表格都有一个字段?(优缺点)
与其关注这两个选择,这里提供我多年来使用过的四种方法。每种方法都有其优缺点。
1. 只有三个字段
在每个表格中添加三个字段(上次操作、时间戳、更新用户),然后就可以结束了。
优点:非常简单,性能良好。
缺点:你无法报告没有数据的内容,所以这种结构几乎什么也不说(除了删除)。
2. 克隆表格
每个表格都有一份副本,加上三个审计字段,每当用户更改记录时,就会将审计表格插入其中。
优点:性能相当不错。容易创建逐行历史记录,用户可以挖掘其中的内容。
缺点:
每次对基础表进行更改都需要对审计表进行相应的更改。
如果用户不想要逐行历史记录,而是想要报告确切的更改内容,那么情况可能会变得很糟糕。请参见如何编写查询以从数据快照中提取单个更改? 3. 仅有历史记录表格

只有历史表,没有基础表。这与克隆表基本相同,只是现在您必须始终获取当前记录。

优点 2的优点,但所有内容都是插入。比选项2更少维护。

缺点 您将失去维护收益,因为您将维护视图或在各个地方添加获取当前记录的逻辑。

4.通用审计表

此表具有四列(Table*,Column_name,old_value,new_value)和三个审计字段。

优点 容易设置和维护。

缺点

  • 它不直观,但需要大量空间,因为您的 old_value new_value 字段必须是nvarchar(max)或等效的,以便接受基础表中的任何内容。

  • 读写性能差。

  • 逐行历史报告设置起来很麻烦

  • 如果记录中存在任何工作流程,则审核报告可能变得非常复杂。例如,您获得了一个要求用户仅查看状态变为“已批准”的记录之后发生的更改的要求。即使在选项2和3中,这也很困难,但在通用审计方法中将变成灾难。

总结

我更喜欢第二种克隆表格的方法,因为它似乎对我来说效果最好。我曾经遇到过第一种方法不足的问题,而第四种方法可能会导致严重的性能问题,需要大量的工作来撤消。


你好,你说你更喜欢第二种方法。从问题描述来看,“AuditTable”表中有一个“TableField”列被更改/影响了。如果我在一个表中更改了多个列,那该怎么办?我应该向“AuditTable”添加更多行吗?还有其他的方法吗?审计表是否可以保持独立,或者我应该通过某种方式与其他表建立关系? - RandomUser
我选择方案2。我通过A.编写表克隆的脚本和B.使用字段:id,时间戳,用户,操作(I,U,D),旧数据(jsonb)来标准化克隆表,消除了缺点。这样,当主表更改字段时,克隆表不需要更改。 - Christiaan Westerbeek
@christiaanwesterbeek 有两件事。Jsonb 只适用于 postgres,而且你似乎做了一些非常困难的报告。考虑一下你需要做什么来确定特定字段值何时发生变化。 - Conrad Frix
在第二个选项中,当我们想要获取某个特定时间点每个用户的快照时,我们如何优化查询?我的意思是按用户分组,然后获取每个用户的最后一条记录。 - Rushabh Patel
时间表是SQL Server 2016引入的另一个很棒的选项。 - Godwin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接