在mysql運維中,研發同事想對比下兩個不同例項上的資料並找出差異,除主鍵外還需要對比每乙個字段,如何做呢?
第一種方案,寫程式將兩個例項上的每一行資料取出來進行對比,理論可行,但是對比時間較長。
第二種方案,對每一行資料所有字段合併起來,取checksum值,再按照checksum值對比,看著可行,嘗試下。
首先要合併所有欄位的值,選用mysql提供的concat函式,如果concat函式中包含null值,會導致最終結果為null,因此需要使用ifnull函式來替換null值,如:
concat(ifnull(c1,''),ifnull(c2,''))加入表有很多行,手動拼個指令碼比較累,別急,可以使用information_schema.columns來處理:
## 獲取列名的拼接串假設我們有測試表:select
group_concat(
'ifnull(
',column_name,'
,'''')'
)from information_schema.columns
where table_name='
table_name
';
create我們便可以拼接出下面的sql:table
t_test01
( id
int auto_increment primary
key,
c1 int,
c2 int)
select在兩個例項上執行下,然後把結果使用beyond compare對比下,就很容易找出不相同的行以及主鍵idid,md5(concat(
ifnull(id,
''),
ifnull(c1,
''),
ifnull(c2,
''),
)) as
md5_value
from t_test01
對於資料量較大的表,執行出來的結果集也很大,對比起來比較費勁,那就先嘗試縮小結果集,可以將多行記錄的md5值合併起來求md5值,如果最後md5值相同,則這些行相同,如果不同,則證明存在差異,再按照這些行進行逐行對比。
假設我們按照1000行一組來進行對比,如果需要將分組後的結果合併,需要使用group_concat函式,注意在group_concat函式中新增排序保證合併資料的順序, sql如下:
select執行結果為:min(id) as
min_id,
max(id) as
max_id,
count(1) as
row_count,
md5(group_concat(
md5(concat(
ifnull(id,
''),
ifnull(c1,
''),
ifnull(c2,
''),
)) order
byid
))as
md5_value
from
t_test01
group
by (id div 1000)
min_id max_id row_count md5_value當差異資料較少時,即使需要對比上千萬資料,我們可以輕鬆根據根據min_id和max_id來快速定位到哪1000條資料裡存在差異,再進行逐行md5值對比,最終找到差異行。0999
1000
7d49def23611f610849ef559677fec0c
1000
1999
1000
95d61931aa5d3b48f1e38b3550daee08
2000
2999
1000
b02612548fae8a4455418365b3ae611a
3000
3999
1000 fe798602ab9dd1c69b36a0da568b6dbb
最終對比圖:
ps:在使用group_concat時,需要配置mysql變數group_concat_max_len
,預設值為1024,超出部分會被階段。
提前祝各位春節快樂
MySQL 如何快速對比資料?
我們在mysql中想要對比下兩個不同的例項上的資料並且找出差異,除了主鍵之外我們還要對比每乙個字段,應該怎麼做呢?方案一 寫乙個程式將兩個例項裡面的每一行資料都分別取出來對比,但是耗時我們無法估計,大概天荒地老吧。方案二 對每一行資料所有字段合併起來,取checksum值,再按照checksum值對...
MySQL快速對比資料技巧
在mysql運維中,研發同事想對比下兩個不同例項上的資料並找出差異,除主鍵外還需要對比每乙個字段,如何做呢?第一種方案,寫程式將兩個例項上的每一行資料取出來進行對比,理論可行,但是對比時間較長。第二種方案,對每一行資料所有字段合併起來,取checksum值,再按照checksum值對比,看著可行,嘗...
快速對比資料
例項需求 日常工作中經常需要對比資料,例如如下的參會名單,現在需要對比兩屆參會名單的異同,100個人的名單,看得老眼昏花也未必能夠準確的找出差異。strcompare 減少 trim strremove vbnewline 新增 trim stradd endfunction sub demo ms...