2010-03-27 130 views
2

我是J2EE开发人员&我们使用的是PostgreSQL数据库的hibernate映射。如何保留数据库中修改的历史细节(审计跟踪)?

我们需要跟踪的数据库中发生的任何变化,在别人的话任何领域的所有以前&电流值应保存。每个字段可以是任何类型(BYTEA,INT,焦炭......)

用一个简单的表很容易,但我们的目标事物的图形都比较困难。

所以我们用UML的观点来讲,一个对象图要存储在数据库中,每个用户改变&。

任何想法或模式如何做到这一点?

回答

1

执行此操作的常用方法是存储对象版本。

如果添加一个“版本”和“删除”字段,你要存储的审计线索的每个表,然后而不是做正常的更新和删除,请遵循以下规则:

  • 插入 - 将版本号设置为0并正常插入。
  • 更新 - 增加版本号并改为插入。
  • 删除 - 增加版本号,将删除的字段设置为true,然后执行插入操作。
  • 检索 - 获取最高版本号的记录并返回该记录。

如果遵循此模式,每次更新时都会创建新记录而不是覆盖旧数据,因此您将始终能够追溯并查看所有旧对象。

这将工作完全相同的对象的关系图中相同,只是添加新的字段以每个表中的对象图内,并且处理每个插入/更新/如上所述删除每个表。

如果您需要知道哪些用户进行的修改,你只需要添加一个“ModifiedBy”领域也是如此。

(你可以做到这一点处理您的DA层的代码,或者如果你喜欢,你可以使用数据库触发器吸引您的更新/删除/检索调用和重新处理他们遵守规则。)

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

+1

请记住,这种方法实际上破坏了关系完整性。在常规表中,我们将有一个主键PK_COL。现在我们有一个(PK_COL,VERSION_NO)的UID。这使得强制执行PK_COL在现实世界中唯一标识某些内容的规则变得更加困难。它还使外键关系复杂化:如果父记录发生变化(插入新版本),我们是否插入所有子版本的新版本*即使它们中没有一个已经更改*?最后,这种方法通过要求额外的过滤器来获取当前视图来惩罚最常见的访问路径。 – APC 2010-03-28 03:47:10

+0

我之前的评论涉及到这是审计的一般方法。可能存储“对象图”的数据库几乎不需要关系完整性,在这种情况下,该技术可以满足Mada的要求。 – APC 2010-03-28 03:52:34

1

当前的RDBMS实现并不擅长处理时态数据。这就是为什么通过触发器维护单独的日记表的一个原因是通常的方法。 (另一个原因是审计跟踪对于常规数据经常具有不同的用例,并且将它们放在单独的表中可以更容易地管理对它们的访问)。 Oracle在其Total Recall product中做了一个非常漂亮的工作来隐藏管道,但作为Oracle,它为此收取$$$。

斯科特·贝利发表了对PostgreSQL中时间数据的介绍。唉,它现在不会帮你,但它似乎有些功能计划为8.5和8。6将启用时间相关数据的透明存储。 Find out more