2011-04-14 42 views
14

我想使用MySQL
中的模式數據庫進行查詢,該查詢顯示了兩個數據庫模式之間的列,觸發器和存儲過程之間的區別:生產和開發。MySQL查詢顯示開發和生產模式之間的差異

查詢,而不是工具
我見過Compare two MySQL databases
其中列出了可以執行此任務的工具,但我想知道的是,如果有一個查詢可以執行此任務。
請只建議查詢,我真的不想知道工具,命令行黑客等。

我正在查看生產數據庫和開發數據庫是否不同步。
以及哪些字段,程序等添加或更改,所以我可以更新生產數據庫,如果我推出使用數據庫的客戶端軟件的新更新。

我正在使用MySQL 5.1最新版本。

+0

您是否在談論比較可能是類似數據庫(如生產與開發)的表格,並且想要讓它們同步(由於任何更改)?如果是這樣,那就是爲什麼你想知道新的/更改的列,過程,索引等?否則,如果你試圖比較ex:Maps數據到音樂到電影...... – DRapp 2011-04-18 19:20:15

+0

是的,開發和生產數據庫之間的比較 – Johan 2011-04-18 19:27:17

回答

21

約翰,嘗試運行此腳本。在腳本開始時指定兩個要在變量中進行比較的數據庫。查詢返回數據集,並設置表/視圖列的狀態。

狀態'Only in source' - 對象僅存在於db1中; 狀態'僅在目標中' - 對象僅在db2中存在; 狀態'在兩個模式中' - 對象存在於db1和db2中,但細節可能不同;例如:value'varchar(255)/ int(11)'表示源字段類型爲'varchar(255)',目標爲'int(11)',值'null'表示細節相同;

SET @source_db = 'db1'; 
SET @target_db = 'db2'; 

SELECT 
    'Only in source' exist_type, 
    c1.table_schema, c1.table_name, c1.column_name, c1.ordinal_position, c1.column_default, c1.is_nullable, c1.numeric_precision, c1.numeric_scale, c1.character_set_name, c1.collation_name, c1.column_type, c1.column_key, c1.extra, c1.column_comment 
FROM 
    (SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = @source_db) c1 
    LEFT JOIN (SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = @target_db) c2 
    ON c1.TABLE_name = c2.TABLE_name AND c1.column_name = c2.column_name 
WHERE c2.column_name is null 

UNION ALL 

SELECT 
    'Only in target' exist_type, 
    c2.table_schema, c2.table_name, c2.column_name, c2.ordinal_position, c2.column_default, c2.is_nullable, c2.numeric_precision, c2.numeric_scale, c2.character_set_name, c2.collation_name, c2.column_type, c2.column_key, c2.extra, c2.column_comment 
FROM 
    (SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = @source_db) c1 
    RIGHT JOIN (SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = @target_db) c2 
    ON c1.TABLE_name = c2.TABLE_name AND c1.column_name = c2.column_name 
WHERE c1.column_name is null 

UNION ALL 

SELECT 
    'In both schemas' exist_type, 
    CONCAT(c1.table_schema, '/', c2.table_schema), 
    c1.table_name, c1.column_name, 
    IF(c1.ordinal_position = c2.ordinal_position OR c1.ordinal_position IS NULL AND c2.ordinal_position IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.ordinal_position, ''), IFNULL(c2.ordinal_position, ''))), 
    IF(c1.column_default = c2.column_default OR c1.column_default IS NULL AND c2.column_default IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.column_default, ''), IFNULL(c2.column_default, ''))), 
    IF(c1.is_nullable = c2.is_nullable OR c1.is_nullable IS NULL AND c2.is_nullable IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.is_nullable, ''), IFNULL(c2.is_nullable, ''))), 
    IF(c1.numeric_precision = c2.numeric_precision OR c1.numeric_precision IS NULL AND c2.numeric_precision IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.numeric_precision, ''), IFNULL(c2.numeric_precision, ''))), 
    IF(c1.numeric_scale = c2.numeric_scale OR c1.numeric_scale IS NULL AND c2.numeric_scale IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.numeric_scale, ''), IFNULL(c2.numeric_scale, ''))), 
    IF(c1.character_set_name = c2.character_set_name OR c1.character_set_name IS NULL AND c2.character_set_name IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.character_set_name, ''), IFNULL(c2.character_set_name, ''))), 
    IF(c1.collation_name = c2.collation_name OR c1.collation_name IS NULL AND c2.collation_name IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.collation_name, ''), IFNULL(c2.collation_name, ''))), 
    IF(c1.column_type = c2.column_type OR c1.column_type IS NULL AND c2.column_type IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.column_type, ''), IFNULL(c2.column_type, ''))), 
    IF(c1.column_key = c2.column_key OR c1.column_key IS NULL AND c2.column_key IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.column_key, ''), IFNULL(c2.column_key, ''))), 
    IF(c1.extra = c2.extra OR c1.extra IS NULL AND c2.extra IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.extra, ''), IFNULL(c2.extra, ''))), 
    IF(c1.column_comment = c2.column_comment OR c1.column_comment IS NULL AND c2.column_comment IS NULL, NULL, CONCAT_WS('/', IFNULL(c1.column_comment, ''), IFNULL(c2.column_comment, ''))) 
FROM 
    (SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = @source_db) c1 
    JOIN (SELECT * FROM information_schema.columns WHERE TABLE_SCHEMA = @target_db) c2 
    ON c1.TABLE_name = c2.TABLE_name AND c1.column_name = c2.column_name; 

該腳本可以被修改,以找到觸發器和程序之間的差異。

+0

哇devart,這就是我所說的。 – Johan 2011-04-22 21:46:23

+0

它的功能就像一個魅力。我很開心(: - |} – Johan 2011-04-22 21:50:00

3

您之後的所有數據都應在information_schema數據庫的表中。

您可能可以通過某種連接進行比較,只顯示不同之處,但試圖在查詢中執行此操作,或者單個查詢看起來像是一種過度複雜的解決問題的方式,重新開始自己的腳。

快速簡便的解決方案是到diff或者每個數據庫的mysqldump --no-data的內容或從信息模式中提取數據並對其進行比較。

+0

我只想知道表和存儲過程之間是否有變化,所以我不必因爲可能不同步的東西而失眠。 – Johan 2011-04-14 23:08:03

0

T1比較到t2

select 
(case t1.table_name=t2.table_name when 1 then concat(t1.table_name,"==",t2.table_name) else concat(t1.table_name,"!=",t2.table_name) end) as table_name, 
(case t1.column_name=t2.column_name when 1 then concat(t1.column_name,"==", t2.column_name) else concat(t1.column_name,"!=", t2.column_name) end) as column_name, 
(case t1.ORDINAL_POSITION=t2.ORDINAL_POSITION when 1 then concat(t1.ORDINAL_POSITION,"==", t2.ORDINAL_POSITION) else concat(t1.ORDINAL_POSITION,"!=", t2.ORDINAL_POSITION) end) as ORDINAL_POSITION 
......--columns in information_schema 
from columns t1 left join (select * from columns where table_schema='t2') t2 on t2.table_name=t1.table_name and t2.column_name=t1.column_name where t1.table_schema='t1'; 

希望這幫助!

0

約翰·您已經縮小你說你想要一個「查詢」來比較數據庫:)

但是我對你的建議是想「二進制日誌」回答域。我已經成功地將它用於類似的目的。

 a) enable logs 
     b) Go through all binary logs files 
     c) grep desired statements 
     d) at then end purge/reset binary logs ie. RESET MASTER 

很明顯,你會在生產數據庫上做到這一點。

其它方式可能是:How to synchronize development and production database