项目上不同环境发版需要对比表结构差异,为此经常需要手动点击 Navicat 的表结构同步功能进行数据库比对,生成 create table 、drop table 、alter table 等语句
为了自动化比对,封装了一个命令行版的对比工具,在 shell 脚本中调用,一键输出同步语句。
例如初始情况下 a_chema
和 b_schema
均有如下 ddl:
create table user ( id bigint comment '主键', name varchar(30) null comment '姓名', address varchar(50) null comment '地址', number varchar(20) null comment '编号', height float null comment '身高' ); create table teacher ( name varchar(30) null comment '姓名' ); create index idx_name on user(name); create index idx_multiple_field on user(name, address); create table course ( id bigint primary key auto_increment comment '主键', name varchar(30) null comment '课程名称', teacher varchar(30) null comment '教师', credit float null comment '学分' ); create table pig ( id bigint not null comment '名称', weight bigint not null comment '重量' );
此时对 a_schema
做如下修改:
use a_schema; alter table user modify column id bigint primary key auto_increment not null comment '主键'; alter table user add column age int default 18 null comment '年龄'; alter table user add column create_time datetime not null default current_timestamp comment '创建时间'; alter table user modify column address varchar(100) not null default 'Shanghai' comment '地址'; alter table user change column number phone varchar(20) null comment '电话号码'; alter table user drop column height; alter table user add unique index uk_phone(phone); alter table user drop index idx_name; create table student( id bigint primary key auto_increment comment '主键', no varchar(30) null comment '学号', name varchar(30) null comment '姓名' ); create unique index uk_no on student(no); drop index idx_multiple_field on user; create index idx_multiple_field on user(name, phone); drop table course; alter table user add unique index uk_test(age, create_time); alter table student add index idx_name(name); alter table teacher add COLUMN `id` bigint NOT NULL primary key AUTO_INCREMENT COMMENT '主键' FIRST; alter table pig add unique index uk_id_weight(id, weight); alter table pig modify column id bigint not null primary key auto_increment comment '名称';
执行命令将会对比表结构差异后输出同步语句:
$ ddl-diff \ --original-user root \ --original-password 123456 \ --original-host 127.0.0.1 \ --original-schema a_schema \ --target-user root \ --target-password 123456 \ --target-host 127.0.0.1 \ --target-schema b_schema
use b_schema; CREATE TABLE `student`( `id` bigint(20) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主键', `no` varchar(30) NULL DEFAULT NULL COMMENT '学号', `name` varchar(30) NULL DEFAULT NULL COMMENT '姓名', INDEX `idx_name` (`name`) USING BTREE, UNIQUE INDEX `uk_no` (`no`) USING BTREE); ALTER TABLE `user` DROP INDEX `idx_name`; ALTER TABLE `user` DROP INDEX `idx_multiple_field`; ALTER TABLE `user` ADD COLUMN `phone` varchar(20) NULL DEFAULT NULL COMMENT '电话号码' AFTER `address`; ALTER TABLE `user` ADD COLUMN `age` int(11) NULL DEFAULT 18 COMMENT '年龄' AFTER `phone`; ALTER TABLE `user` ADD COLUMN `create_time` datetime NOT NULL DEFAULT current_timestamp() COMMENT '创建时间' AFTER `age`; ALTER TABLE `user` MODIFY COLUMN `id` bigint(20) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主键' FIRST; ALTER TABLE `user` MODIFY COLUMN `address` varchar(100) NOT NULL DEFAULT 'Shanghai' COMMENT '地址' AFTER `name`; ALTER TABLE `user` DROP COLUMN `height`; ALTER TABLE `user` DROP COLUMN `number`; ALTER TABLE `user` ADD INDEX `idx_multiple_field` (`name`,`phone`) USING BTREE; ALTER TABLE `user` ADD UNIQUE INDEX `uk_test` (`age`,`create_time`) USING BTREE; ALTER TABLE `user` ADD UNIQUE INDEX `uk_phone` (`phone`) USING BTREE; ALTER TABLE `pig` MODIFY COLUMN `id` bigint(20) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '名称' FIRST; ALTER TABLE `pig` ADD UNIQUE INDEX `uk_id_weight` (`id`,`weight`) USING BTREE; ALTER TABLE `teacher` ADD COLUMN `id` bigint(20) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主键' FIRST; DROP TABLE IF EXISTS `course`;
目前存在的缺点有:
MySQL INFORMATION_SCHEMA.COLUMNS
中并未对字符串和函数做区分。一种解决方法是通过将 SHOW CREATE TABLE xxx 的返回结果解析成 AST ,sqlparser crate 就具有这种解析能力); MariaDB 无此问题。INFORMATION_SCHEMA.COLUMNS
没有存储字段 id 。Navicat 、DataGrip 等工具的表结构差异对比都有此问题,所以在执行返回的语句之前,请务必仔细确认之后再执行。如果有小伙伴知道如何解决该问题,欢迎跟帖讨论。![]() | 1 jybox 218 天前 之前用过这个工具 https://www.skeema.io 很适合在几个环境之间同步表结构 |