我正在尝试在php / mysql应用程序的开发过程中实现git。
到目前为止,我已经设置了git repos,我们正在使用我们的本地机器进行测试,我们已成功将其用于文件,但我真的不知道如何处理数据库?
服务器上有一个cron脚本导出并将新版本的实时数据库提交到repo,我在我的开发机器上设置了一个后合并钩子来更新我的本地数据库,这很有效用于同步生产 - >测试。
我不知道如何以相反的方式进行同步。目前我正在对实时服务器上的数据库进行更改,但我认为这不是一个好习惯。
所以我愿意接受建议。
编辑:在我了解架构迁移的工作原理之前,我问了这个问题。我现在正在使用django进行大部分的Web开发工作,它有一个很棒的迁移模块叫做South(django core的一部分来自1.7版本)。因此,大多数MVC框架都应该有一个处理此问题的迁移模块。
答案 0 :(得分:3)
如果您想版本控制在平面文件中实现的完整数据库,我建议使用sqlite后端。
如果您的应用程序需要MySQL(例如某些过程或视图),则版本控制数据库操作脚本(例如CREATE
,ALTER
)和填充脚本(例如INSERT
)并将其作为构建过程的一部分运行。 dbdeploy is a good pattern to follow
更新评论现有程序
您实际上将生产视为架构的主副本。如果你有多个大师会怎么样?当您的数据库太大而无法有效地执行此操作时会发生什么?如果您需要隔离旧版本代码中的错误怎么办 - 回滚到特定代码/架构状态有多容易?
十年前,我做了这件事。我有一个小型数据库 - 十几个表左右。该应用程序已经增长。它现在有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';
并提交您的更改,然后推送。每个人都重新申请这个并且很高兴。你将它推入你的行李箱(或者你标记稳定),它已准备好投入生产。
确定。你能发现问题吗?有几个。第一个主要问题是,如果您尝试在生产中运行此脚本,它将失败。为什么?因为生产从未添加过“禁用”列。
一般问题是开发数据库经历了临时变更,生产不需要/可能不会通过。有很多方法可以解决这个问题。我喜欢这样做的方法是保留两个更改脚本:开发和生产。开发脚本是累积的,随着开发的进行而不断变化 - 生产脚本代表了开发的最终结果。它们都使数据库以相同的状态结束,这意味着你对最后一个的最终测试都应该通过。
还有哪些其他问题?好吧,开发人员可能会将两个脚本文件命名为同一个。因此,您必须建立一些标准,以防止脚本名称发生冲突。通常,如果脚本名称与某个唯一的问题ID相关联,则可以执行此操作。
另一个问题是每个架构更改脚本可能都有MySQL版本,SQLite版本,Oracle版本等。您支持的数据库越多,您需要处理的架构更改就越多。在命名脚本时请记住这一点。类似addColumnToTable.mysql.sql
,addColumnToTable.sqlite.sql
等
最后,您必须确保在应用相应的代码更改的同时应用架构更改。我所说的是,通常代码和数据库的变化是相辅相成的。只要您的部署技术允许您同时应用两者,并且 - 重要的是 - 如果出现问题就回滚,那么您就是好的。但是这种自动化水平很难,而且手工操作很容易出错。
总之,git将帮助您跟踪更改,并帮助您协作地创建对架构的更改。但它并不是特别的部署工具,因为随着时间的推移处理模式的变化很复杂。
答案 1 :(得分:0)
大多数数据库都具有数据库复制功能。在我看来,这比使用git更适合数据库同步。