我想为我的数据库实体构建一个类似于版本控制系统的git。
模型将是:
Commit
parent_commit_id
Change
entity_id
commit_id
modifier (added, deleted, modified)
Entity
实体永远不会被删除,因此用户可以撤消提交并最终获得有效状态。
听起来很简单,但是:
因为我们只是存储更改,所以必须计算或存储当前状态。
选项1 :保存每次提交的完整状态意味着我不仅会在提交中存储修改,添加和删除,还会存储未更改的每个实体。我认为这不是一个真正的选择,因为系统运行时将有超过2000万个实体。
选项2 :使用递归公用表表达式计算当前状态。我不知道这是否足够快......
选项3 :在一段时间后执行清理(如git gc)。这意味着我实际上会删除在清理时不再有效的所有实体。不是一个选项,因为我希望能够看到所有的变化并回到那些变化。
选项4 :使用图表数据库(neo4j)?它能以合理的性能处理这样的指定吗?
你还有其他想法吗?
答案 0 :(得分:4)
您使用Neo4j的想法非常有趣。快速阅读http://en.wikibooks.org/wiki/Git/Internal_structure已经显示了git的复杂程度,以及提交拓扑是一个“有向无环图”的事实,它支持Neo4j。
但要考虑的一件事是你计划的模型有多复杂?你想要git的部分或全部复杂性吗?如果是这样的话,像Neo4j这样的灵活数据库将是一个好主意。
如果您只想要跟踪单个文件更改的内容,而不考虑多个并发用户,那么请考虑存储最新文件的旧RCS系统以及先前版本的差异链。这可以很容易地存储在两个表中(一个用于文件,一个用于更改)。这是Dan的答案的相反方向,它存储第一个文件和那里的变化。两种方式都有效,但RCS方式能够比旧版本更快地检索最新版本,而视频方法可以最快地检索旧版本。既然您从最旧到最新观看视频,那么它们就是这样做的,但我认为对于文件修订,您通常需要最新的视频。有关这些方法的更全面的评论,请查看Martin Fowlers博客Event Sourcing。但是,这些方法并不真正考虑多个并发用户或任何复杂的用户。但它们可能是更多的基础。
因此,让我们重新考虑更复杂的模型。 Neo4j是无架构的,允许您根据需要开始简单和增强功能。例如,您可以遵循以下路线:
当您浏览上面的列表时,总图表变得更丰富,更复杂,支持更多的用例。我认为这是构建数据模型的好方法。
从阅读http://en.wikibooks.org/wiki/Git/Internal_structure可以清楚地看出,即使提供了简化的描述,我们也可以看到建模中的大部分价值都是图形。链表,树和非循环有向图。对我来说听起来像Neo4j这是一个很好的技术。
那么如何开始?例如,看一下Graph Gist Examples的某些内容。这里看起来很简单的一个简单的是Simple versioning nodes scheme。然后从那里开始构建。
答案 1 :(得分:1)
我必须仔细考虑一些细节 - 但是,如果你从视频处理中吸取教训 - 有原始的签到,并且每个版本都有delta,但是有一个'keyframe'属性可以指示完整快照,每个,10个提交,总是最新版本。为您提供良好的性能组合,无需为每次提交存储完整数据......