关于捕获审计跟踪的数据库设计的想法[关闭]

Posted

技术标签:

【中文标题】关于捕获审计跟踪的数据库设计的想法[关闭]【英文标题】:Ideas on database design for capturing audit trails [closed] 【发布时间】:2010-11-06 06:59:58 【问题描述】:

如何维护数据库中的数据日志?

我必须维护对每一行所做的每次更改的日志。这意味着我不能让DELETEUPDATE 被执行。

我怎样才能保留这样的日志?

【问题讨论】:

【参考方案1】:

使用“仅插入数据库”

基本理念是您永远不会更新或删除数据。

每个表都有 2 个日期时间列 fromto

它们以 null 值开始(从时间开始到时间结束)

当您需要“更改”行时添加新行,同时将上一行中的 to 更新为 Now 并将 from 中的您要添加到 Now 的行。

您通过其中包含 where to = null 的视图从表中读取数据。

此方法还可以让您随时了解数据库的状态。

编辑

只是为了回应评论澄清:序列将由表的主键给出,这将是一个自动递增的数字。

【讨论】:

这不就是对空间的巨大浪费吗? 如果您需要数据,如果您需要审计跟踪,您会这样做,这不会浪费。 我不会为任何 ID/搜索数据或任何序列数据使用日期时间列。系统日期可能因任何原因而更改,或者在单个日期/时间值的同一时间分辨率内发生的多个操作都是可能的。如果您需要及时捕获序列,请使用时间戳(保证唯一)或使用长整数或使用 guid,因为您的 from 也构建了一个链(但您会浪费时间作为信息项 - 另请阅读下面的答案...) Kolten,如果您在一个由于法规遵从性而必须跟踪所有内容的行业工作,您会意识到这是必要的邪恶。此外,发布者只能审核他/她最感兴趣的表子集,因此空间浪费与他/她想要的日志记录级别有关... 不要同时存储tofrom,它会引入更新异常 - 这是不正确的设计。您只需要存储一个值。【参考方案2】:

使用“仅插入”数据库,如 Shiraz Bhaji 所述,但您可以使用更简单的技术。对于您需要为其维护审计数据的每个表,只需为更新时间添加一列,默认为现在。当您对记录进行更改而不是更新时,只需插入所有数据即可; UpdatedTime 列将获取当前时间。

请注意,这种方法意味着您必须打破或重新考虑您的 UNIQUE 约束;你可以保留一个主键,但唯一性是你的主键和你的更新时间的组合。

此技术的优点是为您提供表上每条记录的已知历史数据范围(如果每条记录是 WHERE TimeOfInterest > UpdatedTime ORDER BY UpdatedTime DESC 的记录中的前 1 条记录,则每条记录在给定时间有效)低开销(表中只有一列)。从不使用此方法的表进行转换也很容易,只需使用简单的 ALTER TABLE 添加单个列(您可以一致地命名)。然后您只需要更改您的 UNIQUE 约束以使用其当前约束和 UpdatedTime 列的组合,并且需要更改一些查询。

还请注意,如果您创建的表视图仅返回每条记录的最新条目,则实际上可以避免转换所有查询;您最终会得到一个透明地维护历史数据的表,以及一个看起来像没有更改日志的常规表的视图。

【讨论】:

我真的很喜欢这个想法,并且是我正在尝试的东西,但是您如何处理参照完整性? 如何处理参照完整性。?假设我想要只插入用户表,并且我还有 user_account(with user_id column) 表。我应该在 user_id 列中放入用户表的哪个 id? 这也是 Tomm Carr 所青睐的方法,他编写了一个很好的摘要 PDF,其中涵盖了许多细节,请参阅 this answer。与 Shiraz Bhaji 的答案相比,最明显的改进是该设计避免了由于 fromto 字段之间的不一致而导致的插入异常。【参考方案3】:

[较晚的帖子,但它添加了此处未提及的两种技术]

读取事务日志 – 如果您的数据库处于完全恢复模式,那么事务日志会存储许多有用的信息,可用于查看每一行的历史记录。 缺点是默认情况下不支持此功能。您可以尝试使用未记录的函数 DBCC LOG 或 fn_dblog 或第三方工具,例如 ApexSQL Log

使用变更数据捕获 - Change data capture 本质上与上面显示的相同,但它更精简且更易于使用。不幸的是,这仅在企业版中可用。

这两者都可以解决允许更新和删除的问题,因为您无法真正更改事务日志中写入的内容。

【讨论】:

【参考方案4】:

一种完全不同的方法是只有一个审核日志。然后,您可以使用它来构建数据的最新版本。您定期创建“检查点”或使用缓存来加快速度。

有一个关于有人使用这种技术的演示文稿:http://www.infoq.com/presentations/greg-young-unshackle-qcon08。这里最大的优势是,由于您只有审核日志,因此您可以确信您的审核跟踪是正确的。

我从来没有尝试过这个,它看起来很复杂......但是需要考虑一下。

【讨论】:

【参考方案5】:

看看我对另一个数据库日志记录问题的回答是否包含您需要的信息。在这里找到它...

History tables pros, cons and gotchas - using triggers, sproc or at application level

【讨论】:

以上是关于关于捕获审计跟踪的数据库设计的想法[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

审计日志的数据库设计[关闭]

问题设计审计表以跟踪更改

来自审计跟踪数据库的 Mysql 用户活动报告

DB Audit Trail 的最佳实施是啥? [关闭]

如何在 asp.net mvc 中创建审计日志/审计跟踪

用于保存对审计跟踪表的更改的 Sql 触发器