如何在git(版本控制)下放置数据库?

has*_*sen 263 database git postgresql version-control

我正在做一个Web应用程序,我需要为一些重大更改创建一个分支,事实是,这些更改需要更改数据库模式,所以我想将整个数据库放在git下.

我怎么做?是否有一个特定的文件夹,我可以保存在git存储库下?我怎么知道哪一个?我怎么能确定我正在放置正确的文件夹?

我需要确定,因为这些变化不向后兼容; 我搞不起搞砸了.

我的数据库是PostgreSQL

编辑:

有人建议进行备份并将备份文件置于版本控制下而不是数据库中.说实话,我发现真的很难吞下去.

一定有更好的方法.

更新:

好的,所以没有更好的方法,但我仍然不太相信,所以我会稍微改变一下这个问题:

我想把整个数据库置于版本控制之下,我可以使用什么数据库引擎,以便我可以将实际数据库置于版本控制而不是转储?

sqlite会对git友好吗?

由于这只是开发环境,我可以选择我想要的任何数据库.

EDIT2:

我真正想要的不是跟踪我的开发历史,而是能够从我的"新的激进变化"分支切换到"当前的稳定分支",并且能够例如修复一些错误/问题等等.稳定的分支.这样,当我切换分支时,数据库自动神奇地变得与我当前所在的分支兼容.我真的不太关心实际数据.

X-I*_*nce 134

取一个数据库转储和版本控制.这样它就是一个平面文本文件.

我个人建议您同时保留数据转储和架构转储.通过这种方式使用diff,可以很容易地看到模式中从修订版本到修订版本的变化.

如果您要进行大的更改,您应该有一个辅助数据库,您可以将新架构更改为而不是触及旧架构,因为正如您所说的那样,您正在建立分支.

  • 什么?必须有一个更好的方法. (124认同)
  • PostGreSQL数据库文件是二进制文件,随意将它们放在你的git存储库中,你将无法对它们进行任何差异,任何更改都很可能会改变整个数据库,因此你现在必须发送完整的数据库数据库通过电线连接到你的git repo并存储它.这是低效,缓慢的,并且使得它非常难以使用.此外,我不确定没有VACUUM存储在磁盘上的数据库文件以及关闭PostgreSQL以进行复制是否"稳定",因为所有数据始终都是正确的,因此可能会使您丢失数据. (16认同)
  • 这种类型的解决方案非常标准,架构*实际上是*源代码. (14认同)
  • 这是2017年,这个问题的任何更新?实际上没有开箱即用的DB版本控制?真的吗? (11认同)
  • 嗯,我明白了!那么,有没有更友好的数据库系统? (6认同)
  • 请注意,如果您具有带有密码的Foreign Data Wrapper连接,这些密码将存储在架构中。因此,如果将转储置于版本控制中,则这些密码最终将进入版本控制。 (2认同)
  • 对我们为什么不对二进制文件进行版本控制缺乏理解感到有点恼火(为了效率,几乎每个活动数据库都是二进制文件)。简短的回答:它们不会像源文件那样进行干净的更改,因此维护一长串补丁的效率很低。如果您想要对数据库模式进行版本控制并且懒得进行手动转储,请使用 git hooks(或您最喜欢的 vcs 中的挂钩)让它自动从数据库服务器请求模式转储。然后你就会得到一些一致的东西,你的 vcs 可以比较。 (2认同)

小智 47

查看重构数据库(http://databaserefactoring.com/),了解一系列良好的技术,以便与代码更改一起维护数据库.

我只想说你提出错误的问题.您应该将更改分解为可验证的小步骤,以便您可以轻松地迁移/回滚模式更改,而不是将数据库放入git中.

如果您希望具有完全可恢复性,则应考虑归档postgres WAL日志并使用PITR(即时恢复)将事务回放/转发到特定的已知良好状态.

  • 我没有在数据库重构站点上找到相关信息...似乎列出了数据库代码的各种重构技术(就像Fowler对常规代码所做的那样) (2认同)

has*_*sen 26

我开始想到一个非常简单的解决方案,不知道为什么我之前没有想到它!

  • 复制数据库(架构和数据).
  • 在新主要更改的分支中,只需更改项目配置以使用新的重复数据库.

这样我就可以切换分支而不必担心数据库模式的变化.

编辑:

副本,我的意思是创建另一个具有不同名称的数据库(如my_db_2); 不做转储或类似的事情.

  • 这似乎是最简单,最有效的解决方案,但如果有一些方法可以实现自动化,那将会很好......我很惊讶那里还没有什么东西...... (3认同)

小智 19

使用像LiquiBase之类的东西,这可以让你保持对Liquibase文件的修订控制.您可以仅为生产标记更改,并让lb使您的数据库保持最新,无论是生产还是开发(或您想要的任何方案).

  • Liguibase的最佳实践建议将模式创建脚本保持为一组顺序运行的顺序脚本.虽然这是一个很好的最佳实践,但我没有看到它如何在没有中央存储库的情况下工作,这是非GIT. (3认同)

Hak*_*yal 6

在Doctrine下有一个名为Migrations的伟大项目,仅为此目的而构建.

它仍处于alpha状态,专为php而构建.

http://docs.doctrine-project.org/projects/doctrine-migrations/en/latest/index.html


sib*_*baz 6

我遇到过这个问题,因为我有一个类似的问题,其中一些近似于基于数据库的目录结构,存储“文件”,我需要 git 来管理它。它分布在云中,使用复制,因此它的访问点将通过 MySQL。

上述答案的要点似乎同样为所提出的问题提出了一种替代解决方案,这种解决方案忽略了使用 Git 管理数据库中的某些内容的要点,因此我将尝试回答该问题。

Git 是一个系统,它本质上存储了一个增量(差异)数据库,可以重新组装,以便重现上下文。git 的正常用法假设上下文是一个文件系统,而那些 delta 是该文件系统中的差异,但实际上所有 git 都是一个分层的 delta 数据库(分层,因为在大多数情况下,每个 delta 是一个提交,至少有 1父母,排列在树上)。

只要能生成delta,理论上git就可以存储。问题通常是 git 期望上下文,它在其上生成 delta 是一个文件系统,类似地,当您检出 git 层次结构中的一个点时,它期望生成一个文件系统。

如果你想在数据库中管理变更,你有两个离散的问题,我会分别解决它们(如果我是你的话)。第一个是架构,第二个是数据(尽管在您的问题中,您声明数据不是您所关心的)。我过去遇到的一个问题是 Dev 和 Prod 数据库,Dev 可以在其中对架构进行增量更改,这些更改必须记录在 CVS 中,并传播到实时,以及对几个“静态”之一的添加表。我们通过使用第三个数据库来做到这一点,称为 Cruise,它只包含静态数据。在任何时候都可以比较 Dev 和 Cruise 的模式,我们有一个脚本来获取这两个文件的差异并生成一个包含 ALTER 语句的 SQL 文件,以应用它。类似的任何新数据,可以提炼为包含 INSERT 命令的 SQL 文件。只要只添加字段和表,从不删除,该过程就可以自动生成 SQL 语句以应用增量。

git 生成 deltasdiff的机制是,将 1 个或多个 deltas 与文件结合的机制称为merge. 如果您能想出一种从不同上下文进行差异和合并的方法,git 应该可以工作,但正如已经讨论过的,您可能更喜欢为您执行此操作的工具。我解决这个问题的第一个想法是https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration#External-Merge-and-Diff-Tools,它详细介绍了如何替换 git 的内部差异和合并工具。我会更新这个答案,因为我想出了一个更好的解决方案,但在我的情况下,我希望只需要管理数据更改,就基于数据库的文件存储可能会更改而言,所以我的解决方案可能不是您所需要的。


Tai*_*ils 6

  • Irmin(分支+时间旅行)
  • Flur.ee(不可变+时间旅行)
  • Crux DB(时间旅行)
  • TerminusDB(分支+时间旅行)
  • DoltDB(分支+时间旅行)

一段时间以来,我一直在为 Postgres(或一般的 SQL 数据库)寻找相同的功能,但我发现没有足够合适(简单且直观)的工具。这可能是由于数据存储方式的二进制性质。Klonio听起来很理想,但看起来已经死了。Noms DB看起来很有趣(而且还活着)。另请查看Irmin(基于 OCaml 的 Git 属性)。

尽管这并不能回答问题,因为它可以与 Postgres 一起使用,但请查看Flur.ee数据库。它具有“时间旅行”功能,允许您从任意时间点查询数据。我猜它应该能够使用“分支”模型。

该数据库最近正在为区块链目的而开发。由于区块链的性质,数据需要以增量方式记录,这正是 git 的工作原理。他们的目标是在 2019 年第二季度发布开源版本

因为每个 Fluree 数据库都是一个区块链,所以它存储了每笔交易的完整历史记录。这是区块链如何确保信息不可变和安全的一部分

更新:还可以查看Crux 数据库,它可以查询插入的时间维度,您可以将其视为“版本”。Crux 似乎是备受好评的 Datomic 的开源实现。但是,它不支持 Dolt 和 Git 那样的分支。

Crux 是一个双时态数据库,用于存储交易时间和有效时间历史。虽然 [uni]temporal 数据库支持“时间旅行”查询从数据库创建到当前状态的数据库状态的事务序列,但 Crux 还提供对离散有效时间轴的“时间旅行”查询,而无需不必要的设计复杂性或性能影响。这意味着 Crux 用户可以用过去和未来的信息填充数据库,而不管信息到达的顺序,并对过去的记录进行更正以构建给定域的不断改进的时间模型。

更新 II 查看 Terminus DB:“TerminusDB 的文档 - 一个存储像 git 这样的数据的开源图形数据库”。它支持 Dolt 和 Git 等分支,但看起来还不是很成熟。

更新 III NomsDB 被分叉,现在在 DoltDB 中使用:https : //github.com/dolthub/dolt


Dha*_*DK' 5

面临类似的需求,这是我对数据库版本控制系统的研究:

  1. Sqitch-基于Perl的开源;适用于所有主要数据库,包括PostgreSQL https://github.com/sqitchers/sqitch
  2. Mahout-仅适用于PostgreSQL;开源数据库架构版本控制。 https://github.com/cbbrowne/mahout
  3. Liquibase-另一个开源数据库版本控制软件。免费版本的Datical。http://www.liquibase.org/index.html
  4. Datical - Liquibase的商业版本- https://www.datical.com/
  5. BoxFuse的Flyway-商业广告。https://flywaydb.org/
  6. 另一个开源项目https://gitlab.com/depesz/Versioning 作者在此处提供了指南:https//www.depesz.com/2010/08/22/versioning/
  7. 红门变更自动化-仅适用于SQL Server。 https://www.red-gate.com/products/sql-development/sql-change-automation/