项目上不同环境发版需要对比表结构差异,为此经常需要手动点击 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 3 天前
之前用过这个工具 https://www.skeema.io
很适合在几个环境之间同步表结构 |