我正在做一个web应用程序,我需要为一些主要的更改做一个分支,事情是,这些更改需要更改数据库模式,所以我想把整个数据库放在git下。

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

我需要确定,因为这些更改是不向后兼容的;我可不能搞砸。

在我的例子中,数据库是PostgreSQL

编辑:

有人建议进行备份并将备份文件置于版本控制之下,而不是将数据库置于版本控制之下。说实话,我觉得这真的很难接受。

肯定有更好的办法。

更新:

好吧,没有更好的方法了,但我还是不太相信,所以我要稍微改变一下问题:

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

sqlite是git友好的吗?

因为这只是开发环境,所以我可以选择任何我想要的数据库。

Edit2:

我真正想要的不是跟踪我的开发历史,而是能够从我的“新的根本性变化”分支切换到“当前稳定的分支”,并且能够用当前稳定的分支修复一些错误/问题等。这样,当我切换分支时,数据库就会自动地与我当前所在的分支兼容。 我不太关心实际数据。


当前回答

我已经发布了一个sqlite工具,它可以满足您的要求。它使用一个自定义的差异驱动程序,利用sqlite项目工具'sqldiff', uuid作为主键,并去掉sqlite rowid。它仍然处于alpha阶段,所以反馈是非常感谢的。

Postgres和mysql比较棘手,因为二进制数据保存在多个文件中,即使您能够对其进行快照,也可能无效。

https://github.com/cannadayr/git-sqlite

其他回答

我说不要。数据在任何时候都可能改变。相反,您应该只提交代码、模式和表定义(创建数据库和创建表语句)中的数据模型以及单元测试的示例数据。这就是Laravel的工作方式,提交数据库迁移和种子。

这个问题基本上已经回答了,但我想用一个小建议来补充X-Istence和Dana the Sane的回答。

如果您需要具有一定粒度的修订控制,比如每天,那么您可以使用rdiff-backup之类的工具将表和模式的文本转储与增量备份结合起来。这样做的好处是,不存储每日备份的快照,而只存储与前一天的差异。

这样你就有了修订控制的优势,也不会浪费太多的空间。

在任何情况下,直接在频繁更改的大平面文件上使用git都不是一个好的解决方案。如果数据库变得太大,git在管理文件时会出现一些问题。

在git版本控制下存储每个级别的数据库更改就像每次提交时推送整个数据库,每次拉取时恢复整个数据库。 如果您的数据库很容易发生重大更改,并且您无法承担丢失它们的代价,那么您可以更新pre_commit和post_merge钩子。 我对我的一个项目也做了同样的事情,你可以在这里找到方向。

从本质上讲,您想要的可能是类似Post - Facto的东西,它将数据库的版本存储在数据库中。检查这个演示。

这个项目显然没有任何进展,所以它可能不会马上帮到你,但这是一个有趣的概念。我担心正确地做到这一点会非常困难,因为即使是版本1也必须获得所有的细节,以便让人们信任他们的工作。

以下是我在项目中尝试做的事情:

分离数据、模式和默认数据。

数据库配置存储在不受版本控制的配置文件中(.gitignore)

数据库默认值(用于设置新项目)是一个受版本控制的简单SQL文件。

对于数据库模式,在版本控制下创建数据库模式转储。

最常见的方法是使用包含SQL语句的更新脚本(ALTER Table..或更新)。你还需要在你的数据库中有一个地方来保存你的模式的当前版本)

看看其他大型开源数据库项目(piwik,或者你最喜欢的cms系统),它们都使用updatescripts (1.sql,2.sql,3.sh,4.php.5.sql)

但这是一项非常耗时的工作,您必须创建并测试更新脚本,还需要运行一个通用的更新脚本来比较版本并运行所有必要的更新脚本。

所以理论上(这就是我正在寻找的)你可以 在每次更改后转储数据库模式(手动,conjob, git钩子(可能在提交之前)) (只有在一些非常特殊的情况下才创建更新脚本)

之后,在您的普通updatescript中(对于特殊情况,运行正常的updatescript),然后比较模式(转储和当前数据库),然后自动生成必要的ALTER语句。已经有一些工具可以做到这一点,但还没有找到一个好的工具。