Mysql 使用git在测试和生产环境之间同步数据库

Mysql 使用git在测试和生产环境之间同步数据库,mysql,database,git,Mysql,Database,Git,我试图在php/mysql应用程序的开发过程中实现git 到目前为止,我已经建立了git repos,我们正在使用本地机器进行测试,我们正在成功地将其用于文件,但我真的不知道如何处理数据库 服务器上有一个cron脚本,可以导出新版本的实时数据库并将其提交给repo,我在开发机器上设置了一个post-merge钩子来更新本地数据库,它可以很好地在生产->测试方向上进行同步 我不知道如何以另一种方式进行同步。目前,我正在对live server上的数据库进行更改,但我认为这不是一个好的做法 所以我愿

我试图在php/mysql应用程序的开发过程中实现git

到目前为止,我已经建立了git repos,我们正在使用本地机器进行测试,我们正在成功地将其用于文件,但我真的不知道如何处理数据库

服务器上有一个cron脚本,可以导出新版本的实时数据库并将其提交给repo,我在开发机器上设置了一个post-merge钩子来更新本地数据库,它可以很好地在生产->测试方向上进行同步

我不知道如何以另一种方式进行同步。目前,我正在对live server上的数据库进行更改,但我认为这不是一个好的做法

所以我愿意接受建议


编辑:在我理解模式迁移如何工作之前,我问了这个问题。我现在大部分的web开发工作都使用django,它有一个很棒的名为South的迁移模块(版本1.7中django核心的一部分)。因此,大多数MVC框架都应该有一个迁移模块来处理这个问题。

大多数数据库都有数据库复制功能。在我看来,这比使用git更适合于数据库同步。

如果您想对在平面文件中实现的完整数据库进行版本控制,我建议使用后端

如果您的应用程序需要MySQL(例如某些过程或视图),则版本控制数据库操作脚本(例如
CREATE
ALTER
)和填充脚本(例如
INSERT
),并将其作为构建过程的一部分运行

更新以对现有程序进行评论
实际上,您将产品视为模式的主副本。如果有多个主控会发生什么?当数据库变得太大而无法有效执行此操作时,会发生什么情况?如果您需要在旧版本的代码中隔离一个bug——回滚到特定的代码/模式状态有多容易

十年前,我做了这件事。我有一个小数据库--十几个表左右。应用程序已经增长。它现在有2000张桌子。把我当作圣诞节的幽灵,警告你远离我所经历的痛苦。

推荐
从理论上讲,这个过程很简单:在开发中更改数据库,将这些更改应用到生产中,然后完成。现实要困难得多。我会用例子来解释我的意思

您是开发团队的一员。您想添加对禁用帐户的支持。除了代码更改之外,您还决定将其作为数据库中的一个位字段来实现,如下所示:

ALTER TABLE Account ADD COLUMN disabled BIT(1)默认为0

现在就像我上面提到的,你把它放在一个版本控制下的文件中,我们称之为
addDisabledColumnToAccount.sql
。您可以提交SQL和代码更改并推送它们

其他团队成员获取您的更改,应用模式更改,并对其进行测试。所有人共同决定增加更改的原始范围,以支持帐户的状态,而不仅仅是禁用。所以你要这样做:

ALTER TABLE Account DROP COLUMN disabled;
ALTER TABLE Account ADD COLUMN status ENUM('active','disabled','closed') NOT NULL DEFAULT 'active';
提交您的更改并推送。每个人都重新应用了这个,并且都很高兴。你把它塞进你的后备箱(或者不管你怎么标记稳定),它就可以投入生产了

嗯。你能发现问题吗?有几个。第一个主要问题是,如果您尝试在生产环境中运行此脚本,它将失败。为什么?因为生产从未添加“禁用”列

一般的问题是开发数据库会经历生产不需要/可能不需要经历的临时更改。有很多方法可以解决这个问题。我喜欢这样做的方式是保持变更脚本的两条轨道:开发和生产。开发脚本是累积的,随着开发的进行不断增加变化——生产脚本代表开发的最终结果。它们都使数据库以相同的状态结束,这意味着您对其中一个的最终测试都应该通过

还有什么其他问题?开发人员可能会将两个脚本文件命名为相同的名称。因此,您必须建立一些标准,以防止脚本名称发生冲突。通常,如果脚本名称与某个唯一的问题ID相关联,就可以了

另一个问题是,每个模式更改脚本可能有MySQL版本、SQLite版本、Oracle版本等。支持的数据库越多,需要处理的模式更改就越多。在命名脚本时请记住这一点。类似于
addColumntTable.mysql.sql
addColumntTable.sqlite.sql
,等等

最后,您必须确保在应用相应代码更改的同时应用模式更改。我想说的是,通常代码和数据库更改是同时进行的。只要您的部署技术允许您同时应用这两种技术,并且重要的是--在出现问题时回滚这两种技术,您就可以了。但这种自动化程度可能很难,而且手工操作很容易出错


总之,git将帮助您跟踪更改,并帮助您协同创建对模式的更改。但它并不是一个特别的部署工具,因为处理模式随时间变化的复杂性。

哇,感谢您详细的回答,您确实指出了一个有趣的问题,欢迎您!我在编辑中又添加了一些小细节。祝你好运