在開發及調試的過程中,需要比對新舊代碼的差異,我們可以使用git/svn等版本控制工具進行比對。而不同版本的資料庫表結構也存在差異,我們同樣需要比對差異及擷取更新結構的sql語句。
例如同一套代碼,在開發環境正常,在測試環境出現問題,這時除了檢查伺服器設定,還需要比對開發環境與測試環境的資料庫表結構是否存在差異。找到差異後需要更新測試環境資料庫表結構直到開發與測試環境的資料庫表結構一緻。
我們可以使用mysqldiff工具來實作比對資料庫表結構及擷取更新結構的sql語句。
1.mysqldiff安裝方法
mysqldiff工具在mysql-utilities軟體包中,而運作mysql-utilities需要安裝依賴mysql-connector-python
mysql-connector-python 安裝
下載下傳位址:https://dev.mysql.com/downloads/connector/python/
mysql-utilities 安裝
下載下傳位址:https://downloads.mysql.com/archives/utilities/
因本人使用的是mac系統,可以直接使用brew安裝即可。
brew install caskroom/cask/mysql-connector-python
brew install caskroom/cask/mysql-utilities
安裝以後執行檢視版本指令,如果能顯示版本表示安裝成功
mysqldiff --version
MySQL Utilities mysqldiff version
License type: GPLv2
2.mysqldiff使用方法
指令:
參數說明:
--server1 指定資料庫
--server2 指定資料庫
比對可以針對單個資料庫,僅指定server1選項可以比較同一個庫中的不同表結構。
unified (default)
顯示統一格式輸出
context
顯示上下文格式輸出
differ
顯示不同樣式的格式輸出
sql
顯示SQL轉換語句輸出
如果要擷取sql轉換語句,使用sql這種顯示方式顯示最适合。
--character-set 指定字元集
--changes-for 用于指定要轉換的對象,也就是生成差異的方向,預設是server1
--changes-for=server1 表示server1要轉為server2的結構,server2為主。
--changes-for=server2 表示server2要轉為server1的結構,server1為主。
--skip-table-options 忽略AUTO_INCREMENT, ENGINE, CHARSET的差異。
--version 檢視版本
更多mysqldiff的參數使用方法可參考官方文檔:
https://dev.mysql.com/doc/mysql-utilities/1.5/en/mysqldiff.html
3.執行個體
建立測試資料庫表及資料
create database testa;
create database testb;
use testa;
CREATE TABLE `tba` (
`id` int() unsigned NOT NULL AUTO_INCREMENT,
`name` varchar() NOT NULL,
`age` int() unsigned NOT NULL,
`addtime` int() unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8;
insert into `tba`(name,age,addtime) values('fdipzone',,);
use testb;
CREATE TABLE `tbb` (
`id` int() unsigned NOT NULL AUTO_INCREMENT,
`name` varchar() NOT NULL,
`age` int() NOT NULL,
`addtime` int() NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `tbb`(name,age,addtime) values('fdipzone',,);
執行差異比對,設定server1為主,server2要轉為server1資料庫表結構
mysqldiff [email protected] [email protected] --changes-for=server2 --difftype=sql testa.tba:testb.tbb;
# server1 on localhost: ... connected.
# server2 on localhost: ... connected.
# Comparing testa.tba to testb.tbb [FAIL]
# Transformation for --changes-for=server2:
#
ALTER TABLE `testb`.`tbb`
CHANGE COLUMN addtime addtime int() unsigned NOT NULL,
CHANGE COLUMN age age int() unsigned NOT NULL,
CHANGE COLUMN name name varchar() NOT NULL,
RENAME TO testa.tba
, AUTO_INCREMENT=;
# Compare failed. One or more differences found.
執行mysqldiff傳回的更新sql語句
mysql> ALTER TABLE `testb`.`tbb`
-> CHANGE COLUMN addtime addtime int() unsigned NOT NULL,
-> CHANGE COLUMN age age int() unsigned NOT NULL,
-> CHANGE COLUMN name name varchar() NOT NULL;
Query OK, rows affected ( sec)
再次執行mysqldiff進行比對,結構沒有差異,隻有AUTO_INCREMENT存在差異
mysqldiff [email protected] [email protected] --changes-for=server2 --difftype=sql testa.tba:testb.tbb;
# server1 on localhost: ... connected.
# server2 on localhost: ... connected.
# Comparing testa.tba to testb.tbb [FAIL]
# Transformation for --changes-for=server2:
#
ALTER TABLE `testb`.`tbb`
RENAME TO testa.tba
, AUTO_INCREMENT=;
# Compare failed. One or more differences found.
設定忽略AUTO_INCREMENT再進行差異比對,比對通過
mysqldiff [email protected] [email protected] --changes-for=server2 --skip-table-options --difftype=sql testa.tba:testb.tbb;
# server1 on localhost: ... connected.
# server2 on localhost: ... connected.
# Comparing testa.tba to testb.tbb [PASS]
# Success. All objects are the same.