MySQL 查询以显示开发和生产模式之间的差异

标签 mysql schema information-schema

我想在 MySQL 中使用模式数据库进行查询
这显示了两个数据库模式之间的列、触发器和存储过程之间的差异:生产和开发。

查询,而非工具
我看过Compare two MySQL databases
其中列出了可以执行此任务的工具,但我想知道是否有可以执行此任务的查询
请只提出查询,我真的不想了解工具、命令行黑客等。

我正在查看生产数据库和开发数据库是否不同步。
以及添加或更改了哪些字段、过程等,因此如果我对使用该数据库的客户端软件进行新更新,我可以更新生产数据库。

我使用的是 MySQL 5.1 最新版本。

最佳答案

Johan,尝试运行这个脚本。在脚本开头的变量中指定要比较的两个数据库。查询返回数据集,并设置表/ View 列的状态。

状态 'Only in source' - 对象只存在于 db1 中; 状态“仅在目标中”- 对象仅存在于 db2 中; 状态“在两个模式中”——对象存在于 db1 和 db2 中,但细节可能不同;例如:值'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;

可以修改此脚本以查找触发器和例程之间的差异。

关于MySQL 查询以显示开发和生产模式之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5663482/

相关文章:

oracle11g - Oracle SQL Developer - 如何限制用户只能查看特定模式

go - 如何将范围设置为 terraform schema.schema 字段?

mysql - Google Cloud SQL 信息架构非常慢

postgresql - 如何反射(reflection)物化 View

php - 向 Mysql 数据库发送两个查询时出现问题

sql - 更改 SQL 中表的架构名称

php - 循环遍历函数直到满足条件

php - 使用 INFORMATION_SCHEMA 作为根,错误说它不存在?

通过 SSH 隧道查询 MYSQL 数据库的 MySQL-Python 代码

MySQL 总和更新