1. 程式人生 > >shell指令碼實現mysql資料庫表和表結構的對比

shell指令碼實現mysql資料庫表和表結構的對比

在專案維護和開發中,經常需要知道兩個資料庫之間有哪些差異,如兩個資料庫中資料表有什麼不同(表的名稱,數量),相同的表字段是否相同(欄位數目,約束,欄位型別,大小等),有各種資料庫管理工具可以實現這一點,但是別人的東西用起來總是沒有自己的順手(比如有的工具直接生成了修改的sql語句),鑑於此原因,決定自己寫個簡單的shell指令碼來實現這個功能。
思想:比較兩個庫A、B中資料表的不同,可以對兩個庫分別使用show tables指令,將表名形成兩個臨時檔案,然後遍歷其中一個臨時檔案的行,同時在另外一個臨時檔案中搜索該表名,如果找到說明兩個資料庫中都有這張表,同時將這個表名放入到新的臨時檔案,作為後面欄位對比的依據。欄位對比使用desc 表名(這裡的表名是上面挑選出來的相同的表名)的方式進行。下面通過程式碼來進行說明。
#!bin/sh
#資料庫A的屬性
DB1_NAME=test1
DB1_HOST=192.168.0.1
DB1_USER=root
DB1_PWD=test
#資料庫B的屬性
DB2_NAME=test2
DB2_HOST=192.168.0.2
DB2_USER=root
DB2_PWD=test
#資料庫比較結果的存放位置
DIFFERENT_TABLES_FILE=/home/different_tables.txt
DIFFERENT_COLUMNS_FILE=/home/different_columns.txt
TEMP_FILE_URL=/home/temp
SAME_RESULT_TEMP=${TEMP_FILE_URL}
/same_result_temp.txt #首先定義一個函式方便後面的比較 ############## # 引數1:臨時檔案1,作為比較的基準進行遍歷 # 引數2:臨時檔案2,在這個檔案裡邊搜尋檔案1中的表名 # 引數3:存放不同表名的結果檔案 # 引數4:存放相同表名的臨時檔案 ############## compareTables(){ i=2 #從第二行開始遍歷 while read line do row=$i nameA=$(awk 'NR=='$row' {print $0}' $1) #從臨時檔案1中遍歷取出資料庫A的每一個表名
nameB=$(grep -w -i "$nameA" $2) #在臨時檔案2中搜索這個表名 if [ -z "$nameB" ]; then echo "$nameA">>$3 else if [ $nameA = $nameB ] ; then if [ -f $4 ]; then same_name=$(grep -w -i "$nameA" $4) fi if [ -z "$same_name" ]; then echo "$nameA">>$4 fi else echo "$nameA">>$3 fi fi : $((i++)) done<$1 } ##開始比較兩個資料庫表的不同 echo "start...compare...tables" #首先使用show tables獲得兩個庫中所有的表的名稱,放到臨時檔案 fileA=${TEMP_FILE_URL}/temp_dbA.txt fileB=${TEMP_FILE_URL}/temp_dbB.txt mysql -h${DB1_HOST} -u${DB1_USER} -p${DB1_PWD} -e"use ${DB1_NAME};show tables;">fileA mysql -h${DB2_HOST} -u${DB2_USER} -p${DB2_PWD} -e"use ${DB2_NAME};show tables;">fileB #呼叫函式進行對比 cd $TEMP_FILE_URL rm -rf $SAME_RESULT_TEMP echo "Those tables are unique in ${DB1_NAME}:">${DIFFERENT_TABLES_FILE} compareTables $fileA $fileB $DIFFERENT_TABLES_FILE $SAME_RESULT_TEMP echo "Those tables are unique in ${DB2_NAME}:">>${DIFFERENT_TABLES_FILE} compareTables $fileB $fileA $DIFFERENT_TABLES_FILE $SAME_RESULT_TEMP echo "compare...tables...end" ##開始比對兩個資料庫之間相同表名欄位之間的不同 echo "compare...column...start" rm -rf ${DIFFERENT_COLUMNS_FILE} compareColumns(){ while read line do table_line=$line map_line=$(grep -w -i "$table_line" $2) if [ -z "$map_line" ];then echo "$table_line">>$3 fi done<$1 } #呼叫函式得出結果,此處需要遍歷剛開始得到的相同表名的檔案 while read line do table_name=$line table_desc1=${TEMP_FILE_URL}/table_desc1.txt table_desc2=${TEMP_FILE_URL}/table_desc2.txt echo "the comparing table name is $table_name" mysql -h${DB1_HOST} -u${DB1_USER} -p${DB1_PWD} -e"use ${DB1_NAME};desc ${table_name}">${table_desc1} mysql -h${DB2_HOST} -u${DB2_USER} -p${DB2_PWD} -e"use ${DB2_NAME};desc ${table_name}">${table_desc2} echo "different columns in ${DB1_NAME}.${table_name}">>${DIFFERENT_COLUMNS_FILE} compareColumns ${table_desc1} ${table_desc2} ${DIFFERENT_COLUMNS_FILE} echo "different columns in ${DB2_NAME}.${table_name}">>${DIFFERENT_COLUMNS_FILE} compareColumns ${table_desc2} ${table_desc1} ${DIFFERENT_COLUMNS_FILE} done<${SAME_RESULT_TEMP} echo "compare...column...end" ##最後,清理臨時資料 cd ${TEMP_FILE_URL} rm -rf *

至此,指令碼完成。