【问题标题】:Storing git like commit history of changes像提交更改历史一样存储 git
【发布时间】:2014-04-22 11:06:23
【问题描述】:

我想为我的一个数据库实体构建一个类似 git 的版本控制系统。

模型将是:

Commit
  parent_commit_id

Change
  entity_id
  commit_id
  modifier (added, deleted, modified)

Entity

实体永远不会被真正删除,因此用户可以撤消提交并最终获得有效状态。

听起来很简单,但是:

  • 用户每次点击都会生成一个提交(性能非常重要)
  • 每次提交都会有大约 100 处更改(修改、添加或删除)

因为我们只是存储更改,所以必须计算或存储当前状态。

选项 1:保存每次提交的完整状态意味着我不仅会在提交中存储修改、添加和删除,而且还会存储所有未更改的实体。我认为这不是一个真正的选择,因为系统运行时将有超过 2000 万个实体。

选项 2:使用递归公用表表达式计算当前状态。我不知道这是否足够快......

选项 3:在一段时间后执行清理(如 git gc)。这意味着我实际上会删除在清理时不再有效的所有实体。这不是一个真正的选择,因为我希望能够查看所有更改并返回到这些更改。

选项 4:使用图形数据库 (neo4j)?它能以合理的性能处理这样的规范吗?

您还有其他想法吗?

【问题讨论】:

  • 我想存储两个东西 - 一个具有当前状态的 unlogged 表,以及一个包含一系列更改和原始状态的普通表。在崩溃时,您可以通过应用历史差异来重新生成未记录的“当前状态”表,但这需要一段时间。 (根据一致性要求,您甚至可以选择使用 redis / memcached 之类的东西来存储当前状态。但是您需要以某种方式对其进行缓存。)

标签: postgresql neo4j


【解决方案1】:

您使用 Neo4j 的想法很有趣。快速阅读http://en.wikibooks.org/wiki/Git/Internal_structure 已经显示了 git 的复杂程度以及提交拓扑是一个“有向无环图”这一事实,它支持 Neo4j。

但要考虑的一件事是您计划的模型有多复杂?你想要 git 的部分或全部复杂性吗?如果是这样,像 Neo4j 这样的灵活数据库将是一个好主意。

如果您只想要跟踪单个文件的更改,而不考虑多个并发用户,那么请考虑旧的 RCS 系统,它存储了最新的文件,以及与以前版本的差异链。这可以很容易地存储在两个表中(一个用于文件,一个用于更改)。这是丹的答案的相反方向,它存储第一个文件和那里的更改。两种方式都有效,但 RCS 方式检索最新版本的速度比旧版本快,而视频方式检索旧版本最快。由于您从最旧到最新观看视频,因此他们这样做是有道理的,但我认为对于文件修订,您通常首先需要最新的。要更全面地了解这些方法,请查看 Event Sourcing 上的 Martin Fowlers 博客。然而,这些方法并没有真正考虑多个并发用户或任何复杂的东西。但它们可以成为更多的基础。

让我们重新考虑更复杂的模型。 Neo4j 是无模式的,允许您从简单开始并根据需要使用功能进行增强。例如,您可能会遵循以下路线:

  • 构建一个简单的类似 RCS 的文件修订系统,在单个图形节点中包含最新内容,以及旧版本的链接链(或旧版本的差异链)
  • 然后您决定需要支持多个文件的提交,添加树对象(在http://en.wikibooks.org/wiki/Git/Internal_structure 中描述),这些可以是图中的真实树结构,图节点链接到文件对象节点。
  • 这些树由提交对象引用,这些提交对象本身与先前的提交以链形式链接。一旦你有了这些提交链,你可能就不再需要文件链了,因为你会遍历提交链。每个提交都指向一棵树,该树指向文件。
  • 然后也许你决定支持分支,所以你添加标签和分支对象,它们链接到提交(以及从那里的树和文件)。这自然会导致无环有向图显示随时间发生的分支和合并。
  • 然后也许您甚至考虑添加 reflog,也可以将其建模为图表。

当您浏览上面的列表时,整个图表会变得更丰富、更复杂,从而支持更大的用例集。我认为这是构建数据模型的好方法。

从阅读http://en.wikibooks.org/wiki/Git/Internal_structure 可以清楚地看出,即使在那里提供了简化的描述,我们已经可以看到大部分建模的价值是图表。链表、树和无环有向图。在我看来,Neo4j 将是一项不错的技术。

那么如何开始呢?例如,查看一些Graph Gist Examples。一个与此处相关的简单方法是Simple versioning nodes scheme。然后从那里构建。

【讨论】:

  • 感谢您的出色回答和图表要点的链接。我想我会试试 Neo4j。
【解决方案2】:

我必须仔细考虑一些细节 - 但如果你从视频处理中吸取教训 - 拥有原始签入,并让每个版本都有增量,但有一个“关键帧”属性表明完整的快照,例如 10 次提交,并且始终是最新版本。为您提供良好的性能组合,无需为每次提交存储完整数据...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-06
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 2020-12-18
    • 2021-09-03
    相关资源
    最近更新 更多