-- -- MySQL database diff -- ------------------- -- -- A set of SQL queries on the INFORMATION_SCHEMA to compare the structure -- of two databases placed on the same MySQL server. -- Works only with MySQL v5.0 and higher. -- -- Created: muzso (muzso@muzso.hu), 2009.08.12 -- Version: 1.0 -- -- -- Parameters -- -- addcollation: include the character set and collation in the generated column -- changing SQL statements. set @addcollation = 1; -- sourcedb: the db with the "template" structure that we want to duplicate set @sourcedb = 'sourcedb'; -- sourcedbexclude: a LIKE expression for source tables that we want to exclude set @sourcedbexclude = 'SRC_%'; -- targetdb: the db that we want to update to the same structure as sourcedb set @targetdb = 'targetdb'; -- sourcedbexclude: a LIKE expression for target tables that we want to exclude set @targetdbexclude = 'TRG_%'; -- -- Queries -- -- new tables to be created in targetdb select src.`TABLE_NAME` from `information_schema`.`tables` src left outer join `information_schema`.`tables` dst on dst.`TABLE_SCHEMA` = @targetdb and dst.`TABLE_NAME` = src.`TABLE_NAME` where 1 = 1 and src.`TABLE_SCHEMA` = @sourcedb and src.`TABLE_NAME` not like @sourcedbexclude and dst.`TABLE_NAME` is null order by src.`TABLE_NAME` -- old tables to be dropped in targetdb select dst.`TABLE_NAME`, concat('drop table `', dst.`TABLE_NAME`, '`;') as stmt from `information_schema`.`tables` dst left outer join `information_schema`.`tables` src on src.`TABLE_SCHEMA` = @sourcedb and dst.`TABLE_NAME` = src.`TABLE_NAME` where 1 = 1 and dst.`TABLE_SCHEMA` = @targetdb and dst.`TABLE_NAME` not like @targetdbexclude and src.`TABLE_NAME` is null order by dst.`TABLE_NAME` -- new columns to be created in existing tables of targetdb select srcc.`TABLE_NAME`, srcc.`COLUMN_NAME`, concat('alter table `', srcc.`TABLE_NAME`, '` add column `', srcc.`COLUMN_NAME`, '` ', srcc.`COLUMN_TYPE`, if(@addcollation = 1 and srcc.`CHARACTER_SET_NAME` is not null, concat(' character set ', srcc.`CHARACTER_SET_NAME`, ' collate ', srcc.`COLLATION_NAME`), ''), if(srcc.`IS_NULLABLE` = 'NO', ' not', ''), ' null', if(srcc.`COLUMN_DEFAULT` is null, '', concat(' default ', if(srcc.`CHARACTER_SET_NAME` is not null, '\'', ''), srcc.`COLUMN_DEFAULT`, if(srcc.`CHARACTER_SET_NAME` is not null, '\'', ''))), if(length(srcc.`EXTRA`) > 0, concat(' ', srcc.`EXTRA`), ''), ';') as stmt from `information_schema`.`columns` srcc inner join `information_schema`.`tables` dstt on dstt.`TABLE_SCHEMA` = @targetdb and dstt.`TABLE_NAME` = srcc.`TABLE_NAME` where 1 = 1 and srcc.`TABLE_SCHEMA` = @sourcedb and srcc.`TABLE_NAME` not like @sourcedbexclude and not exists( select 1 from `information_schema`.`columns` dstc where 1 = 1 and dstc.`TABLE_SCHEMA` = @targetdb and dstc.`TABLE_NAME` = srcc.`TABLE_NAME` and dstc.`COLUMN_NAME` = srcc.`COLUMN_NAME` ) order by srcc.`TABLE_NAME`, srcc.`COLUMN_NAME` -- old columns to be dropped in existing tables of targetdb select dstc.`TABLE_NAME`, dstc.`COLUMN_NAME`, concat('alter table `', dstc.`TABLE_NAME`, '` drop column `', dstc.`COLUMN_NAME`, '`;') as stmt from `information_schema`.`columns` dstc inner join `information_schema`.`tables` srct on srct.`TABLE_SCHEMA` = @sourcedb and srct.`TABLE_NAME` = dstc.`TABLE_NAME` where 1 = 1 and dstc.`TABLE_SCHEMA` = @targetdb and dstc.`TABLE_NAME` not like @targetdbexclude and not exists( select 1 from `information_schema`.`columns` srcc where 1 = 1 and srcc.`TABLE_SCHEMA` = @sourcedb and srcc.`TABLE_NAME` = dstc.`TABLE_NAME` and srcc.`COLUMN_NAME` = dstc.`COLUMN_NAME` ) order by dstc.`TABLE_NAME`, dstc.`COLUMN_NAME` -- existing columns with changed specification select src.`TABLE_NAME`, src.`COLUMN_NAME`, concat('alter table `', src.`TABLE_NAME`, '` change column `', src.`COLUMN_NAME`, '` `', src.`COLUMN_NAME`, '` ', src.`COLUMN_TYPE`, if(@addcollation = 1 and src.`CHARACTER_SET_NAME` is not null, concat(' character set ', src.`CHARACTER_SET_NAME`, ' collate ', src.`COLLATION_NAME`), ''), if(src.`IS_NULLABLE` = 'NO', ' not', ''), ' null', if(src.`COLUMN_DEFAULT` is null, '', concat(' default ', if(src.`CHARACTER_SET_NAME` is not null, '\'', ''), src.`COLUMN_DEFAULT`, if(src.`CHARACTER_SET_NAME` is not null, '\'', ''))), if(length(src.`EXTRA`) > 0, concat(' ', src.`EXTRA`), ''), ';') as stmt from `information_schema`.`columns` src inner join `information_schema`.`columns` dst on src.`TABLE_NAME` = dst.`TABLE_NAME` and src.`COLUMN_NAME` = dst.`COLUMN_NAME` where 1 = 1 and src.`TABLE_SCHEMA` = @sourcedb and dst.`TABLE_SCHEMA` = @targetdb and ( src.`COLUMN_TYPE` != dst.`COLUMN_TYPE` or src.`IS_NULLABLE` != dst.`IS_NULLABLE` or coalesce(src.`COLUMN_DEFAULT`, 'NULL') != coalesce(dst.`COLUMN_DEFAULT`, 'NULL') or src.`EXTRA` != dst.`EXTRA` ) order by src.`TABLE_NAME`, src.`COLUMN_NAME` -- side-by-side comparison of old spec vs. new spec of the changed columns select src.`TABLE_NAME`, src.`COLUMN_NAME`, concat('alter table `', dst.`TABLE_NAME`, '` add column `', dst.`COLUMN_NAME`, '` ', dst.`COLUMN_TYPE`, if(@addcollation = 1 and dst.`CHARACTER_SET_NAME` is not null, concat(' character set ', dst.`CHARACTER_SET_NAME`, ' collate ', dst.`COLLATION_NAME`), ''), if(dst.`IS_NULLABLE` = 'NO', ' not', ''), ' null', if(dst.`COLUMN_DEFAULT` is null, '', concat(' default ', if(dst.`CHARACTER_SET_NAME` is not null, '\'', ''), dst.`COLUMN_DEFAULT`, if(dst.`CHARACTER_SET_NAME` is not null, '\'', ''))), if(length(dst.`EXTRA`) > 0, concat(' ', dst.`EXTRA`), ''), ';') as old_stmt, concat('alter table `', src.`TABLE_NAME`, '` add column `', src.`COLUMN_NAME`, '` ', src.`COLUMN_TYPE`, if(@addcollation = 1 and src.`CHARACTER_SET_NAME` is not null, concat(' character set ', src.`CHARACTER_SET_NAME`, ' collate ', src.`COLLATION_NAME`), ''), if(src.`IS_NULLABLE` = 'NO', ' not', ''), ' null', if(src.`COLUMN_DEFAULT` is null, '', concat(' default ', if(src.`CHARACTER_SET_NAME` is not null, '\'', ''), src.`COLUMN_DEFAULT`, if(src.`CHARACTER_SET_NAME` is not null, '\'', ''))), if(length(src.`EXTRA`) > 0, concat(' ', src.`EXTRA`), ''), ';') as new_stmt from `information_schema`.`columns` src inner join `information_schema`.`columns` dst on src.`TABLE_NAME` = dst.`TABLE_NAME` and src.`COLUMN_NAME` = dst.`COLUMN_NAME` where 1 = 1 and src.`TABLE_SCHEMA` = @sourcedb and dst.`TABLE_SCHEMA` = @targetdb and ( src.`COLUMN_TYPE` != dst.`COLUMN_TYPE` or src.`IS_NULLABLE` != dst.`IS_NULLABLE` or coalesce(src.`COLUMN_DEFAULT`, 'NULL') != coalesce(dst.`COLUMN_DEFAULT`, 'NULL') or src.`EXTRA` != dst.`EXTRA` ) order by src.`TABLE_NAME`, src.`COLUMN_NAME`