4

我正在尝试创建一些功能,以跟踪给定用户表单中的数据如何随时间变化的审计跟踪,并在该页面的底部进行了过时的审计。例如:

2009 年 2 月 4 日 21:49 名称从“汤姆”更改为“克里斯”。

我这样做是通过在会话中以当前格式存储数据,然后在保存时检查存储的数据是否有任何差异。如果有,我将数据在最近一次编辑之前的状态存储在一个名为历史的表中,并将新值存储在当前用户表中。

这是最好的方法吗?

4

6 回答 6

12

我不确定是否有一种“最佳方法”,有很多变量需要考虑,包括您的开发路径有多远。

通过基于代码和 db-trigger 审计解决方案,我在下面列出了一些评论;我希望你能看到你现在所处的位置(在发展方面)可能会影响这些问题:

  • 如果您需要映射更改数据的用户(您通常会这样做),那么 db 触发器将需要以某种方式获取此信息。并非不可能,但需要更多的工作和几种方法来解决这个问题(db 用户执行查询、每个表中的公共用户列等)
  • 如果您使用 db 触发器并且依赖从查询返回的受影响的行数,那么您的审计触发器需要关闭此功能,或者修改您现有的代码以解决它们。
  • 恕我直言,数据库触发器提供更高的安全性,并提供更轻松的审计自动化途径,但它们并非万无一失,因为任何具有适当访问权限的人都可以禁用触发器、修改数据然后再次启用它们。换句话说,确保您的数据库安全访问权限是严格的。
  • 拥有一个历史记录表并不是一个坏方法,尽管如果您要审计多个表的历史记录,您将有更多工作要做(以及要存储的数据),尤其是在重建审计跟踪时。如果有许多表试图写入一个审计表,您还必须考虑锁定问题。
  • 为每个表创建一个审计历史表是另一种选择。您只需要审计表中的每一列都可以为空,并存储操作(插入/更新/删除)的日期和时间以及与操作关联的用户。
  • 如果你选择单表选项,除非你有很多时间花在这上面,不要太想只审核更新或删除,尽管避免插入可能很诱人(因为大多数应用程序都这样做比更新或删除更频繁),重建审计历史需要相当多的工作。
  • 如果您的服务器或数据跨越多个时区,则考虑使用适当的日期时间类型来存储和重建时间线,即以 UTC 存储审计事件日期以及包括时区偏移量。
  • 这些审计表可能会变得很大,因此如果它们开始影响性能,请制定策略。选项包括将表分区到不同的磁盘、归档等。基本上现在就考虑这一点,而不是当它成为问题时 :)
于 2009-04-02T21:24:39.247 回答
6

一个建议;这在数据库触发器中相对容易做到。在这种情况下,您永远不必担心运行更新的代码是否记得添加历史记录。

于 2009-04-02T21:02:09.007 回答
3

我一直喜欢使用一个表,而不是将其分解为“活动”表和“历史”表。我在这些表上放了 4 列,所有时间戳:创建、删除、开始、结束。“创建”和“删除”是不言自明的。“开始”和“结束”时间戳用于记录实际上是“活动”记录的时间。当前活动的记录将具有之前的“开始”时间now()NULL“结束”时间。通过分离“创建”和“开始”时间,您可以安排将来发生的更改。

与两表设计相反,这种设计允许您轻松编写将自动对正确数据进行操作的查询。假设您的表随着时间的推移存储税率......您不希望在计算中使用税率的所有查询都具有额外的复杂性,即在处理旧发票时决定在历史表中查找内容,例如例如...您可以在一个查询中查找发票创建时的有效税率,无论它是否是当前税率。

这个想法最初不是我的(尽管在阅读之前我确实自己重新发明了这个粗略的想法)......你可以在这本在线书籍中找到关于它的详细讨论。

于 2009-04-02T21:24:22.197 回答
0

会话参与让我有点警惕(当两个用户同时处理相同的数据时,你确定你处理得当吗?),但总的来说,是的,保留历史表是正确的。

于 2009-04-02T21:01:24.513 回答
0

我还会考虑插入或更新时的数据库触发器,以将更改详细信息(谁、何时、什么、之前的值、之后的值)记录到单独的审计表中。这样您就知道,即使直接使用数据库在您的应用程序之外更改数据,它仍然会被拾取。

您可能还想做一些事情来检测数据是否在您的应用程序之外更改,例如计算记录的哈希或 crc 并将其存储在某处的字段中,然后在读取数据时检查它。

于 2009-04-02T21:19:01.743 回答
0

我认为您的建议将涉及编写大量代码/元数据以启用对象/记录的比较,以便您获得业务级别的审计。

或者,数据库触发器可能无法让您对所发生的事情有足够的了解。如果您很少使用审计以致重新创建业务意义的努力是可以接受的,这可能是可以接受的。

这似乎也是 AOP(方面)的一个很好的应用程序,您可以在对象模型上使用反射来转储有意义的东西,而无需大量元数据。

于 2009-04-02T22:57:59.383 回答