MySQL comparison database table structure

MySQL comparison database table structure

introduce

This chapter mainly introduces how to compare the differences in the table structure of the database. Here, we mainly introduce the use of the mysqldiff tool to compare the differences in the table structure. In fact, after version 5.6, the system tables in the information library can also be compared by querying, but mysqldiff has another advantage. The function of directly producing differential SQL statements is what we need to use, and it is difficult to achieve this by analyzing system tables; let's take a look at how to use this tool.

 

 

grammar

mysqldiff --server1=user:pass@host:port:socket --server2=user:pass@host:port:socket db1.object1:db2.object1 db3:db4

There are two uses for this syntax:

db1:db2: If you only specify the database, then the objects that are missing from each other in the two databases will be displayed, and the differences in the objects will not be compared; the objects here include tables, stored procedures, functions, triggers, etc.

db1.object1:db2.object1: If a specific table object is specified, the differences between the two tables will be compared in detail, including table-related objects that have table names, field names, remarks, indexes, capitalization, etc.

Let's look at some of the main parameters:

--server1: Configure the connection of server1

--server2: configure the connection of server2

--character-set: The character set used when configuring the connection, if the configuration is not displayed, "character_set_client" is used by default

--width: configure the width of the display

--skip-table-options: This option means to keep the table options unchanged, that is, the differences in comparison do not include differences in table names, AUTO_INCREMENT, ENGINE, CHARSET, etc.

-d DIFFTYPE, --difftype: The way the difference information is displayed, there is [unified|context|differ|sql](default: unified), if you use sql, it is very convenient to directly generate the difference SQL.

--changes-for=: For example --changes-for=server2, then the comparison is based on server1, and the modification of the generated difference is also the modification of the object of server2.

--show-reverse: This literally means to show the opposite meaning. In fact, the generated difference modification will include the modification of server2 and server1 at the same time.

test

copy code
use study;

create table test1
(id int  not  null  primary  key ,
a varchar(10) not null,
b varchar(10),
c varchar(10) comment 'c',
d int

)
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='test1';


create table test2
(id you are  not  null ,
a varchar(10),
b varchar(5),
c varchar(10),
D int
)
ENGINE=myisam DEFAULT CHARSET=utf8 COMMENT='test2';
copy code

1. Do not use --skip-table-options

mysqldiff  --server1=root:root@localhost --server2=root:root@localhost --changes-for=server2   --show-reverse   --difftype=sql study.test1:study.test2



 

2.使用--skip-table-options


 

 

其实用SQL语句也可以达到查询的效果,这里就贴上平时用的对比语句。

copy code
###############################################################################################################################
##判断两个数据库相同表的字段不为空是否相同
select a.TABLE_SCHEMA,a.TABLE_NAME,a.COLUMN_NAME,a.COLUMN_TYPE,a.IS_NULLABLE,a.COLUMN_DEFAULT,b.TABLE_SCHEMA,b.TABLE_NAME,b.COLUMN_NAME,b.COLUMN_TYPE,b.IS_NULLABLE ,b.COLUMN_DEFAULT,b.COLUMN_COMMENT 
from information_schema.`COLUMNS` a inner join information_schema.`COLUMNS` b 
on a.TABLE_SCHEMA='db1' and b.TABLE_SCHEMA='db2'and a.TABLE_NAME=b.TABLE_NAME and a.COLUMN_NAME=b.COLUMN_NAME and a.IS_NULLABLE<>b.IS_NULLABLE
where a.IS_NULLABLE='NO';
################################################################################################################################
##判断两个数据库相同表的字段默认值是否相同
select a.TABLE_SCHEMA,a.TABLE_NAME,a.COLUMN_NAME,a.COLUMN_DEFAULT,b.TABLE_SCHEMA,b.TABLE_NAME,b.COLUMN_NAME,b.COLUMN_DEFAULT from information_schema.`COLUMNS` a 
inner join information_schema.`COLUMNS` b on a.TABLE_SCHEMA='db1' and b.TABLE_SCHEMA='db2'
and a.TABLE_NAME=b.TABLE_NAME and a.COLUMN_NAME=b.COLUMN_NAME and a.COLUMN_DEFAULT<>b.COLUMN_DEFAULT;

#################################################################################################################################
##判断两个数据库相同表的字段数据类型是否相同,这里是判断数据类型不同如果要判断数据类型的长度不同需要用COLUMN_TYPE字段
select a.TABLE_SCHEMA,a.TABLE_NAME,a.COLUMN_NAME,a.DATA_TYPE,a.COLUMN_DEFAULT,b.TABLE_SCHEMA,b.TABLE_NAME,b.COLUMN_NAME,b.DATA_TYPE ,b.COLUMN_DEFAULT
from information_schema.`COLUMNS` a inner join information_schema.`COLUMNS` b on a.TABLE_SCHEMA='db1' and b.TABLE_SCHEMA='db2'
and a.TABLE_NAME=b.TABLE_NAME and a.COLUMN_NAME=b.COLUMN_NAME and a.DATA_TYPE<>b.DATA_TYPE;

##################################################################################################################################
##判断两个数据库相同表的中互相不存在的字段
select a.TABLE_SCHEMA,a.TABLE_NAME,a.COLUMN_NAME,a.DATA_TYPE,a.COLUMN_DEFAULT
from information_schema.`COLUMNS` a 
where a.TABLE_SCHEMA='db1' and a.COLUMN_NAME NOT IN(SELECT b.COLUMN_NAME from information_schema.`COLUMNS` b where b.TABLE_SCHEMA='db2' and a.TABLE_SCHEMA='db1'
and a.TABLE_NAME=b.TABLE_NAME );

select a.TABLE_SCHEMA,a.TABLE_NAME,a.COLUMN_NAME,a.DATA_TYPE,a.COLUMN_DEFAULT
from information_schema.`COLUMNS` a 
where a.TABLE_SCHEMA='db2' and a.COLUMN_NAME NOT IN(SELECT b.COLUMN_NAME from information_schema.`COLUMNS` b where b.TABLE_SCHEMA='db1' and a.TABLE_SCHEMA='db2'
and a.TABLE_NAME=b.TABLE_NAME );

####mysql没有full jion所以变相的多做了一次select查询,这种方法性能比较差,对于表比较多的数据库建议使用上面的分开查询
select b.TABLE_SCHEMA,b.TABLE_NAME,b.COLUMN_NAME,b.DATA_TYPE,c.TABLE_SCHEMA,c.TABLE_NAME,c.COLUMN_NAME,c.DATA_TYPE from 
(select TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME,DATA_TYPE from information_schema.`COLUMNS` a where a.TABLE_SCHEMA in('db2','db1') )a left join
(select TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME,DATA_TYPE from information_schema.`COLUMNS` a where a.TABLE_SCHEMA in('db2')) b  on a.TABLE_NAME=b.TABLE_NAME AND a.COLUMN_NAME=b.COLUMN_NAME left join 
(select TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME,DATA_TYPE from information_schema.`COLUMNS` a where a.TABLE_SCHEMA in('db1')) c on a.TABLE_NAME=c.TABLE_NAME AND a.COLUMN_NAME=c.COLUMN_NAME
where b.COLUMN_NAME is null or c.COLUMN_NAME is null ;

#######################################################################################################################
##判断两个数据库互相不存在的表
select a.TABLE_SCHEMA,a.TABLE_NAME
from information_schema.TABLES a 
where a.TABLE_SCHEMA='db1' and a.TABLE_NAME NOT IN(SELECT b.TABLE_NAME from information_schema.TABLES b where b.TABLE_SCHEMA='db2');

select a.TABLE_SCHEMA,a.TABLE_NAME
from information_schema.TABLES a 
where a.TABLE_SCHEMA='db2' and a.TABLE_NAME NOT IN(SELECT b.TABLE_NAME from information_schema.TABLES b where b.TABLE_SCHEMA='db1');


select b.TABLE_SCHEMA,b.TABLE_NAME,c.TABLE_SCHEMA,c.TABLE_NAME from 
(select TABLE_SCHEMA,TABLE_NAME from information_schema.TABLES a where a.TABLE_SCHEMA in('db2','db1') )a left join
(select TABLE_SCHEMA,TABLE_NAME from information_schema.TABLES a where a.TABLE_SCHEMA in('db2')) b  on a.TABLE_NAME=b.TABLE_NAME left join 
(select TABLE_SCHEMA,TABLE_NAME from information_schema.TABLES a where a.TABLE_SCHEMA in('db1')) c on a.TABLE_NAME=c.TABLE_NAME 
where b.TABLE_NAME is null or c.TABLE_NAME is null ;
copy code

 

总结

 这里没有演示对数据库的对比,数据库的对比显示的只是缺少的数据库对象,理解起来更加容易。

 

------------

补充:

1、自动对比两个库里相同表,并生成更新第二个库表的ALTER 语句: 

 

select concat(
'ALTER `', TABLE_NAME1, '` ADD COLUMN ', COLUMN_NAME1, ' ', COLUMN_TYPE1, ' ', 
  if(IS_NULLABLE1='NO', ' not null ', ''), 
	if(IFNULL(COLUMN_DEFAULT1,'')='', '', CONCAT('default ', COLUMN_DEFAULT1, ' ')), 
	if(IFNULL(COLUMN_COMMENT1, '')='', '', CONCAT(' COMMENT \'', COLUMN_COMMENT1, '\' ')), 
  '; '
)
FROM(

SELECT b.TABLE_SCHEMA,b.TABLE_NAME,b.COLUMN_NAME,b.DATA_TYPE,b.COLUMN_TYPE,b.IS_NULLABLE,b.COLUMN_DEFAULT,b.COLUMN_COMMENT,
	c.TABLE_SCHEMA TABLE_SCHEMA1,c.TABLE_NAME TABLE_NAME1,c.COLUMN_NAME COLUMN_NAME1,c.DATA_TYPE DATA_TYPE1,c.COLUMN_TYPE COLUMN_TYPE1,
		c.IS_NULLABLE IS_NULLABLE1,c.COLUMN_DEFAULT COLUMN_DEFAULT1,c.COLUMN_COMMENT COLUMN_COMMENT1  
FROM 
(select TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME,DATA_TYPE,COLUMN_TYPE,IS_NULLABLE,COLUMN_DEFAULT,COLUMN_COMMENT FROM information_schema.`COLUMNS` a where a.TABLE_SCHEMA in('ecshop_fx','ecshop') )a 
left join
  (SELECT TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME,DATA_TYPE,COLUMN_TYPE,IS_NULLABLE,COLUMN_DEFAULT,COLUMN_COMMENT FROM information_schema.`COLUMNS` a where a.TABLE_SCHEMA in('ecshop_fx')) b 
    on a.TABLE_NAME=b.TABLE_NAME AND a.COLUMN_NAME=b.COLUMN_NAME 
left join 
  (SELECT TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME,DATA_TYPE,COLUMN_TYPE,IS_NULLABLE,COLUMN_DEFAULT,COLUMN_COMMENT FROM information_schema.`COLUMNS` a where a.TABLE_SCHEMA in('ecshop')) c 
    on a.TABLE_NAME=c.TABLE_NAME AND a.COLUMN_NAME=c.COLUMN_NAME
where b.COLUMN_NAME is null or c.COLUMN_NAME is null 

) AS D;
 

 

 

2、查一个表里的所有字段并拼成一个字符串:

SELECT GROUP_CONCAT(COLUMN_NAME) from information_schema.COLUMNS 
where table_name = 'ecs_goods' 
and table_schema = 'ecshop_fx_test';

 

3、查询一个表所有字段并生成插入另一个库的SQL语句

SELECT
concat(
	'INSERT INTO ecshop_fx.', table_name, ' (', GROUP_CONCAT(COLUMN_NAME), ') \n',
	'SELECT ', GROUP_CONCAT(COLUMN_NAME),
		' FROM ecshop_fx_test.', table_name
) AS _INSQL
FROM
	information_schema. COLUMNS
WHERE
	table_name LIKE 'ecs_goods%'
AND table_schema = 'ecshop_fx_test';

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326441253&siteId=291194637