2010-07-08 67 views
4

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

我们玩弄类似布局的思路:

ID(PK)
的recordId
VERSIONID

,并具有一个新的记录每个编辑,达到创纪录的结果正与创造相同的recordId和递增的versionId。然后,记录显示将按照SELECT ... WHERE recordId = X AND versionId = MAX(versionId)的顺序完成一些操作。

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

但是我们很好奇其他实现方式是否已经尝试成功,或者存在潜在的问题。

+0

Robert,请在标签中标明“MSSQL,C#4,NHib,Sharp Arch”等标签。 – 2010-07-11 05:36:10

回答

3

我们有一个由我们的DBA开发的系统,用作更新/删除触发器。有一个辅助表几乎反映了正在审计的表(除了一些其他的细节,如交易时间,登录用于更新,服务器等)。任何时候有人进行更改,都会通过触发器登录到表格的审核版本中。每当架构发生变化时,都必须保持审计触发器的更新,但这种做法很烦人。

关于这个的好处是,应用程序并不需要在所有这个审计关注......所以它使应用程序代码低(更低)的概念,计数。

这是生产和工作在交易数量在每天数以万计的表格。您的里程数可能会因您的服务器大小和数据性质等因素而有所不同,但它适用于我们:-)

+0

我第二种方法! – Homer1980ar 2010-07-13 14:32:53

2

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

您可以将这些历史记录存储在单独的表中或不存在。如果你想只有一个包含所有行版本的表格,这个表格可以更好的维护和使用,你可能想看看SQL Server分区(分区表),它允许你将最近的历史和旧的历史分开,并优化搜索在上面。

1

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

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

7

你似乎暗指一张临时表。三种方法:

有效状态表:追加两个'时间戳'列(例如,型DATETIME),一种指定当行变为有效和一个指定当行不再是有效的,中间的时间被该行的有效期间

事务时状态表:同伙与每一行该行在监视表中存在的时间段,从而允许重建在任何先前时间点的受监视表的状态。

Bitemporal表:捕获有效时间和交易时间,同时记录企业的历史,同时捕获历史记录的变化顺序。

来源:Developing Time-Oriented Database Applications in SQL (Richard T Snodgrass)

2

我有一个类似的问题,我需要审核的每一个变化,以一组表。尝试使用只有NHibernate的功能来管理大量的插入和更新(因为UI需要他们)时

,我们有最大的问题是性能。所以我们的解决方案是使用TRIGGERS来审计表格上的所有信息,并且比较我们当时可能遇到的任何解决方案与NH的响应时间是不可思议的。

如果有人问我该怎么办呢,我想说的触发器是审计数据的方式。

0

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