tyaga / php-mysql-diff
Requires
- php: >5.6||>7.1
- symfony/console: ~3.0|~4.0|~5.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2
- phpunit/phpunit: ^8.5
README
MySQL Schema Diff - 对比/迁移脚本生成
为什么不是 MySQL Utilities 中的 mysqldiff 呢?
MySQL Utilities 包含一个类似的工具 mysqldiff,但它非常 糟糕!这个项目的目的是提供一个简单易用、可靠且快速的工具。
安装
要安装 PHP MySQL Diff,请安装 Composer 并执行以下命令
$ ./composer.phar global require camcima/php-mysql-diff
然后,确保 ~/.composer/vendor/bin 在您的 PATH 中,您就可以开始了
export PATH="$PATH:$HOME/.composer/vendor/bin"
更新
您可以通过以下命令更新 PHP MySQL Diff
$ ./composer.phar global update camcima/php-mysql-diff
用法
数据库创建脚本
PHP MySQL Diff 与由 MySQL 发行版中的 mysqldump 创建的数据库创建脚本一起工作。要生成数据库创建脚本,请使用以下命令
$ mysqldump -h hostname -u username -p -d dbname > outputfile.sql
由于这个工具依赖于对文件格式进行了精确调整的正则表达式,因此它可能无法处理由其他方式生成的创建脚本。
我选择与数据库创建脚本一起工作,而不是直接连接到数据库,因为这样更易于移植,并且可以离线工作。在未来,我可能会开发从数据库的 INFORMATION_SCHEMA 表中直接获取信息的选项。
对比
$ php-mysql-diff diff <from> <to> [-i <ignore-tables-file>]
其中 from 是初始数据库创建脚本的路径,to 是目标数据库创建脚本的路径。
忽略表
使用 -i 选项在对比过程中忽略表。文件格式是匹配要忽略的表名的正则表达式列表,每行一个。
示例
/^employee.+/
/^catalog$/
/^test[\d]$/
输出文件
输出将如下所示
PHP MySQL Diff 1.0.0
----------------------------------------
• Parsing initial database ...... ✓
• Parsing target database ....... ✓
• Comparing databases ........... ✓
FROM tests\fixtures\sakila.sql
TO tests\fixtures\sakila_new.sql
▲ table "test3" is in the TO database but not in the FROM database
▼ table "test1" is in the FROM database but not in the TO database
► table "test2" has a different schema
▲ column "new_field" is in the TO database but not in the FROM database
► column "id" has a different definition
FROM `id` int(11) NOT NULL AUTO_INCREMENT
TO `id` int(10) NOT NULL AUTO_INCREMENT
► column "fk" has a different definition
FROM `fk` int(10) NOT NULL
TO `fk` int(10)
► column "val" has a different definition
FROM `val` decimal(10,2) NOT NULL
TO `val` decimal(11,3) NOT NULL
► column "texto" has a different definition
FROM `texto` varchar(60) DEFAULT NULL
TO `texto` char(60) NOT NULL DEFAULT 'default'
► primary key has a different definition
FROM PRIMARY KEY (`id`)
TO PRIMARY KEY (`id`,`new_field`)
▲ foreign key "FK__test3" is in the TO database but not in the FROM database
▼ foreign key "FK__test1" is in the FROM database but not in the TO database
► index "FK__test1" has a different definition
FROM KEY `FK__test1` (`fk`)
TO UNIQUE KEY `FK__test1` (`datade`)
Diff completed!
▲ = 仅在目标数据库中存在
► = FROM 和 TO 数据库之间的定义不同
▼ = 仅在 FROM 数据库中存在
迁移脚本
$ php-mysql-diff migrate <from> <to> [-o <output-file>] [-i <ignore-tables-file>] [-p]
其中 from 是初始数据库创建脚本的路径,to 是目标数据库创建脚本的路径。
忽略表
使用 -i 选项在对比过程中忽略表。文件格式是匹配要忽略的表名的正则表达式列表,每行一个。
示例
/^employee.+/
/^catalog$/
/^test[\d]$/
输出文件
如果不使用 -o 选项,迁移脚本将输出到 stdout。
使用 -o 选项的输出将如下所示
PHP MySQL Diff 1.0.0
----------------------------------------
• Parsing initial database ...... ✓
• Parsing target database ....... ✓
• Comparing databases ........... ✓
• Generating migration script ... ✓
• Writing output file ........... ✓
Migration script generated!
迁移脚本将如下所示
# Disable Foreign Keys Check SET FOREIGN_KEY_CHECKS = 0; SET SQL_MODE = ''; # Deleted Tables -- deleted table `test1` DROP TABLE `test1`; # Changed Tables -- changed table `test2` ALTER TABLE `test2` DROP PRIMARY KEY, DROP FOREIGN KEY `FK__test1`, DROP INDEX `FK__test1`, CHANGE COLUMN `id` `id` int(10) NOT NULL AUTO_INCREMENT FIRST, CHANGE COLUMN `fk` `fk` int(10) AFTER `id`, CHANGE COLUMN `val` `val` decimal(11,3) NOT NULL AFTER `fk`, CHANGE COLUMN `texto` `texto` char(60) NOT NULL DEFAULT 'default' AFTER `val`, ADD COLUMN `new_field` int(10) AFTER `datade`, ADD PRIMARY KEY (`id`,`new_field`), ADD UNIQUE KEY `FK__test1` (`datade`), ADD CONSTRAINT `FK__test3` FOREIGN KEY (`fk`) REFERENCES `test3` (`id`); # New Tables -- new table `test3` CREATE TABLE `test3` ( `id` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; # Disable Foreign Keys Check SET FOREIGN_KEY_CHECKS = 1;
显示进度
对于长时间运行的迁移,建议使用 -p 选项来显示正在运行的迁移的进度。
贡献
请随时通过 PR 发送您的贡献。请确保更新/编写新的测试来支持您的贡献。请遵循 PSR-2。