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

02/04/09 21:49 名称从“Tom”更改为“Chris”。

我这样做的方法是将数据以其当前格式存储在会话中,然后在保存时检查所存储的数据是否存在任何差异。如果有,我会将最新编辑之前的数据存储在名为历史记录的表中,并将新值存储在当前用户表中。

这是最好的方法吗?

有帮助吗?

解决方案

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

其他提示

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

在经历了基于代码和数据库触发的审计解决方案之后,我在下面列出了一些评论;我希望您能看到您现在所处的位置(在发展方面)可能会影响这些问题:

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

我一直使用一个表,而不是将其分成“活动”表和“历史”表的粉丝。我把4列在这些表中,所有时间戳:创建,删除,开始,结束。 “创造”和“删除”是相当不言自明。在“开始”和“结束”时间戳是当记录实际上是“主动”的纪录。当前活动的记录将有一个之前“启动”时间now()NULL“结束”时间。通过分离出来的“创造”和“开始”时间,可以安排更改发生在未来。

此设计,而不是在两个表的设计,让您轻松写下在正确的数据自动地操作的查询。假设你的表是存放一段时间的税率......你不想有使用税率在他们的计算有决定处理旧发票时看东西了一个历史记录表的额外的复杂性您所有的疑问,对于例如......你可以查找税率生效的发票是在一个查询创建的时候,不管它是否是当前税率还是不行。

这想法是不是本来矿(阅读这件事,虽然我没有重新发明我自己之前的粗略的想法)...你可以找到它在此详细讨论的在线图书

在会议的参与让我有点担心(你确定你正在处理得当,当两个用户在相同的数据在同一时间工作?),但在一般情况下,是的,保持一个历史表是正确的的事情。

我也想上插入或更新的记录更改信息数据库触发器(谁,什么时候,什么,前值,值之后)到一个单独的审计表。这样,你知道,即使数据发生变化outide直接使用数据库您的应用程序,它仍然会回升。

您也可能想要做的东西,如果该数据被更改outide您的应用程序,如计算记录的散列或CRC并将其存储在一个领域的地方,然后检查其读取数据时检测到。

我觉得你的建议将涉及编写大量的代码/元数据,使对象/记录比较,所以你得到一个企业级的审计。

另外,数据库触发器可能不会给你什么事足够高的水平视图。如果你使用的审计如此罕见,以至重新创建业务含义的努力是好了,这是可以接受的。

这也似乎是AOP(方面)有很好的应用,在那里你可以使用反射的对象模型倾倒点有意义的事情,而不需要大量的元数据。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top