有人用 mysqldiff 吗?只能说勉强能用吧,有没有更好的工具?

2016-05-27 00:41:21 +08:00
 tusj

工作上经常需要对比不同环境数据库表结构差异。 用 mysqldiff 试了一下,功能基本可以满足, 但还是发现了一些问题。


use `test`;
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
  `id` bigint(20) DEFAULT NULL,
  `v1` varchar(64) DEFAULT NULL,
  `v2` varchar(64) DEFAULT NULL,
  `v3` varchar(64) DEFAULT NULL,
  `v4` varchar(64) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `t2`;
CREATE TABLE `t2` (
  `id` bigint(20) DEFAULT NULL,
  `v4` varchar(64) DEFAULT NULL,
  `v1` varchar(64) DEFAULT NULL,
  `v2` varchar(64) DEFAULT NULL,
  `v3` varchar(64) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

假设 test.t1 是正确的,需要修改 test.t2,手动写出来的 DDL 肯定都这样写,一目了然:

ALTER TABLE `test`.`t2` CHANGE COLUMN v4 v4 varchar(64) NULL AFTER v3;

但通过 mysqldiff 跑出来的结果却复杂很多:

$ time mysqldiff --server1=root:root@localhost:3306 --difftype=sql --changes-for=server2 --show-reverse test.t1:test.t2
# WARNING: Using a password on the command line interface can be insecure.
# server1 on localhost: ... connected.
# Comparing test.t1 to test.t2                                     [FAIL]
# Transformation for --changes-for=server2:
#

ALTER TABLE `test`.`t2` 
  CHANGE COLUMN v1 v1 varchar(64) NULL AFTER id, 
  CHANGE COLUMN v2 v2 varchar(64) NULL AFTER v1, 
  CHANGE COLUMN v3 v3 varchar(64) NULL AFTER v2, 
  CHANGE COLUMN v4 v4 varchar(64) NULL AFTER v3;

#
# Transformation for reverse changes (--changes-for=server1):
#
# ALTER TABLE `test`.`t1` 
#   CHANGE COLUMN v1 v1 varchar(64) NULL AFTER v4, 
#   CHANGE COLUMN v2 v2 varchar(64) NULL AFTER v1, 
#   CHANGE COLUMN v3 v3 varchar(64) NULL AFTER v2, 
#   CHANGE COLUMN v4 v4 varchar(64) NULL AFTER id;
#

Compare failed. One or more differences found.

real	0m0.936s
user	0m0.404s
sys	0m0.084s
$ 

同理,如果将 test.t1 变更成 test.t2 也是如此,手动写脚本只需要 1 个 CHANGE 。 而 mysqldiff 需要 4 个 CHANGE 。


虽然 mysqldiff 出来的结果很啰嗦,但并不影响最终效果 所有 CHANGE 都是写在一个 DDL 语句里的,所以即使表里面有大量数据需要迁移,也是一次到位的,不会比手工写的 DDL 差,所以用还是能用。

但就是看着不爽!大量垃圾信息将重点给淹没了,感觉很傻逼。

不知道各位 V 友有没有更好的工具?

或者有啥算法能解决这个问题,以最少的挪动次数来完成 DDL ?


Navicat 我也试过了,生成的脚本不行,比 mysqldiff 糟很多, 4 个 CHANGE 他会给你写出 4 条 DDL ,简直不能再傻逼了!

ALTER TABLE `test`.`t2` CHANGE COLUMN v1 v1 varchar(64) NULL AFTER id;
ALTER TABLE `test`.`t2` CHANGE COLUMN v2 v2 varchar(64) NULL AFTER v1;
ALTER TABLE `test`.`t2` CHANGE COLUMN v3 v3 varchar(64) NULL AFTER v2;
ALTER TABLE `test`.`t2` CHANGE COLUMN v4 v4 varchar(64) NULL AFTER v3;

如果表里数据量大的话,变更的时候会发生 4 次数据拷贝,就等着哭吧!

3717 次点击
所在节点    问与答
1 条回复
tusj
2016-05-27 18:40:38 +08:00
一个回复都没有
看来只得另想办法了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/281561

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX