为什么源代码控制系统仍大多以文件为后盾?


22

似乎更多的源代码控制系统仍将文件用作存储版本数据的手段。Vault和TFS使用Sql Server作为它们的数据存储,我认为这对于数据一致性和速度会更好。

因此,为什么SVN,我相信GIT,CVS等仍然将文件系统用作本质上的数据库(我问这个问题,因为我们的SVN服务器只是在正常提交期间损坏了自己),而不是使用实际的数据库软件( MSSQL,Oracle,Postgre等)?

编辑:我想问我的问题的另一种方式是“为什么VCS开发人员推出自己的结构化数据存储系统而不使用现有的结构化数据存储系统?”


29
您认为大多数数据库将其用作什么基础?大多数使用文件(但是,少数使用直接访问硬盘)。您可以使用“正义文件”来拥有数据库的所有功能。
约阿希姆·绍尔

2
@JoachimSauer公平的观点,尽管您当然必须自己创建一个数据库。如果您所需的功能集与现有解决方案的功能集非常接近,并且没有充分的理由不使用这些功能,则这是很愚蠢的。

1
@JoachimSauer是的,我意识到这一点,但是DBM系统有办法确保没有不一致的东西进入数据库。除非这些基于文件的存储库使用的是诸如Transactional NTSF之类的东西,否则仍有可能被破坏。而且,我相信真实的数据库比我对一组开发人员本质上重新发明轮子的信任更重要,因为我认为我们可以同意源代码控制系统需要数据完整性。
安迪

2
@delnan事务支持和内部一致性。现在,我们正在从磁带b / c还原SVN存储库,因为SVN服务器未正确写入它应该写入的所有文件。还搜索大量数据。我的意思是,为什么要尝试重新发明轮子。
安迪2012年

7
每个主要操作系统都内置有一个文件系统。所有这些文件系统都具有相同的基本功能(文件,文件夹,相同的持久性)。基本上,数据库是最终用户需要安装并保持更新的一个额外依赖项。源代码控制不是大多数人的主要业务(除非您是sourceforge或github)。VC通常是由团队的最新成员通过命令行安装在服务器上的。易于安装和设置很重要。
GlenPeterson,2012年

Answers:


23

TL; DR:很少有版本控制系统使用数据库,因为它不是必需的。

作为一个问题的答案,为什么不呢?在这种情况下,“真实的”数据库系统相对于文件系统有什么好处?

考虑到修订控制主要是跟踪少量的元数据和大量的文本差异。文本不能更有效地存储在数据库中,内容的可索引性也不会成为因素。

让我们假设Git(出于参数考虑)使用BDB或SQLite DB作为其后端来存储数据。哪一个更可靠?任何可能破坏简单文件的内容也可能破坏数据库(因为这也是具有更复杂编码的简单文件)。

从程序员除非必要就不进行优化的范式来看,如果修订控制系统足够快且足够可靠地工作,为什么要更改整个设计以使用更复杂的系统?


2
TLDR?您回答的时间是原来的两倍,而问题实际上是很短的!
Brad

25
@Brad后面的三个词TL;DR是答案的删节版本,不是陈述问题太长,并且他在回答之前没有看过它。

6
@Andy Mercurial也有“历史上的grep”,而git也可能也有。它也已经快如闪电。至于将事情留给专家:开发VCS的人专家。

3
只是想补充一点,我确实明白你的意思;如果VCS写入错误数据,则将其写入文件或数据库也没关系。但是,不利的一面是,基于文件的存储库可能一次写入多个文件,并且通常对此没有事务支持,因此,如果一个文件写入但另一个失败,则您的VCS已损坏,而数据库中的多个表写入事务将作为一个整体提交失败。我觉得好像一组开发数据库软件的开发人员比编写SVN的人们对此有更多的经验……但是也许我错了。
安迪

6
您在git上“出于参数考虑”的选择在这里很重要:git有一个很好的模型来编写其对象,但是许多工具却没有。使用git,如果在提交过程中关闭了计算机的电源,则您已经将一些对象写入了文件系统,而这些对象将只是不可访问的。对于其他VCS,您可能会将更改附加到一半的文件中(随之而来的是混乱)。您可能会说其他版本控制工具的设计不佳(您是对的),但是在编写VCS时,它是仅使用SQL事务并让它做正确的事就容易得多。
爱德华·汤姆森

25

您似乎在做出许多假设,可能是基于您对SVN和CVS的经验。

Git和Mercurial基本上就像SVN和CVS

比较git和CVS就像比较iPad和Atari。CVS是在恐龙漫游地球时创建。Subversion基本上是CVS的改进版本。假设像git和Mercurial这样的现代版本控制系统像它们那样工作几乎没有任何意义。

关系数据库比单一用途的数据库效率更高

为什么?关系数据库确实非常复杂,并且可能没有单一用途的数据库有效。我的脑海有些变化:

  • 版本控制系统不需要复杂的锁定,因为无论如何您不能同时进行多个提交。
  • 分布式版本控制系统需要非常节省空间,因为本地数据库是仓库的完整副本。
  • 版本控制系统只需要以几种特定的方式查找数据(按作者,按修订ID,有时是全文搜索)。创建自己的数据库来处理作者/修订ID搜索很简单,在我尝试过的任何关系数据库中,全文搜索都不是很快。
  • 版本控制系统需要在多个平台上工作。这使得使用需要安装并作为服务运行的数据库(例如MySQL或PostgreSQL)更加困难。
  • 本地计算机上的版本控制系统仅在执行某些操作(例如提交)时才需要运行。离开运行像MySQL服务所有的时间,以防万一你想要做一个承诺是一种浪费。
  • 在大多数情况下,版本控制系统从不希望删除历史记录,而只是将其追加。这可能导致不同的优化和保护完整性的不同方法。

关系数据库更安全

同样,为什么呢?您似乎以为,因为数据存储在文件中,所以git和Mercurial之类的版本控制系统没有原子提交,但它们确实有原子提交。关系数据库其数据库存储为文件。这里值得注意的是CVS 不会执行原子提交,但这很可能是因为它来自黑暗时代,而不是因为它们不使用关系数据库。

一旦将数据放入数据库中,还存在防止数据损坏的问题,答案也相同。如果文件系统已损坏,则使用哪个数据库都没有关系。如果文件系统未损坏,则数据库引擎可能已损坏。我不明白为什么版本控制数据库比关系数据库更容易出现这种情况。

我认为,分布式版本控制系统(如git和Mercurial)比集中式版本控制更适合保护数据库,因为您可以从任何克隆还原整个存储库。因此,如果中央服务器与所有备份一起自然燃烧,则可以通过git init在新服务器上运行来恢复它,然后git push任何开发人员的计算机上恢复它

重新发明轮子是不好的

仅仅因为您可以将关系数据库用于任何存储问题,并不意味着您应该这样做。为什么使用配置文件而不是关系数据库?当您可以将数据存储在关系数据库中时,为什么将图像存储在文件系统上?当您可以将所有代码存储在关系数据库中时,为什么还要将代码保留在文件系统上?

“如果你只有一把锤子,那么一切看起来就像钉子。”

还有一个事实是,开源项目有能力在方便的时候重新发明轮子,因为您没有商业项目那样的资源约束。如果您有一位自愿编写数据库的志愿者,那么为什么不使用它们呢?

至于为什么我们希望版本控制系统的作者知道他们在做什么。.我不能代表其他VCS,但是我非常有信心Linus Torvalds可以 理解文件系统

为什么某些商业版本控制系统使用关系数据库呢?

最有可能是以下各项的组合:

  • 一些开发者不想要编写数据库。
  • 商业版本控制系统的开发人员受时间和资源的限制,因此,当他们拥有的东西已经接近他们想要的东西时,他们将无力编写数据库。而且,开发人员很昂贵,而数据库开发人员(例如,编写数据库的人)可能会更昂贵,因为大多数人没有那种经验。
  • 商业版本控制系统的用户不太可能关心建立和运行关系数据库的开销,因为他们已经拥有一个。
  • 商业版本控制系统的用户更可能希望使用关系数据库来支持其修订数据,因为这可以更好地与他们的流程集成(例如备份)。

1
一件事:SVN提交原子的。实际上,这是一个主要卖点(或者至少是在他们不得不说服CSV用户进行转换时返回)。

1
@delnan-请注意,在工作目录中的不同目录可以处于不同修订版本的情况下获得的理论原子性与使用或获得的真正的存储库范围的原子性之间存在很大差异。svnsvngithg
Mark Booth 2012年

2
@Andy我的观点是,无需成熟的关系数据库就可以处理那些完全相同的场景。如果两个人在同一时间提交,则服务器可以一个接一个地执行。这不是实现一个复杂的功能。如果要对本地用户执行此操作,只需拥有一个锁定文件。开始提交时,请锁定文件。结束提交后,释放锁。如果要允许一次提交到多个分支,请为每个分支使用一个锁定文件。当然,SQLite会为我执行此操作,但这不是必需的
恢复莫妮卡2012年

1
同样,实施基本日记也不复杂。(1)将新提交写入文件。(2)复制旧的索引文件。(3)写一个新的索引文件。(4)删除旧索引文件的副本。如果在步骤1、2或4失败,则只需清理您创建的新文件。如果在第3步失败,则只需将旧索引文件复制回去。更好地了解文件系统的人可能会对此做一个更有效的版本,但是如果需要,您可以始终引用SQLite的源代码(它是公共领域的)。
恢复莫妮卡2012年

1
@BrendanLong很棒的观点。赞赏讨论。明确地说,我认为这两种后备商店都各有利弊,我不相信只有一个正确的答案。但是让我有些惊讶的是,似乎只有三个(如果您分别计算Vault和Vercity,则使用四个)使用SQL,而绝大部分都没有。
安迪

18

实际svn用于将BDB用于存储库。最终将其消除,因为它容易断裂。

当前使用DB(SQLite)的另一个VCS是fossil。它还集成了一个错误跟踪器。

我对真正原因的猜测是,VCS可处理大量文件。文件系统只是另一种数据库(分层的,专注于CLOB / BLOB存储效率)。普通数据库不能很好地解决这一问题,因为没有理由-文件系统已经存在。


1
BDB并不是完全可靠的,就像SQLite一样,它是一个进程内数据库。就是说,我认为Oracle / MSSQL / MySQL / Postgres的可靠性(取决于您如何配置它们)与文件系统没有太大区别。主要问题是,RDBMS并非为VCS通常使用的层次结构和图结构而构建。在这种情况下,文件系统只会赢。
迈克·拉尔森

3
@Andy:化石是由SQLite的创建者创建的。这不是真的那么奇怪:-)
约尔格W¯¯米塔格

1
@Andy:我对SQLite的信任比对Oracle或MSSQL的信任要大得多。毫无疑问,它是目前使用最广泛的SQL数据库。它也是移植到大多数不同体系结构上的一个,每个体系结构都有其自身的挑战,从而使共享代码具有难以置信的防弹性能。
哈维尔2012年

1
@Javier我对Sqlite的信任程度不如MSSQL或Oracle。正如Mike所说,进程中的部分使我感到恐惧,好像您的应用程序死了,可能现在会使您的数据库损坏。使用客户端/服务器数据库,客户端快要中止事务。并不是说CS DB不可能损坏,但我认为它比将DB引擎与应用程序结合的可能性要小。
安迪2012年

5
@Andy,这就是交易的目的。无论在什么时候杀死一个好的数据库引擎,给定的事务都将被提交或不提交。SQLite的原子提交(sqlite.org/atomiccommit.html)实现是一种特别复杂的实现。
哈维尔

10
  1. 文件系统一个数据库。当然,它不是关系数据库,但是大多数都是非常有效的键/值存储。而且,如果您的访问模式针对键值存储(例如git存储库格式)进行了精心设计,那么使用数据库可能不会比使用文件系统提供明显优势。(实际上,这只是妨碍实现的另一层抽象。)

  2. 许多数据库功能只是多余的负担。全文搜索?全文搜索对源代码有意义吗?还是需要以不同的方式标记它?这还要求您在每个修订版中存储完整文件,这是不常见的。为了节省空间,许多版本控制系统都在同一文件的修订版之间存储增量,例如SubversionGit(至少在使用打包文件时)。

  3. 跨平台的要求使使用数据库更具挑战性。

    大多数版本控制工具都可以在多个平台上运行。对于集中式版本控制工具,这仅影响服务器组件,但是仍然难以依靠单个数据库服务器,因为Unix用户无法安装Microsoft SQL Server,而Windows用户可能不愿意安装PostgreSQL或MySQL。文件系统是最小公分母。但是,有几种工具必须将服务器安装在Windows机器上,因此需要SQL Server,例如SourceGear Vault和Microsoft Team Foundation Server

    分布式版本控制系统使这更具挑战性,因为每个用户都可以获取存储库的副本。这意味着每个用户都需要一个数据库将存储库放入其中。这意味着该软件:

    1. 仅限于存在特定数据库的平台的子集
    2. 针对跨平台的单个数据库后端(例如SQLite)。
    3. 面向可插拔的存储后端,以便人们可以使用他们想要的任何数据库(可能包括文件系统)。

    因此,大多数分布式版本控制系统仅使用文件系统。SourceGear的Veracity是一个明显的例外,它可以存储在SQLite数据库(对本地存储库有用)或关系数据库(如SQL Server)(可能对服务器有用)。他们的云托管产品可能使用非关系存储后端,如Amazon SimpleDB。 ,但我不知道这是真的。


就像恶魔的拥护者评论一样,大多数问这类“为什么不使用数据库”问题的人似乎都意味着“为什么不使用RDBMS?”。所有ACID合规性以及其他相关问题。所有文件系统已经是其自身同类数据库的事实已经被丢弃。
mikebabcock 2012年

6

据我在许多产品中所看到的,似乎文件“足够好”地完成工作,这是合理的,考虑到在一天结束时VCSes输出也是文件。

有许多公司提供带有svn / git / etc接口的RDBMS后端,因此您所要求的基本上已经存在。


5

我会说这是因为版本控制系统的主要数据结构是DAG,它很难映射到数据库。许多数据也是内容可寻址的,这也很难映射到数据库。

数据完整性不是VCS唯一关注的问题,它们还与版本历史记录有关完整性有关,而数据库的不是很出色。换句话说,当您检索一个版本时,不仅需要确保该版本没有当前缺陷,而且还需要确保其整个历史中的所有内容都没有被秘密修改。

除了企业产品之外,VCS还是消费产品。人们在一个人的小型业余爱好项目中使用它们。如果您增加了安装和配置数据库服务器的麻烦,那么您将疏远大部分市场。我猜您在家里看不到很多Vault和TFS安装。这是电子表格和文字处理器不使用数据库的相同原因。

同样,这更是DVCS的原因,但是不使用数据库使其变得非常可移植。我可以将源树复制到拇指驱动器上,然后在任何计算机上重用它,而无需配置数据库服务器进程。

至于提交期间的损坏,VCS使用与数据库完全相同的技术来防止同时访问,使事务原子化等。两者中的损坏很少见,但确实 会发生。出于所有目的和目的,VCS数据存储库一个数据库。


1
“到数据库的映射非常差”,而Vault和TFS只是这样做。“数据完整性不是VCS唯一关心的问题,它们还与版本历史记录完整性有关,而数据库的数据库历史记录并不是很擅长。” 我看不到存储版本历史记录如何使其适合数据库中的文件,尤其是因为我已经命名了可以做到这一点的产品。“。两者中的腐败都很罕见,但确实会发生。” 第一页中的所有结果均未提及Vault服务器数据库已损坏。甚至讨论Vault软件问题的一个链接是WC已损坏。
安迪

“从所有意图和目的来看,VCS数据存储都是一个数据库。” 好吧...这就是我的意思。为什么不将数据保留在真实的数据库系统中而不是自己滚动呢?
安迪

2
@Andy是的,这是一个数据库,但并非所有数据库都可以互相替代。每个数据库对世界都有一定的看法(例如,SQL DB基本实现了关系模型)。关于此答案的详细信息,VCS存储的数据以及数据的使用方式不适合关系模型。我不确定某些NoSQL db是否会做得更好,但是它们是相当新的并且尚未证明其优越性(我记得有些报告涉及严重的完整性问题)。然后,还有其他所有问题。

DAG仅在DVCS中使用(除非您将线性历史记录视为非常简单的DAG,但它并不是真正有用的抽象。)当您的历史记录是线性的且单调增加变更集时,SQL数据库的意义就更大了。
爱德华·汤姆森

对于VCS,单调增加版本号没有多大意义。我已经使用了相当多的代码,而那些使用集中版本号(CVS和SVN是我最熟悉的2)的代码往往很难合并。甚至那些尝试合并的人也使用DAG。仅仅因为它们的存储表示不基于它,并不意味着它没有被使用。
Mike Larsen 2012年

2
  • 更好的灾难恢复(最坏的情况:像过去一样,我们会通过肉眼来解析它)

  • 简化由VCS系统故障引起的此类灾难的跟踪和调试。

  • 减少依赖性数量。(让我们不要忘记这些系统中的一个处理内核,另一个是应该)

  • 文本编辑器始终可用。(MS SQL Server许可证...不多)


这个答案是不好的。唯一真正正确的一点是减少依赖项的数量。两种备份系统都应该与您进行适当的备份时处于同等水平,调试DB应用程序不比调试写入文件的应用程序困难,并且文本编辑器始终可用吗?我什至不知道您的意思是什么,因为VCS本身不会使用文本编辑器,并且那里还有其他数据库服务器(Sqlite,Postgre,MySql等),因此如果您想要db支持的解决方案缺少db服务器应该不是一个因素。
安迪

1
@Andy ...程序员将习惯使用文本编辑器。您知道,即使在您最喜欢的IDE中,文本编辑仍可作为辅助功能使用。
ZJR 2012年

1
鉴于现代DVCS提供了大量的分布式方案,@ Andy sqlite文本文件的唯一可能替代方案。(idk,也许您可​​能已经错过了DVCS的“分布式”部分)。其他任何事情都太麻烦了(配置+防火墙+许可证),甚至很愚蠢而无法分发。然后再次对sqlite进行最坏情况的验尸可能会很难。
ZJR 2012年

1
@ZJR:我不认为最初的问题指定过分布式版本控制,而是总体上询问了版本控制系统。此外,您的文本编辑器参数有点扁平化,因为许多系统不仅仅存储平面文本文件。甚至git也具有许多二进制文件格式(松散的对象,打包文件等),这些格式使您的文本编辑器无用。
爱德华·汤姆森

@ZJR在文本编辑器中编辑代码如何关联到VCS的后备存储?例如,您是否建议手动编辑SVN的数据库?另外,我的问题不仅限于DVCS,所以我不知道您为什么要对此施加压力。
安迪

2

化石是出色的分布式版本控制系统(DVCS),使用SQLite进行存储,没有纯文本文件。

我真的很喜欢它已经集成:错误跟踪,Wiki,并且它确实是分布式的。我的意思是您可以真正脱机工作并修复错误。

Fossil使用Sqlite作为其应用程序文件格式。在PgCon主题演讲中, Richard Hipp博士解释了将sqlite用作应用程序文件系统的优点,并对使用数据库作为文件系统的好处提出了令人信服的论点。

第二个主要主题是将SQLite视为一种应用程序文件格式,这是发明自己的文件格式或使用ZIPED XML的替代方法。语句“ SQLite不能替代PostgreSQL。SQLite替代了fopen()”钉子(幻灯片21)。最后,Richard重点强调了SQLite会处理您的数据(崩溃安全,ACID)的事实use-the-index.com

现在,希普博士已经解决了将代码保存在数据库中的问题

  • 为什么Fossil基于SQLite而不是基于分布式NoSQL数据库?

Fossil不是基于SQLite。Fossil的当前实现使用SQLite作为分布式数据库内容的本地存储,并用作有关分布式数据库的元信息的缓存,该信息已预先计算以方便快速地呈现。但是,在此角色中使用SQLite是实现细节,而不是设计的基础。Fossil的某些将来版本可能会取消SQLite,并用一堆文件或键/值数据库代替SQLite。(实际上,这不太可能发生,因为SQLite在其当前角色中表现出色,但关键是从Fossil省略SQLite是一种理论上的可能性。)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.