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

Dan*_*ane 25 database postgresql database-design crud audit-trail

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

关于DB的一些信息:

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

Eri*_*ard 22

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

但它创建了一个庞大的数据库,并选择所有需要额外的子句来选择当前版本的记录.

  • 你怎么知道哪一个是当前的版本?通过desc子句获得前1个订单?@Eric Z Beard (2认同)

Mar*_*nke 11

如果您正在使用Hibernate,请查看JBoss Envers.从项目主页:

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

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


mk.*_*mk. 10

在过去,我使用触发器来构建db update/insert/delete日志记录.

每次在特定表上执行上述操作之一时,您都可以将记录插入到记录表中,该记录表记录操作,数据库用户执行操作,时间戳,预先执行的表以及之前的值.

可能有一个更好的答案,因为这需要你在实际删除或更新之前缓存值我认为.但你可以用它来做回滚.

  • 数据库级解决方案的问题在于操作没有业务上下文,即您不知道哪个用户执行了操作或他们正在执行的操作.大多数Web应用程序使用单个用户名连接到其数据库,因此登录的Web用户名不是触发器看到的用户名. (10认同)
  • 安德鲁,任何非数据库级解决方案都没有审计跟踪,因为它不会捕获未在GUI中添加的记录.我们捕获特定用户,因为我们的所有表都有last_updated列,插入,更新等都发送进行更新的人的person_id而不是web用户名. (8认同)