数据库历史记录表/跟踪表


13

目前,我想构建一个跟踪/历史记录表,如下所示:

  • PrimaryKey-ID
  • OtherTableId-fk
  • fieldName-其跟踪的字段名称
  • 旧值
  • 新价值
  • 用户名
  • CreateDateTime

因此,基本上,我希望有一个表可以跟踪另一个表的历史记录,并使用新值和旧值存储更改后的字段的列名。我的问题是,有人可以戳破这个漏洞吗?另外,最简单的方法是确保仅将其跟踪表中的列名输入到fieldName列中?目前,我的选择是在要构建的服务中包含一个枚举,或者创建另一个状态表并使fieldName成为fk。还有更好的主意吗?

修改 目标:我们目前只跟踪2个字段。一个字段将显示在网页上以显示历史记录,而另一个字段将仅由一个部门访问,并且他们有权访问他们可以查询的数据库视图。他们将只查询这一字段,以获得有关谁更改了字段以及更改内容的信息。这就是我们想要在数据库字段定义表列的位置而不是具有表记录历史记录的精确副本的地方进行设置的原因。我们只希望跟踪两个字段,以便将来增加或删除字段。

谢谢!


您事先知道要跟踪多少张表吗?
科菲·萨尔夫

该表将仅跟踪另一个表,到目前为止,我们仅跟踪该表。
user76982 2013年

因此,这种方法可能会过大。更糟糕的是,如果要重新创建快照具有任何价值,那么要查询该表并同时对其进行监视以在某个时间点重新创建实时数据将不容易。
科菲·萨尔夫

1
另一方面,使用您提出的方法可以更轻松地查询哪些列更改最频繁。
科菲·萨尔夫

您可能要在dba.stackexchange.com上搜索;那里也曾提出过类似的问题,有些可能会有您可以使用的答案。
FrustratedWithFormsDesigner 2013年

Answers:


8

戳孔:如果稍后在同一时间更改数据库架构,并且更改了列名,或者该列被完全删除,该怎么办?许多数据库系统都允许这样做。那么,您的“ fieldName”将如何处理?

为了确保数据完整性:您必须确保每次更新或删除操作都将确保更新跟踪表。最好通过触发器调用存储过程来完成。您应该确保只有那些存储过程具有对跟踪表的写访问权,以便其他任何人都不能写错值。

如果您可以使用特定于数据库供应商的解决方案:大多数数据库系统都有系统表,其中存储了模式信息(表名,表ID,列名等)。您可以检查是否可以为此类系统表设置外键引用。如果数据库支持这样的内容,则可以用字段ID替换字段名称。

实际上,如果您需要跟踪特定表的整个行,包括所有列(而不仅仅是列的一小部分),则应考虑@sarfeast的建议。阅读有关名称/值对模型的缺点的文章


8

我所见过的最成功的变更审计(历史记录跟踪)实施方式通用性较差,而且简单得多。它涉及为要监视的每个表创建一个更改日志表,并保持相同的列名和数据类型(带有一个用于时间戳的附加列)。

最终目标,即您要对审核的数据执行的操作将有助于评估每种方法的适用性。


您好Sarfeast,我添加了要实现的最终目标。很抱歉不包含此内容。
user76982 2013年


7

简而言之:您需要为要跟踪值更改的表设置“ 审核跟踪”机制。

单一审计追踪表

创建一个表来记录表名,字段名和数据的新旧版本。对于此方法,通常记录数据的旧版本和新版本,并且仅记录那些已更改的字段。要在触发器中实现此功能,要求表上有主键或仅更新单行。

这是一篇很好的文章,介绍了如何实现的脚本- 创建审计跟踪

其他有用的参考


现在第二个链接不好。
杰里米·哈里斯

@cillosis,感谢您的注意。它现在更新:)
Yusubov

3

您可能需要查看NHibernate Envers 项目文档以获取想法。

基本上,您有一个修订表,可以在其中添加额外的数据,例如时间戳或用户。然后,您跟踪的每个表都会获得一个附加的审计表,该审计表具有所有重复的列,修订表的fk和修订类型(添加,修改,删除)。AFAIK,您不希望审计表在实际表上有实际的FK,因为那样会阻止删除。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.