3

可能是我的标题不清楚。我正在寻找某种对数据库表的版本控制,就像 subversion 对文件所做的那样,就像 wiki 所做的那样。

我想跟踪更改日志。我想提取并反向运行差异。(像“svn merge -r 101:100”一样撤消)。我可能需要对历史进行索引搜索。

我已经阅读了“ Undo Engine 的设计模式”,但它与“模式”有关。有什么我可以在不重新发明轮子的情况下重复使用的东西吗?

编辑: 例如,银行账户交易。我在表格中更新了“余额”(和其他)列。用户会在 10 天后发现他的错误,他会想要取消/回滚特定交易,而不更改其他交易。

如何在应用程序级别优雅地做到这一点?

4

7 回答 7

3

Martin Fowler 在Patterns 中讨论了随时间变化的事物的主题。仍然是模式而不是实际的框架,但他展示了示例数据以及如何使用它。

于 2008-12-09T15:19:19.943 回答
3

您可以对要跟踪的每条记录使用修订方法。这将涉及在您的表中为记录的每个修订保留一行。这些记录将通过一个共享的“ID”联系在一起,并且可以在“修订状态”上进行查询(例如,获取最新的“已批准”记录)。

在您的应用程序层中,您可以单独处理这些记录,并在需要时回滚到较早的状态,只要您记录了所有必要的信息。

[ID] [Revision Date] [Revision Status] [Modified By] [Balance]
1     1-1-2008         Expired           User1         $100
1     1-2-2008         Expired           User2         $200
2     1-2-2008         Approved          User3         $300
1     1-3-2008         Approved          User1         $250
于 2008-12-09T15:40:07.140 回答
1

迂腐点。您的银行账户示例无法通过审计员/监管机构。

帐户中的任何错误条目都应留在那里以备记录。将对帐户应用相等且相反的更正交易。实际上回滚了原始事务,但留下了非常明显的原始错误及其更正痕迹。

于 2008-12-09T15:05:04.307 回答
1

我会采用双时态数据库设计,这将为您提供执行和回滚所需的所有数据,无论这意味着插入更多行还是简单地删除以后的修改。

这种数据库设计有相当多的微妙之处,但是关于这个主题有很好的书:

Richard T. Snodgrass 用 SQL 开发面向时间的数据库应用程序

可在此处下载:

http://www.cs.arizona.edu/people/rts/tdbbook.pdf

使用数据库事务将是一个坏主意,因为它会在数据库中创建锁 - 基本上数据库事务应该尽可能短。

应用层中的任何东西,除非它本身具有某种持久性机制,否则将无法在应用程序重新启动后继续存在(尽管这可能不是必需的)。

于 2008-12-09T17:02:34.913 回答
0

根据您对 James Anderson 的评论,我会让用户界面在取消交易时编写一个新的插入。它将向表中插入一条新记录,该记录与取消的事务具有相同的值,但该值将是负数而不是正数。如果您的结构包含定义交易目的的内容,我会说它已取消以及它正在取消的交易的记录号。

于 2008-12-09T16:05:51.953 回答
0

根据各种评论,您的问题的可能解决方案是制作一个“日期有效”表。

基本上,您将valid-from-date 和valid-to-date 列添加到每个表中。

“当前”记录的 valid_to_date 应始终为“2999-12-31”或一些任意高的值。当值更改时,您将“有效日期”更改为当前日期并插入一个新行,其有效日期为今天,有效日期为“2999-12-31”,复制所有旧行中的列(如果它们尚未更改)。

您可以使用“select all-columns-except-valid-xx-date from table where valid-to-date = '2999-12-31'”创建视图

这将允许您当前的所有查询保持不变。

这在数据仓库环境中是一种非常常见的技术,对于像汇率这样有效日期很重要的事情。

撤消逻辑应该是显而易见的。

于 2008-12-10T10:07:16.793 回答
0

尽管我在使用触发器和行版本之前已经设置了完整的撤消/审核历史记录,但我不知道具体的模式。

有几个适用于 MS Sql 的应用程序可让您浏览日志并查看实际更改。

我在 MS SQL 2000 中使用了一个名为 Log Navigator 的工具,它曾经让我撤消特定的历史事务——但我现在找不到它。

http://www.lumigent.comhttp://www.apexsql.com是查看日志的工具,但我认为它们都不能让你回滚它们。

我认为最好的方法是在编写应用程序时牢记这一点——你已经在这里有一些关于如何做的好建议。

于 2008-12-10T10:20:16.580 回答