我需要在应用程序中构建“版本控制”,并且想知道如何最好地处理它。
我有这种一般模式:
模型A有很多B
在更新时,A的属性需要进行版本控制,其关联对象(B)也需要进行版本控制。因此,应用程序将显示A的当前版本,但也必须能够查看以前版本的A及其关联对象。
我想使用文档存储但是这只是应用程序的一部分,并且拥有doc存储和关系数据库会带来更多的复杂性。
我考虑使用星型模式,但在我进步之前,我想知道是否有一个设计模式可以解决这个问题?
这个问题倾向于解决在关系数据库中存储关联对象的版本的问题。哪里有固有的需要能够有效地查询数据(即序列化对象是不够的)。
更新:我在想什么/已经实施但想要看看它是否是“更好的方式”
,---------. 1 * ,--------.
| Model A |----------| Model B|
`---------' `--------'
|PK | | a_id |
|b_version| |version |
|version | `--------'
`---------'
我将复制模型A和所有关联的B并增加版本属性。然后通过b_version和b.version进行选择以加入B'。只是想知道这是否可以做得更好。
答案 0 :(得分:10)
Martin Fowler有一些关于时间/版本设计模式的好文章 - 绝对值得一看:
答案 1 :(得分:7)
我认为没有特定的GoF设计模式本身用于版本控制,因为它存在许多实现。
最简单的版本控制实现是对象的链接列表。其中列表中的每个节点都是可版本化对象的新版本。为了节省空间,您还可以实现某种diff,以显示修订版之间的差异。这样您就可以在数据库中存储差异,但也可以在版本控制系统的最终版本中存储差异,因为版本控制系统应该能够在其间导出版本。
数据库架构主要看起来像这样(你可以在大多数wiki系统中看到这种模式):
+--------------------+ 1 * +-----------------------------+
| VersionableObject |---------| Diff |
+--------------------+ +-----------------------------+
| lastStateContent | | difference |
| originalAuthor | | revision |
| #dates and whatnot | | # userId, dates and whatnot |
+--------------------+ +-----------------------------+
如果你想用分支和东西去硬核,你可能要考虑看一下现代分布式版本控制系统使用的DAG。
现在,如果我们谈论你的例子,需要在配置中保存一大堆对象。即我们必须挑选出我们想要的模型对象的修订版。这意味着我们有多对多关系(用中间表解决),有点像这样:
+---+ 1 * +---------------+ 1 * +-----------------+ * 1 +-------+
| B |-------| Diff |-------| ModelSelection |-------| Model |
+---+ +---------------+ +-----------------+ +-------+
| revisionNo | | {PK} configId |
| {FK} configId | | {FK} modelId |
+---------------+ +-----------------+
我希望这会有所帮助。
答案 2 :(得分:2)
我使用acts_as_versioned
插件在rails中解决了这个问题。将其应用于模型时,它假定除了model_name_version
表之外还有model_name
。每次保存模型时,旧版本和时间戳都会复制到model_name_version
表中。
此方法可以保持模型表的大小可管理,同时仍允许搜索以前的版本。我不确定插件是否可以处理您想要的链接,但是添加起来并不难。
答案 3 :(得分:1)
Memento pattern与Observer pattern的组合应符合您的需求。另请查看Visitor pattern以了解您的案例中可能的应用程序......
答案 4 :(得分:0)
如何保存想要版本的数据库模式的XML快照?然后能够改变数据库的状态吗?