一尘不染

保留数据库中数据更改的历史记录

sql

数据库中某行的每一次数据更改都应将前一行数据保存在某种历史记录中,以便用户可以回滚到前一行数据状态。这种方法有什么好的做法吗?尝试过使用DataContract并对数据对象进行序列化和反序列化,但是对于复杂的对象来说,它几乎不会造成混乱。

所以要更清楚一点:

  1. 我正在使用NHibernate进行数据访问,并希望不影响数据库依赖性(用于使用SQL Server 2005进行测试)

  2. 我的意图是提供数据历史记录,以便用户每次可以回滚到某些以前的版本。

用法示例如下:

  • 我有一篇新闻文章
  • 有人对该文章进行了一些更改
  • 主编看到这个消息有错别字
  • 它决定回滚到以前的有效版本(直到更正了最新版本)

希望我能给您有效的信息。


阅读 653

收藏
2021-03-17

共1个答案

一尘不染

当主表更改时存储更改的表称为审核表。您可以通过多种方式执行此操作:

  • 在使用触发器的数据库中: 我建议使用此方法,因为这样就无法在没有记录的情况下更改数据。执行此操作时,必须考虑3种类型的更改:添加,删除,更新。因此,您需要可同时在这三个平台上使用的触发器功能。

还请记住,一个事务可以同时修改多个记录,因此您应该使用完整的修改记录集,而不仅仅是最后一个记录(因为大多数人迟来才意识到它们确实做了)。

在触发器执行完成之前,控制权不会返回到调用程序。因此,您应该保持代码尽可能轻巧和快速。

  • 在中间层使用代码: 此方法将使您可以将更改保存到其他数据库,并可能减轻数据库的负担。但是,运行UPDATE语句的SQL程序员将完全绕过您的中间层,并且您将没有审核记录。

审核表的结构

您将拥有以下专栏:
Autonumber PK, TimeStamp, ActionType + All columns from your original table
过去,我已经通过以下方式做到这一点:

表结构:
Autonumber PK, TimeStamp, ActionType, TableName, OriginalTableStructureColumns

这种结构意味着您为每个保存的数据表创建一个审核表。数据保存和重建相当容易。我会推荐这种方法。 名称值对:
Autonumber PK, TimeStamp, ActionType, TableName, PKColumns, ColumnName, OldValue, NewValue

这种结构将允许您保存任何表,但是您将必须为触发器中的每一列创建名称/值对。这是非常通用的,但是很昂贵。您还需要编写一些视图以通过取消透视表数据来重新创建实际的行。这变得乏味并且通常不是所遵循的方法。

2021-03-17