如何在数据库中维护数据日志?
我必须记录每行所做的每项更改。这意味着我无法允许执行DELETE
和UPDATE
。
我如何保留这样的日志?
答案 0 :(得分:24)
使用“仅插入数据库”
基本思想是您永远不会更新或删除数据。
每个表格都有2个日期时间列从和到。
它们以每个值(从时间开始到结束时)的值null开始
当您需要“更改”该行时,您需要添加一个新行,同时将上一行中的更新为更新为现在,将更新为你要添加到Now的行。
您通过视图中的数据从表中读取数据,其中包含where = null。
此方法还可以为您提供任何时间点数据库状态的图片。
修改强>
只是为了澄清以回应评论:序列将由表格的主键给出,这将是一个自动增量数字。
答案 1 :(得分:17)
[后期帖子,但它添加了两种未在此处提及的技术]
读取事务日志 - 如果数据库处于完全恢复模式,则事务日志会存储许多可用于查看每行历史记录的有用信息。 缺点是默认情况下不支持此功能。您可以尝试使用未记录的函数DBCC LOG或fn_dblog或第三方工具,例如ApexSQL Log
使用更改数据捕获 - Change data capture基本上执行与上面所示相同的操作,但它更简化,更易于使用。不幸的是,这仅适用于企业版。
这两个都可以解决允许更新和删除的问题,因为您无法真正更改事务日志中写入的内容。
答案 2 :(得分:14)
使用“仅插入”数据库,如Shiraz Bhaji所述,但您可以使用更简单的技术。对于您需要维护审计数据的每个表,只需要有一个更新时间的附加列,默认为现在。当您对记录进行更改而不是更新时,只需插入所有数据; UpdatedTime列将获取当前时间。
请注意,此方法意味着您必须打破或重新考虑您的UNIQUE约束;您可以保留主键,但唯一性将成为主键和UpdatedTime的组合。
这种技术的优势在于为您提供表中每条记录的已知历史数据范围(如果它是记录的TOP 1,则每条记录在给定时间内有效WHERE TimeOfInterest> UpdatedTime ORDER BY UpdatedTime DESC)开销很低(桌子上只有一列)。它也非常适合从不使用此方法的表进行转换,使用简单的ALTER TABLE添加单个列(您可以一致地命名)。然后,您只需要更改UNIQUE约束以使用其当前约束和UpdatedTime列的组合,并且需要更改某些查询。
另请注意,如果您创建一个只返回每条记录的最新条目的表视图,您实际上可以避免转换所有查询;最终得到一个透明地维护历史数据的表,以及一个看起来像没有更改记录的常规表的视图。
答案 3 :(得分:5)
完全不同的方法是只有审计日志。然后,您可以使用它来构建最新版本的数据。您可以定期创建“检查点”或使用缓存来加快速度。
有关使用此技术的人的演示文稿:http://www.infoq.com/presentations/greg-young-unshackle-qcon08。这里的一大优势是,由于您只有审计日志,因此您将非常确信您的审计跟踪是正确的。
我从未尝试过这个,看起来很复杂......但需要考虑一下。
答案 4 :(得分:1)
查看我对另一个数据库记录问题的回答是否包含您需要的信息。在这里找到它......
History tables pros, cons and gotchas - using triggers, sproc or at application level