你如何为你的数据库模式进行版本控制?

137

你是如何准备你的SQL差分文件的?你是手动保存每个改变模式的SQL到一个差分文件夹中,还是有一些自动化的差分过程?

我对将数据库模式版本化的惯例很感兴趣。也许有一个预提交钩子来进行模式差异比较?

此外,除DbDeploy之外,还有什么差分差异选项可用呢?

编辑:看到答案后,我想澄清一下,我熟悉使用差分文件运行数据库迁移的标准方案。我的问题是关于自动生成差分文件,最好是自动化的。

另外,如果涉及到PHP和MySQL,则与Ruby解决方案无关。


我使用schemasync来生成补丁(以及回滚脚本)。这些被添加到SVN存储库中。虽然不是完美的,但对我来说效果很好。另外,使用schemasync轻松部署模式更改。 - Jay Sidri
这个链接似乎是空的 - 这个还存在吗? - jocull
似乎已经移动了:https://github.com/mmatuson/SchemaSync - Jay Sidri
16个回答

66

从我的问题中可以看出,我了解增量的概念。我的问题是关于创建增量的惯例,最好是自动化的。 - Eran Galperin
我想我会自己动手做... ;) - Eran Galperin
你试过使用DBDiff: https://github.com/DBDiff/DBDiff 吗?对于你@EranGalperin所寻找的,它非常适合,因为它可以自动迁移SQL中的模式和数据。_声明_我是其背后的开发人员! - Jasdeep Khalsa

4
如果您仍在寻找选项:请看neXtep designer。它是一个基于版本控制概念的免费GPL数据库开发环境。在该环境中,您始终使用版本化实体,并可以专注于数据模型开发。一旦发布完成,插入到版本控制系统上的SQL生成引擎可以生成您需要的任何两个版本之间的差异,并且如果需要,将为您提供一些交付机制。
此外,您可以在开发过程中同步和反向同步您的数据库,创建数据模型图,使用集成SQL客户端查询数据库等。
请查看维基获取更多信息: http://www.nextep-softwares.com/wiki 它目前支持Oracle、MySql和PostgreSql,并且是用Java编写的,因此该产品可以在Windows、Linux和Mac上运行。

4

3
我保证模式更改始终是增量的。因此,我不会删除列和表,因为这将清除数据并且无法回滚。这样,使用数据库的代码可以回滚而不会丢失数据或功能。
我有一个迁移脚本,其中包含如果尚不存在则创建表和列的语句,并填充数据。
迁移脚本在每次生产代码更新后和新安装后运行。
当我想要删除某些内容时,我通过从数据库安装脚本和迁移脚本中删除它们来实现,因此这些过时的模式元素将逐渐淘汰在新安装中。缺点是新安装无法降级到旧版本之前的安装。
当然,我通过这些脚本执行DDL,而不是直接在数据库上执行,以保持同步。

3
我不管理增量。我对主数据库进行更改,并使用一个工具创建基于主数据库的基于XML的构建脚本。
在升级现有数据库时,我有一个程序,它使用基于XML的构建脚本创建新数据库和裸表。然后我使用“INSERT INTO x SELECT FROM y”将数据从旧数据库复制过来,然后应用所有索引、约束和触发器。
新表、新列、删除的列都会自动处理,通过一些小技巧调整复制例程,我可以处理列重命名、列类型更改和其他基本重构。
我不建议在具有大量数据的数据库上使用此解决方案,但我经常更新一个拥有400个表且超过1GB的数据库。

这听起来有些繁琐,特别是在处理多个开发人员时。此外,构建过程听起来很费力,我希望尽可能简单。 - Eran Galperin
我承认这需要一些时间来做到完美,但现在几乎不需要任何努力就可以准备升级,执行升级的工作量也更少了。另外,我喜欢的一点是,我可以进行临时热修复更改,而这不会对升级过程产生影响。每次升级都是一个全新的数据库。 - Darrel Miller

2

2
我不是那种自吹自擂的人,但我开发了一个内部网络应用程序来跟踪数据库模式的变化并创建版本化的更新脚本。
这个工具被称为Brazil,现在已经在 MIT 许可下开源。Brazil 基于 Ruby / Ruby on Rails,并支持对任何 Ruby DBI 支持的数据库进行更改部署(MySQL、ODBC、Oracle、Postgres、SQLite)。
计划支持将更新脚本放入版本控制中。

巴西看起来挺不错,可惜我主要使用 PHP。你有没有考虑过移植系统? - Eran Galperin

2

您没有提到使用哪种关系型数据库管理系统,但如果是MS SQL Server,Red-Gate的SQL Compare在我们创建对象创建脚本之间的差异方面非常重要。


1
这是针对Mysql的,我已经更新了我的问题。 - Eran Galperin

1

针对MySQL的操作

当我进入一个新的数据库时:

首先,我会检查其结构:

mysqldump --no-data --skip-comments --skip-extended-insert -h __DB_HOSTNAME__ -u __DB_USERNAME__ -p __DB1_NAME__ | sed 's/ AUTO_INCREMENT=[0-9]*//g' > FILENAME_1.sql
mysqldump --no-data --skip-comments --skip-extended-insert -h __DB_HOSTNAME__ -u __DB_USERNAME__ -p __DB2_NAME__ | sed 's/ AUTO_INCREMENT=[0-9]*//g' > FILENAME_2.sql
diff FILENAME_1.sql FILENAME_2.sql > DIFF_FILENAME.txt
cat DIFF_FILENAME.txt | less

Thanks to stackoverflow users I could write this quick script to find structure differences.

src : https://dev59.com/43VC5IYBdhLWcg3wpS3g#8718572 & https://dev59.com/vWUo5IYBdhLWcg3w7jEq#26328331

在第二步中,我使用mysqldiff逐表检查数据。虽然有点古老,但基于information_schema数据的php循环可以确保工作顺利。
对于版本控制,我使用相同的方法,但使用差异结果格式化SQL更新脚本(用于升级或回滚),并使用版本号约定(通过几个修改使版本号看起来像IP地址)
initial version : 1.0.0
                  ^ ^ ^
                  | | |
structure change: - | |
datas added: -------- |
datas updated: --------

1

我还开发了一套PHP脚本集,让开发人员可以将他们的deltasql脚本提交到一个中央代码库中。

在一个名为TBSYNCHRONIZE的数据库表中,我存储了最新执行脚本的版本号,因此我可以使用Web界面或为Eclipse专门开发的客户端轻松升级任何数据库。

Web界面允许管理多个项目。它还支持数据库“分支”。

您可以通过http://www.gpu-grid.net/deltasql(如果您以密码testdbsync登录管理员帐户)测试该应用程序。 该应用程序是开源的,可在此处下载: http://sourceforge.net/projects/deltasql

deltasql已经在瑞士和印度投入生产,并在日本很受欢迎。


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