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

3
我正在尝试在我们的php/mysql应用程序开发过程中实现git。到目前为止,我们已经设置了git仓库,并且我们正在使用本地机器进行测试并成功地将其用于文件,但我不知道如何处理数据库?
服务器上有一个cron脚本将最新版本的线上数据库导出并提交到仓库中,我已经在我的开发机器上设置了post-merge钩子来更新我的本地数据库,并且这对于从线上同步到测试的方向工作良好。
我不知道如何使同步双向工作。目前我正在在线上服务器上更改数据库,但我认为这不是一个好的做法。
所以我非常乐意听取建议。
编辑:在我理解模式迁移工作方式之前,我提出了这个问题。现在,我大多数的web开发工作都使用django,它有一个名为South的很棒的迁移模块(从1.7版本开始成为django核心的一部分)。因此,大多数MVC框架都应该具有处理此问题的迁移模块。
1个回答

4
如果你想对实现在扁平文件中的完整数据库进行版本控制,我建议使用sqlite后端。
如果你的应用程序需要MySQL(例如某些过程或视图),那么请版本控制数据库操作脚本(例如CREATEALTER)和填充脚本(例如INSERT),并将其作为构建过程的一部分运行。推荐采用dbdeploy模式
更新评论的流程:
你基本上是把生产环境当做模式的主版本。如果你有多个主版本怎么办?如果你的数据库变得太大而无法有效地完成这个任务怎么办?如果你需要隔离一个旧版本代码中的错误,回滚到特定的代码/模式状态有多容易?
十年前,我也曾经做过这件事情。 我有一个小型数据库——大约十几张表。应用程序不断发展。 现在它有2000个表了。考虑我是一个来自未来的鬼魂,警告你避免我经历过的痛苦。
建议:
理论上这个过程很简单:在开发中进行数据库更改,将其应用于生产环境,完成。现实要困难得多。我将通过例子来解释我的意思...
你是开发团队的一部分。 你想添加禁用账户的支持。除了代码更改之外,你决定将其实现为数据库中的位字段,如下所示: ALTER TABLE Account ADD COLUMN disabled BIT(1) DEFAULT 0; 现在像我上面提到的那样,你将这个内容放在版本控制文件中,让我们称其为addDisabledColumnToAccount.sql。你提交SQL和代码更改并推送它们。
其他团队成员获得你的更改,应用模式更改并进行测试。你们共同决定扩大更改的原始范围以支持账户状态,而不仅仅是禁用。所以你做了这个:
ALTER TABLE Account DROP COLUMN disabled;
ALTER TABLE Account ADD COLUMN status ENUM('active','disabled','closed') NOT NULL DEFAULT 'active';

并提交更改,然后推送。每个人都重新应用并感到满意。你将其推入你的主干(或标记为稳定的位置),它已经准备好进入生产环境了。
好的。你能发现问题吗?有几个问题。第一个主要问题是,如果你尝试在生产环境上运行此脚本,它将失败。为什么?因为生产环境从未添加“disabled”列。
总体问题是,开发数据库经历了中间变化,而生产环境不需要/可能不需要经历这些变化。有很多方法可以解决这个问题。我喜欢的方法是保持两个变更脚本的跟踪:开发和生产。开发脚本是累积的,随着开发的进行而增加变化 - 生产脚本代表开发的最终结果。它们都让数据库以相同的状态结束,这意味着你对任何一个最终测试都应该通过。
还有哪些问题?开发人员可能会给两个脚本文件取相同的名称。所以你必须建立一些标准来防止脚本名称冲突。通常,如果脚本名称与某个唯一的问题ID相关联,那就可以解决这个问题。
另一个问题是,每个模式更改脚本可能会有一个MySQL版本,一个SQLite版本,一个Oracle版本等。你支持的数据库越多,就必须处理越多的模式更改。在命名脚本时要记住这一点。类似于addColumnToTable.mysql.sql、addColumnToTable.sqlite.sql等。
最后,你必须确保模式更改与相应的代码更改同时应用。我的意思是通常代码和数据库更改是相辅相成的。只要你的部署技术让你同时应用两者,并且 - 更重要的是 - 如果有问题回滚两者,那么你就没问题了。但这种自动化水平可能很难,手动操作容易出错。
总之,Git将帮助你跟踪你的更改,并帮助你协作创建模式更改。但它并不是特别适合部署工具,因为处理随时间变化的模式更改的复杂性。

1
哇,感谢你详细的回答,你确实指出了一个有趣的问题。 - Martin Taleski
不用谢!我在编辑中添加了一些小细节。祝你好运! - bishop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接