Database 如何在数据库中保留修改的历史详细信息(审计跟踪)?

Database 如何在数据库中保留修改的历史详细信息(审计跟踪)?,database,database-design,postgresql,audit,Database,Database Design,Postgresql,Audit,我是一名J2EE开发人员&我们正在使用hibernate映射和PostgreSQL数据库 我们必须跟踪数据库中发生的任何更改,换句话说,任何字段的所有以前和当前值都应该保存。每个字段可以是任何类型(bytea、int、char…) 用一个简单的表格很容易,但我们用一个对象的图形来做事情就更难了 因此,从UML的角度来说,我们有一个对象图,存储在数据库中,每一次更改&用户 有什么想法或模式可以做到这一点吗?一种常见的方法是存储对象的版本 如果在要存储审核跟踪的每个表中添加“版本”和“已删除”字段,

我是一名J2EE开发人员&我们正在使用hibernate映射和PostgreSQL数据库

我们必须跟踪数据库中发生的任何更改,换句话说,任何字段的所有以前和当前值都应该保存。每个字段可以是任何类型(bytea、int、char…)

用一个简单的表格很容易,但我们用一个对象的图形来做事情就更难了

因此,从UML的角度来说,我们有一个对象图,存储在数据库中,每一次更改&用户


有什么想法或模式可以做到这一点吗?

一种常见的方法是存储对象的版本

如果在要存储审核跟踪的每个表中添加“版本”和“已删除”字段,则不执行常规更新和删除,而是遵循以下规则:

  • 插入-将版本号设置为0,然后按正常方式插入
  • 更新-增加版本号,改为插入
  • Delete-增加版本号,将deleted字段设置为true,然后执行插入操作
  • 检索-获取具有最高版本号的记录并返回该记录
如果遵循此模式,则每次更新时都将创建新记录,而不是覆盖旧数据,因此您将始终能够跟踪并查看所有旧对象

这对对象图的作用完全相同,只需将新字段添加到对象图中的每个表中,并按上述方式处理每个表的每个插入/更新/删除

如果您需要知道是哪个用户进行了修改,那么只需添加一个“ModifiedBy”字段

(您可以在DA层代码中执行此处理,或者如果愿意,可以使用数据库触发器捕获更新/删除/检索调用,并按照规则重新处理它们。)


显然,你需要考虑空间需求,因为每一个更新都会产生一个全新的记录。如果您的应用程序需要大量更新,那么将生成大量数据。通常还包括“上次修改的时间”字段,以便脱机处理数据库并删除比所需时间早的数据。

当前的RDBMS实现在处理时态数据方面不是很好。这就是为什么通过触发器维护单独的日志表是常用方法的原因之一。(另一个原因是审计跟踪经常与常规数据有不同的用例,将它们放在单独的表中可以更容易地管理对它们的访问)。甲骨文在隐藏管道方面做得相当巧妙,但作为甲骨文,它为此收取$$$的费用


Scott Bailey在PostgreSQL中发表了一篇关于时态数据的演讲。遗憾的是,它现在对您没有帮助,但似乎8.5和8.6计划的一些功能将支持时间相关数据的透明存储

请记住,这种方法实际上破坏了关系完整性。在一个常规表中,我们会有一个主键PK_COL。现在我们有一个UID(PK_COL,VERSION_NO)。这使得强制执行PK_COL在现实世界中唯一标识某些东西的规则变得更加困难。它还使外键关系复杂化:如果父记录更改(插入新版本),我们是否会插入其所有子记录的新版本,即使它们都没有更改?最后,这种方法通过要求额外的过滤器来获取当前视图来惩罚最常见的访问路径。可能存储“对象图”的数据库不需要关系完整性,在这种情况下,这种技术可以满足Mada的要求。