为数据库应用程序留下审计跟踪/更改历史记录的有效策略?

时间:2020-03-05 18:42:19  来源:igfitidea点击:

人们成功地维护了相当复杂的数据库中数据的更改历史的一些策略是什么?我经常使用和开发的应用程序之一确实可以从跟踪记录如何随时间变化的更全面的方法中真正受益。例如,现在的记录可以具有多个时间戳记和已修改的用户字段,但是例如,如果某个操作被回滚,则我们目前尚无记录多个更改的方案。在理想情况下,可以重新保存每次保存后的记录,等等。

数据库上的一些信息:

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

解决方案

回答

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

我们可以在每次对特定表执行上述操作之一时,在记录表中插入一条记录,以跟踪该操作,db用户执行的操作,时间戳,执行该操作的表以及先前的值。

我想可能会有更好的答案,因为这将要求我们在执行实际的删除或者更新之前缓存值。但是我们可以使用它进行回滚。

回答

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

但是它构成了一个庞大的数据库,并且全部选择都需要一个额外的子句来选择记录的当前版本。

回答

如果我们使用的是Hibernate,请看一下JBoss Envers。从项目主页:

The Envers project aims to enable easy versioning of persistent JPA classes. All that you have to do is annotate your persistent class or some of its properties, that you want to version, with @Versioned. For each versioned entity, a table will be created, which will hold the history of changes made to the entity. You can then retrieve and query historical data without much effort.

这有点类似于埃里克(Eric)的方法,但可能要少得多的精力。但是,不知道我们使用哪种语言/技术来访问数据库。

回答

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

另一种方法是探究数据库是否提供了某种方式来挖掘"重做"日志,就像在Oracle中一样。重做日志是数据库在失败并必须恢复的情况下用来重新创建数据的工具。

回答

与触发器(甚至与触发器)类似,我们可以让每个事务异步触发日志事件,并让另一个进程(或者仅线程)实际处理日志。取决于应用程序,可以有很多方法来实现。我建议让应用程序触发该事件,以便它不会对第一个事务造成不必要的负载(有时会导致级联审核日志的锁定)。

此外,通过将审核数据库放在单独的位置,我们也许可以提高主数据库的性能。

回答

我使用的是SQL Server,而不是PostgreSQL,所以我不确定这是否对我们有用,但是Pop Rivett撰写了一篇很棒的文章,介绍如何在此处创建审核跟踪:
Pop rivett的SQL Server常见问题解答5:在审计追踪中流行

生成审核表,然后为要审核的每个表创建一个触发器。

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