首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据库版本控制

问数据库版本控制
EN

Stack Overflow用户
提问于 2009-12-07 13:23:20
回答 7查看 1K关注 0票数 3

我已经做了几个项目(CMS和EC系统),需要有一些数据版本。

通常我都会带着这样的模式

代码语言:javascript
复制
+--------------+
+ foobar       +
+--------------+
+ foobar_id    +
+ version      +
+--------------+

它工作得很好,但我想知道是否有更好的方法来做它。该解决方案的主要问题在于,您必须始终使用子查询来获取最新版本。

即:

代码语言:javascript
复制
SELECT * FROM foobar WHERE foobar_id = 2 and version = (SELECT MAX(version) FROM foobar f2 WHERE f2 = 2)

这使得大多数查询变得更加复杂,并具有一些性能缺陷。

因此,如果你能分享你创建版本化表的经验,以及每种方法的优缺点,那就太好了。

谢谢

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2009-12-07 13:26:54

我更喜欢将历史数据放在另一个表中。我会制作foobar_history或类似的东西,并制作一个foobar_id的FK。这将使您不必同时使用子查询。这还有一个额外的好处,那就是不会用大量的历史数据污染您的主数据表,而您可能不希望在99%的时间内访问这些数据。

不过,您可能希望为更新此数据创建一个触发器,因为这需要将当前数据复制到_history中,然后进行更新。

票数 5
EN

Stack Overflow用户

发布于 2009-12-07 14:49:00

在我看来,最干净的解决方案是为每个需要版本化的表创建一个History表。换句话说,先有一个foobar表,然后是一个foobar_History表,在foobar上有一个触发器,该触发器会将现有数据写入到History表中,并带有时间戳和更改数据的用户。较旧的数据很容易查询,按时间戳降序排序,而且您知道主表中的数据始终是最新版本。

票数 2
EN

Stack Overflow用户

发布于 2009-12-07 19:24:52

我曾经在一个包含历史数据的系统上工作,我们有一个布尔值来指示哪个是数据的最新版本。当然,您需要在应用级别上保持标志的一致性。然后,您可以创建使用该标志的索引,如果在where子句中提供该标志,则速度会更快。

优点:

  • easy to understand
  • does不需要对(现有)数据库架构进行重大更改
  • 不需要复制另一个表中的旧数据,只需更新标志。

缺点:

需要在应用程序级别维护

  • 标志

否则,您可以依赖于一个单独的历史表,如几个答案中所建议的。

优点:

  • 将历史记录与实际数据完全分开,以便在实体被

删除时,在实际数据及其历史记录之间进行数据库级联删除

缺点:

如果您想要完整的历史记录(即,旧数据+当前数据),

  • 需要2个查询(或联合)
  • 对应于最新版本数据的行将被更新。我听说update比insert慢,这取决于更改的数据的“大小”。

什么是最好的将取决于您的用例。我不得不处理一个文档管理系统,在这个系统中,我们希望能够对文档进行版本控制。但我们也有一些功能,比如恢复到旧版本。使用布尔值来加速只需要最后一个的操作会更容易。如果您有真实的历史数据(这些数据永远不会改变),那么专用的历史表可能会更好。

历史的概念适合你的领域模型吗?如果不是,那么您的db架构与您的概念域模型不同。如果在域级别,实际数据和旧数据需要以相同的方式处理,则使用两个表会使设计复杂化。只需考虑需要返回完整历史记录(旧+新)的情况。最简单的解决方案是为每个表都有一个类,但这样就不能像只有一个表那样容易地返回列表。但如果这是两个截然不同的概念,那么让历史在你的设计中成为一流的是很好的。

我还推荐M.Fowler的这篇文章,这篇文章在处理时态数据时也很有趣:Patterns for things that change with time

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1857977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档