有没有用于撤销/重做数据库行更改的库/框架?

3

也许我的标题不够清楚。我正在寻找一种类似于subversion对文件进行版本控制的数据库表版本控制方法,类似于wiki的做法。

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

我已经阅读了“Undo引擎设计模式”,但它与“模式”相关。有没有什么东西可以重用而不必重新发明轮子?

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

如何在应用程序级别上优雅地完成这项工作?


你可能会喜欢看这里:https://dev59.com/MHRC5IYBdhLWcg3wW_tk - WW.
我不是在问我怎么做。我是在问是否有任何可以重用的代码。 - Dennis C
7个回答

3

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

“Revision Staus” 列对我来说似乎是不必要的,如果有多行具有相同的ID,则可以得出最大/最新的修订日期的行被批准,所有其他行都已过期。 - jamiebarrow

1

有点事无巨细。您的银行账户示例无法通过审计员或监管机构的审核。

任何账目中的错误条目都应保留在记录中。等额而相反的纠正交易将被应用于该账户。实际上,它是回滚原始交易,但会留下非常明显的原始错误及其更正的痕迹。


1
那就是我想要的。我不打算取消那个提交,但请允许我跟踪和撤消(例如使用另一个“svn合并-r 101:100”再进行“svn提交”)。 但是我该如何在我的应用程序上优雅地实现它呢? - Dennis C

1
我会选择双时间数据库设计,这将为您提供执行和回滚所需的所有数据,无论是插入更多行还是仅删除后续修改。
这种数据库设计有相当多的微妙之处,但是关于此主题有一本非常好的书:
《SQL中开发面向时间的数据库应用》Richard T. Snodgrass著
可以在此处下载:

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

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

除非应用程序层具有某些持久性机制,否则应用程序层中的任何内容都无法在应用程序重新启动后存活(尽管这可能不是必需的)。


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

0

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

基本上,您需要在每个表中添加有效日期和到期日期列。

“当前”记录的有效截止日期应始终为“2999-12-31”或某个高值。当值更改时,您需要将“有效截止日期”更改为当前日期,并插入一个新行,其中今天的有效起始日期和有效截止日期为“2999-12-31”,如果旧行的所有列都没有更改,则复制它们。

您可以使用以下视图创建:

"从表中选择除valid-xx-date之外的所有列,其中valid-to-date ='2999-12-31'"

这将允许所有当前查询无需更改即可工作。

这是数据仓库环境和汇率等重要的有效日期技术中非常常见的技术。

撤消逻辑应该很明显。


1
至少在Oracle中,设置一个离谱的大值是不好的,因为它会让优化器感到困惑。通常使用NULL更好。 - WW.
我会阅读《开发面向时间的数据库应用程序》(它在我发布的答案中有链接)。在那里解释了很多原因,说明为什么使用null是一个坏主意,大多数原因都归结于它增加了查询的复杂性。 - Nick Holt

0

我不知道具体的模式,但我曾经在使用触发器和行版本之前建立完整的撤销/审核历史记录。

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

我曾经使用过一个叫做 Log Navigator 的应用程序,它可以让我撤消特定的历史交易-尽管现在我找不到它了。

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

我认为最好的方法是考虑编写应用程序时的这一点-您已经有了几个关于如何做到这一点的好建议。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接