如何实现历史版本控制?

我们正处于构建SQL 2008 R2上的大型C#MVC2应用程序(我们还将Sharp架构和Nhibernate作为生态系统的一部分)的早期阶段,其中一个要求是所有数据库行版本都可以在给定的时间内访问历史。

我们玩弄了类似于以下布局的想法:

id(PK)
的recordId
VERSIONID

并且使用相同的recordId和增加的versionId创建新记录中的每个编辑记录结果。 然后记录显示将按照SELECT … WHERE recordId = X AND versionId = MAX(versionId)的内容完成。

每个事务的快照都不起作用(太多了?并且无法从应用程序中轻松访问)。

但我们很好奇其他实施方案是否成功,或者我们的提案存在潜在问题。

你似乎暗指一个时间表。 三种方法:

有效状态表 :附加两个’timestamp’列(例如,类型为DATETIME ),一个指定行何时生效,另一个指定行何时停止有效,中间时间是行的有效期

事务时间状态表 :将每行与该监视表中存在的行的时间段相关联,从而允许重建任何先前时间点的被监视表的状态。

双时态表 :捕获有效时间和事务时间,同时记录企业的历史记录,同时还捕获该历史记录的更改顺序。

资料来源: 在SQL中开发面向时间的数据库应用程序(Richard T Snodgrass) 。

我们有一个由我们的DBA开发的系统,它作为更新/删除的触发器。 有一个辅助表几乎镜像被审计的表(除了一些其他细节,如事务时间,用于执行更新的登录,服务器等)。 每当有人进行更改时,都会通过触发器将其记录在表的审核版本中。 在架构发生变化的任何时候都必须让审计触发器保持最新状态,这很烦人,但是请大家好奇心。

关于这一点的好处是应用程序根本不需要关心这个审计……所以它使应用程序代码的概念数量保持较低(呃)。

这是在生产中并且在每天数万个交易数量的表格上工作。 您的里程数当然可能因服务器的大小和数据的性质等因素而异,但它适用于我们:-)

而不是versionId,它要求你自我加入以获得最大版本,我将介绍validFrom – validTo对。 这要求您在插入新版本的行时更新(结束)当前记录的validTo,但允许where @now >= validFrom and @now < validTo或任何历史时间的数据中轻松选择当前数据。

您可以将这些历史记录放在单独的表中。 如果您只想拥有一个包含所有行版本的表,这些表更易于维护和使用,您可能需要查看SQL Server分区(分区表),它允许您将最近的历史记录与旧历史记录分开并优化搜索在上面。

我有一个类似的问题,我需要审核一组表的每个更改。

我们遇到的最大问题是尝试仅使用NHibernatefunction来管理大量插入和更新时的性能(因为UI需要它们)。 因此,我们的解决方案是使用TRIGGERS审核表格上的所有信息,并且比较我们当时可能与NH提出的任何解决方案的响应时间都令人难以置信。

如果有人问我该怎么做,我会说触发器是审核数据的方法。

如果您有SQL 2008 Enterprise,并且根据您的意图,更改数据捕获(CDC)可能值得一看。

这取决于您是保留以前的版本是出于审计目的还是出于其他原因。

我的企业还使用基于触发器的方法进行审计和历史记录。 除了企业仓库中的核心表之外,每个重要的表都在一个单独的数据库中有一个审计表。 每个事务的此审计表都有1行。 我们的一些表在第三个数据库中也有一个历史版本。 审计数据库纯粹用于事后故障排除和不可否认 – 但查询数据分析很困难且不具备性能。 我们的历史数据库经过优化,可以非常有效地回答时间点查询。 所有这些都是我编写的.net工具100%编写的,因此当我们更改模式或将新表添加到历史记录时,我们只需重新编写受影响的触发器脚本。