C# 如何实现历史版本控制?

C# 如何实现历史版本控制?,c#,sql,nhibernate,asp.net-mvc-2,s#arp-architecture,C#,Sql,Nhibernate,Asp.net Mvc 2,S#arp Architecture,我们正处于构建大型MVC2应用程序的早期阶段,我们还采用了夏普体系结构和Nhibernate作为SQL 2008 R2生态系统的一部分,其中一个要求是在给定的历史时期内可以访问所有数据库行版本 我们曾尝试过类似以下布局的想法: id PK 记录ID 版本 对记录的每次编辑都会导致创建一个具有相同记录ID和递增版本ID的新记录。然后,记录显示将通过沿SELECT。。。其中recordId=X,versionId=MAXversionId 对每个事务进行快照不会太多吗?并且不容易从应用程序内部访问

我们正处于构建大型MVC2应用程序的早期阶段,我们还采用了夏普体系结构和Nhibernate作为SQL 2008 R2生态系统的一部分,其中一个要求是在给定的历史时期内可以访问所有数据库行版本

我们曾尝试过类似以下布局的想法:

id PK 记录ID 版本

对记录的每次编辑都会导致创建一个具有相同记录ID和递增版本ID的新记录。然后,记录显示将通过沿SELECT。。。其中recordId=X,versionId=MAXversionId

对每个事务进行快照不会太多吗?并且不容易从应用程序内部访问


但我们很好奇,还有哪些其他的实现是成功的,或者我们的方案中存在的潜在问题。

我们有一个由DBA开发的系统,可以作为更新/删除的触发器。除了事务时间、用于更新的登录名、服务器等其他一些详细信息外,还有一个几乎与正在审核的表镜像的辅助表。。任何时候有人进行更改,都会通过触发器记录到表的审核版本中。每当模式发生变化时都必须使审计触发器保持最新,这有点烦人,但这就是生活

这样做的好处是,应用程序根本不需要关注这种审计。。。因此,它降低了应用程序代码的概念计数


这是在生产中,并且在每天事务数为数万的表上工作。当然,您的里程数可能会因服务器的大小和数据的性质等诸多因素而有所不同,但这对我们来说是可行的:-

而不是versionId,后者要求您进行自连接以获得最大版本,我将介绍validFrom-validTo对。这要求您在插入新版本的行时更新结束当前记录的validTo,但允许轻松选择@now>=validFrom和@now
您可以将这些历史记录保存在单独的表中,也可以不保存。如果您只想有一个表,其中包含行的所有版本,这样可以更好地进行维护和使用,那么您可能想看看SQL Server分区表,它允许您将最近的历史记录与旧的历史记录分开,并优化对它的搜索。

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


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

您似乎在暗示一个时态表。三种方法:

有效状态表:附加两个“时间戳”列,例如DATETIME类型,一个指定行何时变为有效,另一个指定行何时停止有效,中间时间为行的有效期

事务时间状态表:将该行在受监控表中的时间段与每一行相关联,从而允许重构受监控表在任何以前时间点的状态

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


来源:。

我遇到了一个类似的问题,我需要审核对一组表的每次更改

我们遇到的最大问题是在试图仅使用NHibernate功能来管理大量插入和更新时的性能,因为UI需要它们。因此,我们的解决方案是使用触发器来审核表上的所有信息,与NH当时提出的任何解决方案相比,响应时间都是难以置信的


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

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

Robert,请在标记中保留MSSQL、C4、NHib、Sharp Arch等标记,而不在标题中。