这是创建审计跟踪的最佳方法吗?
我正在尝试创建一些功能,以保留给定用户表单中的数据如何随时间变化的审计跟踪,并在该页面的底部提供日期审计。 例如:
02/04/09 21:49 名称从“Tom”更改为“Chris”。
我这样做的方法是将数据以其当前格式存储在会话中,然后在保存时检查所存储的数据是否存在任何差异。 如果有,我会将最新编辑之前的数据存储在名为历史记录的表中,并将新值存储在当前用户表中。
这是最好的方法吗?
I'm trying to create some functionality that keeps an audit trail of how data in a given user form has been changed over time, with a dated audit at the foot of that page. For example:
02/04/09 21:49 Name changed from "Tom" to "Chris".
I'm doing this by storing the data in it's present format in the session and then on save checking whether there are any differences in the data being stored. If there are, I'm storing the data how it was before the latest edit in a table called history, and storing the new values in the current user table.
Is this the best approach to be taking?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我不确定是否存在一种“最佳方法”,需要考虑很多变量,包括您的发展道路有多远。
在经历了基于代码和数据库触发的审计解决方案之后,我在下面列出了一些评论; 我希望您能看到您现在所处的位置(就开发而言)可能会影响这些问题:
I'm not sure there is one "best approach", there are so many variables to take into consideration, including how far down the development path you are.
Having been through both code-based and db-trigger auditing solutions, I've listed some comments below; I hope you can see where you are now at (in terms of development) could affect these issues:
一个建议; 这在数据库触发器中相对容易完成。 在这种情况下,您永远不必担心运行更新的代码是否记得添加历史记录。
One suggestion; this would be relatively easy to do in a database trigger. In that case, you would never have to worry about whether the code running the update remembers to add a history record.
我一直喜欢使用一张表,而不是将其分成“活动”表和“历史”表。 我在这些表上放置了 4 列,所有时间戳:创建、删除、开始、结束。 “创建”和“删除”是相当不言自明的。 “开始”和“结束”时间戳是记录实际上是“活动”记录的时间。 当前活动的记录将有一个早于
now()
的“开始”时间和一个NULL
“结束”时间。 通过分离“创建”和“开始”时间,您可以安排将来发生的更改。与双表设计相反,这种设计允许您轻松编写将自动操作正确数据的查询。 假设您的表正在存储一段时间内的税率...您不希望所有在计算中使用税率的查询在处理旧发票时决定在历史表中查找内容的额外复杂性,例如例如...您可以在一个查询中查找创建发票时有效的税率,无论它是否是当前税率。
这个想法最初不是我的(尽管在阅读它之前我确实重新发明了我自己的粗略想法)......您可以在这个 在线图书。
I've always been a fan of using one table instead of breaking it up into an "active" table and a "history" table. I put 4 columns on these tables, all timestamps: created, deleted, start, end. "created" and "deleted" are fairly self-explanatory. The "start" and "end" timestamps are for when the record was actually the "active" record. The currently-active record would have a "start" time prior to
now()
and aNULL
"end" time. By separating out the "created" and "start" times, you can schedule changes to take place in the future.This design, as opposed to the two-table design, allows you to easily write queries that will automatically operate on the right data. Suppose your table is storing the tax rate over time... you don't want to have all your queries that use tax rates in their calculations have the extra complexity of deciding to look stuff up in a history table when processing old invoices, for example... you can just look up the tax rate in effect at the time the invoice was created in one query, regardless of whether it's the current tax rate or not.
This idea is not originally mine (although I did re-invent the rough idea on my own prior to reading about it)... you can find a detailed discussion of it in this online book.
会话的参与让我有点警惕(当两个用户同时处理相同的数据时,你确定你能正确处理它吗?),但总的来说,是的,保留历史表是正确的事情。
The session involvement makes me a little wary (are you sure you're handling it properly when two users are working on the same data at the same time?), but in general, yeah, keeping a history table is the right thing.
我还会考虑插入或更新时的数据库触发器,以将更改详细信息(谁、何时、什么、之前的值、之后的值)记录到单独的审计表中。 这样您就知道,即使直接使用数据库在应用程序外部更改数据,它仍然会被拾取。
您可能还想做一些事情来检测数据是否在应用程序外部发生更改,例如计算记录的哈希值或 crc 并将其存储在某个字段中,然后在读取数据时进行检查。
I would also think about a database trigger on insert or update to record change details (who, when, what, value before, value after) to a separate audit table. That way you know that even if the data is changed outide of your app using the database directly, it will still be picked up.
You might also want to do something to detect if the data is changed outide of your app, such as calculate a hash or crc of the record and store it in a field somewhere, then check it when reading the data.
我认为您的建议将涉及编写大量代码/元数据来比较对象/记录,以便您获得业务级审计。
或者,数据库触发器可能无法为您提供所发生事件的足够高级视图。 如果您很少使用审计,以至于重新创建业务含义的努力是可以接受的,那么这可能是可以接受的。
这似乎也是 AOP(方面)的一个很好的应用程序,您可以在对象模型上使用反射来转储一些有意义的内容,而不需要大量元数据。
I think your proposal would involve writing a lot of code/metadata to enable comparison of objects/records so you get a business-level audit.
Alternatively, a database trigger may not give you a high-enough level view of what happened. This may be acceptable if you use the audit so infrequently that the effort of recreating the business meaning is ok.
This also seems like a good application for AOP (Aspects), where you could use reflection on the object model to dump something meaningful without requiring a lot of metadata.