人们在相当复杂的数据库中维护数据更改历史记录的成功策略是什么?我经常使用和开发的应用程序之一可以真正受益于更全面的跟踪记录随时间变化的方式。例如,现在记录可以具有多个时间戳和修改的用户字段,但是我们目前没有用于记录多个更改的方案,例如,如果回滚操作。在完美的世界中,可以在每次保存之后重建记录等等。
关于数据库的一些信息:
答案 0 :(得分:22)
您可以使用的一种策略是MVCC,多值并发控制。在此方案中,您永远不会对任何表进行更新,只需执行插入操作,维护每个记录的版本号。这样做的好处是可以从任何时间点提供精确的快照,它还可以完全避开困扰许多数据库的更新锁定问题。
但它创建了一个庞大的数据库,并选择所有需要额外的子句来选择当前版本的记录。
答案 1 :(得分:11)
如果您使用的是Hibernate,请查看JBoss Envers。从项目主页:
Envers项目旨在实现持久JPA类的简单版本控制。您需要做的就是使用@Versioned注释您想要版本的持久类或其某些属性。对于每个版本化实体,将创建一个表,该表将保存对实体所做更改的历史记录。然后,您可以轻松地检索和查询历史数据。
这有点类似Eric's approach,但可能要少得多。但是,不知道您使用什么语言/技术来访问数据库。
答案 2 :(得分:10)
过去我使用触发器来构建db update / insert / delete日志记录。
每次在特定表上执行上述操作之一时,您都可以将记录插入到记录表中,该记录表跟踪操作,db用户执行的操作,时间戳,执行的表以及之前的值。
可能有一个更好的答案,因为这需要你在实际删除或更新执行之前缓存值我认为。但你可以用它来做回滚。
答案 3 :(得分:4)
使用触发器的唯一问题是它增加了任何插入/更新/删除的性能开销。为了获得更高的可伸缩性和性能,您希望将数据库事务保持在最低限度。通过触发器进行审计会增加执行事务所需的时间,并且根据卷可能会导致性能问题。
另一种方法是探索数据库是否提供了挖掘“重做”日志的任何方式,就像Oracle中的情况一样。重做日志是数据库用于重新创建数据的情况,以防数据失败并且必须恢复。
答案 4 :(得分:4)
与触发器(甚至是触发器)类似,您可以让每个事务异步触发日志记录事件,并让另一个进程(或只是线程)实际处理日志记录。根据您的应用,有很多方法可以实现这一点。我建议让应用程序触发事件,以便它不会对您的第一个事务造成不必要的负载(这有时会导致级联审计日志的锁定)。
此外,您可以通过将审计数据库保存在单独的位置来提高主数据库的性能。
答案 5 :(得分:2)
我使用的是SQL Server,而不是PostgreSQL,所以我不确定这是否适合你,但Pop Rivett在这里有一篇关于创建审计线索的精彩文章: Pop rivett's SQL Server FAQ No.5: Pop on the Audit Trail
构建审计表,然后为要审计的每个表创建触发器。
提示:使用Codesmith构建触发器。