在遷移庫(kù)表抖格、定位線上問(wèn)題時(shí)冕房,要對(duì)比兩個(gè)庫(kù)表的內(nèi)容生逸。根據(jù)數(shù)據(jù)規(guī)模和使用工具可以有很多種做法牢屋。
1. SQL 外連接查詢。
查數(shù)據(jù)和處理數(shù)據(jù)都在DB完成槽袄。
select * from tb1 left join tb2 on t1.filed1 = t2.filed1 where t1.field2 <> t2.field2
這種方法適用于數(shù)據(jù)規(guī)模很小烙无,db做外連接操作不會(huì)影響線上。如果數(shù)據(jù)量大遍尺,絕對(duì)不能用截酷,一個(gè)不小心把db拖死那就玩砸了。 我們讓數(shù)據(jù)查詢和數(shù)據(jù)處理分離乾戏,把數(shù)據(jù)從db拉出來(lái)迂苛,做離線的對(duì)比。
2. 數(shù)據(jù)提取
echo "select field1,field2 from tb1;" | mysql -h ip -s -r
第一個(gè)字段最好是主鍵或唯一索引鼓择,這樣后面對(duì)比時(shí)少些麻煩三幻。
如果有的字段內(nèi)容為空或者NULL,取出來(lái)的內(nèi)容就沒(méi)法區(qū)分這兩個(gè)字段呐能,我們用concat_ws把字段內(nèi)容用分隔符連接起來(lái)念搬,而不是用默認(rèn)的空格。
select concat_ws('~', field1, field2) from tb1;
這時(shí)又發(fā)現(xiàn)一個(gè)問(wèn)題摆出,如果內(nèi)容中有NULL朗徊,concat_ws會(huì)直接忽略,導(dǎo)致少了一個(gè)字段懊蒸。于是荣倾,把字段用IFNULL包含起來(lái)悯搔。
select concat_ws('~', IFNULL(field1,''), IFNULL(field2,'')) from tb1;
3. 數(shù)據(jù)對(duì)比
數(shù)據(jù)提取的工作解決了骑丸,怎么對(duì)比兩個(gè)文件的內(nèi)容呢。數(shù)據(jù)量很多妒貌,而且大部分是相同的數(shù)據(jù)通危。代碼對(duì)比用diff,除非完全一致灌曙,否則結(jié)果不可靠菊碟,還要人肉查看。簡(jiǎn)化下問(wèn)題在刺,這其實(shí)是求兩個(gè)集合A逆害、B的差集头镊,即A有B沒(méi)有∑悄唬可以用下面的命令
grep -F -f B A -v
或者
sort A B B | uniq -u
對(duì)稱的相艇,B有A沒(méi)有,也可以取出來(lái)纯陨。如果想對(duì)比到底那些字段不一致坛芽,可以在對(duì)兩個(gè)差集A', B'分別sort后join再awk比較, 得出哪個(gè)字段不一致。
join -t '~' -j 1 A' B' | awk -F '~' '{for (i=0;i < 30; i++){if($(i+2) != $(i+2+30)) print i,$i}}}'