27

人们成功地使用了哪些策略来维护相当复杂的数据库中数据的更改历史记录。我经常使用和开发的应用程序之一可以真正受益于更全面的跟踪记录随时间变化的方式。例如,现在记录可以有许多时间戳和修改的用户字段,但我们目前没有记录多个更改的方案,例如,如果操作回滚。在一个完美的世界中,可以在每次保存后重建记录,等等。

关于数据库的一些信息:

  • 需要有能力每周增加数千条记录
  • 50-60 桌
  • 主修订表每个可能有几百万条记录
  • 设置合理数量的外键和索引
  • 使用 PostgreSQL 8.x
4

6 回答 6

24

您可以使用的一种策略是 MVCC,多值并发控制。在这个方案中,您永远不会对任何表进行更新,您只需进行插入,维护每条记录的版本号。这样做的好处是可以从任何时间点提供准确的快照,并且还完全避开了困扰许多数据库的更新锁问题。

但它会产生一个巨大的数据库,并且选择所有都需要一个额外的子句来选择记录的当前版本。

于 2008-08-23T00:14:00.483 回答
12

如果您使用的是 Hibernate,请查看JBoss Envers。从项目主页:

Envers 项目旨在实现持久 JPA 类的简单版本控制。您所要做的就是使用@Versioned 注释您想要版本化的持久类或其某些属性。对于每个版本化的实体,将创建一个表,其中将保存对该实体所做的更改的历史记录。然后,您可以轻松检索和查询历史数据。

这有点类似于Eric 的方法,但可能要少得多。不过,不知道您使用什么语言/技术来访问数据库。

于 2008-08-23T01:28:23.177 回答
11

过去,我使用触发器来构建数据库更新/插入/删除日志记录。

每次对特定表执行上述操作之一时,您都可以将一条记录插入到日志表中,该表跟踪该操作、数据库用户执行的操作、时间戳、执行操作的表和先前的值。

可能有更好的答案,因为我认为这需要您在执行实际删除或更新之前缓存该值。但是您可以使用它来进行回滚。

于 2008-08-23T00:12:10.443 回答
4

使用触发器的唯一问题是它增加了任何插入/更新/删除的性能开销。为了获得更高的可伸缩性和性能,您希望将数据库事务保持在最低限度。通过触发器进行审计会增加执行事务所需的时间,并且根据数量可能会导致性能问题。

另一种方法是探索数据库是否提供任何方式来挖掘“重做”日志,就像在 Oracle 中的情况一样。重做日志是数据库用来重新创建数据以防万一发生故障并必须恢复的内容。

于 2008-09-15T18:09:35.137 回答
4

与触发器(或什至)类似,您可以让每个事务异步触发一个日志事件,并让另一个进程(或只是线程)实际处理日志。根据您的应用程序,有很多方法可以实现这一点。我建议让应用程序触发该事件,这样它就不会对您的第一个事务造成不必要的负载(这有时会导致级联审计日志锁定)。

此外,您可以通过将审计数据库保存在单独的位置来提高主数据库的性能。

于 2008-09-15T18:23:09.097 回答
2

我使用的是 SQL Server,而不是 PostgreSQL,所以我不确定这是否适合您,但 Pop Rivett 有一篇关于创建审计跟踪的精彩文章: Pop rivett 的 SQL Server FAQ No.5:Pop on the Audit踪迹

构建一个审计表,然后为要审计的每个表创建一个触发器。

提示:使用Codesmith构建您的触发器。

于 2008-09-16T12:58:43.237 回答