运维人

如何实现mysql数据库差异化对比

在团队开发中,一般都会存在测试、预发布、正式环境或多版本进行开发;代码的管理一般也有git/svn等等工具;

但是在mysql的管理就有些麻烦了,对于一些正规化的大厂团队,对数据库的每一次表结构都有详细的记录,这样在执行变更/升级的时候只需要执行直接执行变更过的SQL即可,但是有时候也会出现记录不完整或者遗漏造成测试/预发布/正式环境的不一致。

这时候就需要人工去查找两个数据库数据表中的不同;看哪里少什么,哪里多了什么,但是如果人工去每次desc/select是很费时费力的事情;那么这时候我们就需要用到mysql的相关工具;例如mysqldiff

例如:

这里有个db1db2 数据库,各自里面有两张表student_1,student2,这里只是举个例子,下面的结构用肉眼是可以看出来的;

MariaDB [(none)]> use db1;
Database changed
MariaDB [db1]> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| student_1     |
+---------------+
1 row in set (0.00 sec)

MariaDB [db1]> desc student_1;
+-------------+-------------+------+-----+---------+-------+
| Field       | Type        | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| studentNo   | char(10)    | NO   | PRI | NULL    |       |
| studentName | varchar(20) | NO   |     | NULL    |       |
| sex         | char(2)     | YES  |     | NULL    |       |
| birthday    | date        | YES  |     | NULL    |       |
| native      | varchar(20) | YES  |     | NULL    |       |
| nation      | varchar(20) | YES  |     | NULL    |       |
| classNo     | char(6)     | YES  |     | NULL    |       |
+-------------+-------------+------+-----+---------+-------+
7 rows in set (0.01 sec)

MariaDB [db1]> use db2;
Database changed
MariaDB [db2]> desc student_2;
+-------------+-------------+------+-----+---------+-------+
| Field       | Type        | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| studentNo   | char(10)    | NO   | PRI | NULL    |       |
| studentName | varchar(20) | NO   |     | NULL    |       |
| sex         | char(2)     | YES  |     | NULL    |       |
| birthday    | date        | YES  |     | NULL    |       |
| native      | varchar(40) | YES  |     | NULL    |       |
| nation      | varchar(20) | YES  |     | NULL    |       |
+-------------+-------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

MariaDB [db2]>

如果使用mysqldiff工具输出将会是这样的:
mysqldiff --server1=root:123.com@127.0.0.1:3306 --server2=root:123.com@127.0.0.1:3306   db1.student_1:db2.student_2;
# WARNING: Using a password on the command line interface can be insecure.
# server1 on 127.0.0.1: ... connected.
# server2 on 127.0.0.1: ... connected.
# Comparing db1.student_1 to db2.student_2                         [FAIL]
# Object definitions differ. (--changes-for=server1)
#

--- db1.student_1
+++ db2.student_2
@@ -1,10 +1,9 @@
-CREATE TABLE `student_1` (
+CREATE TABLE `student_2` (
   `studentNo` char(10) NOT NULL,
   `studentName` varchar(20) NOT NULL,
   `sex` char(2) DEFAULT NULL,
   `birthday` date DEFAULT NULL,
-  `native` varchar(20) DEFAULT NULL,
+  `native` varchar(40) DEFAULT NULL,
   `nation` varchar(20) DEFAULT NULL,
-  `classNo` char(6) DEFAULT NULL,
   UNIQUE KEY `studentNo` (`studentNo`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
# Compare failed. One or more differences found.

从以上输出可以看出来, db2student_2相对于db1student_1结构
1.字段native的vachar类型限制不同;表student_2是40,表student_1是40;
2.表student_2缺少字段classNo

这样一来就能很快速的输出两个库中表结构的差异;然后看以那个库为标杆进行Alert操作就行了
下面是我改正后再次执行mysqldiff工具命令的结果输出:

mysqldiff --server1=root:123.com@127.0.0.1:3306 --server2=root:123.com@127.0.0.1:3306   db1.student_1:db2.student_2;
# WARNING: Using a password on the command line interface can be insecure.
# server1 on 127.0.0.1: ... connected.
# server2 on 127.0.0.1: ... connected.
# Comparing db1.student_1 to db2.student_2                         [PASS]
# WARNING: The tables structure is the same, but the columns order is different. Use --change-for to take the order into account.
# Success. All objects are the same.

意思就是说检测通过,看起来所有的对象都是一样的。

So, 简单使用方法就是酱紫的了;其实还有更多的选项就行操作的;但是目前暂时没有用到;需要的话找man就好了。

    分享到:
码字很辛苦,转载请注明来自运维人《如何实现mysql数据库差异化对比》

评论