我想询问是否有可能比较两个巨大数据库的完整结构。 我们有两个数据库,一个是开发数据库,另一个是生产数据库。 有时候在发布一些代码之前,我会忘记将更改应用到生产数据库中,这导致生产数据库的结构与开发数据库不同,如果有东西需要发布,我们就会遇到一些错误。 有没有办法比较这两个数据库或进行同步?
我想询问是否有可能比较两个巨大数据库的完整结构。 我们有两个数据库,一个是开发数据库,另一个是生产数据库。 有时候在发布一些代码之前,我会忘记将更改应用到生产数据库中,这导致生产数据库的结构与开发数据库不同,如果有东西需要发布,我们就会遇到一些错误。 有没有办法比较这两个数据库或进行同步?
对于MySQL数据库,您可以使用以下查询比较视图和表(列名称和列类型):
SET @firstDatabaseName = '[first database name]';
SET @secondDatabaseName = '[second database name]';
SELECT * FROM
(SELECT
CONCAT(cl.TABLE_NAME, ' [', cl.COLUMN_NAME, ', ', cl.COLUMN_TYPE, ']') tableRowType
FROM information_schema.columns cl, information_schema.TABLES ss
WHERE
cl.TABLE_NAME = ss.TABLE_NAME AND
cl.TABLE_SCHEMA = @firstDatabaseName AND
ss.TABLE_TYPE IN('BASE TABLE', 'VIEW')
ORDER BY
cl.table_name ) AS t1
LEFT JOIN
(SELECT
CONCAT(cl.TABLE_NAME, ' [', cl.COLUMN_NAME, ', ', cl.COLUMN_TYPE, ']') tableRowType
FROM information_schema.columns cl, information_schema.TABLES ss
WHERE
cl.TABLE_NAME = ss.TABLE_NAME AND
cl.TABLE_SCHEMA = @secondDatabaseName AND
ss.TABLE_TYPE IN('BASE TABLE', 'VIEW')
ORDER BY
cl.table_name ) AS t2 ON t1.tableRowType = t2.tableRowType
WHERE
t2.tableRowType IS NULL
UNION
SELECT * FROM
(SELECT
CONCAT(cl.TABLE_NAME, ' [', cl.COLUMN_NAME, ', ', cl.COLUMN_TYPE, ']') tableRowType
FROM information_schema.columns cl, information_schema.TABLES ss
WHERE
cl.TABLE_NAME = ss.TABLE_NAME AND
cl.TABLE_SCHEMA = @firstDatabaseName AND
ss.TABLE_TYPE IN('BASE TABLE', 'VIEW')
ORDER BY
cl.table_name ) AS t1
RIGHT JOIN
(SELECT
CONCAT(cl.TABLE_NAME, ' [', cl.COLUMN_NAME, ', ', cl.COLUMN_TYPE, ']') tableRowType
FROM information_schema.columns cl, information_schema.TABLES ss
WHERE
cl.TABLE_NAME = ss.TABLE_NAME AND
cl.TABLE_SCHEMA = @secondDatabaseName AND
ss.TABLE_TYPE IN('BASE TABLE', 'VIEW')
ORDER BY
cl.table_name ) AS t2 ON t1.tableRowType = t2.tableRowType
WHERE
t1.tableRowType IS NULL;
Compalex是一个轻量级的脚本,用于比较两个数据库模式。它支持MySQL、MS SQL Server和PostgreSQL。
你可以使用命令行:
mysqldump --skip-comments --skip-extended-insert -d --no-data -u root -p dbName1>file1.sql
mysqldump --skip-comments --skip-extended-insert -d --no-data -u root -p dbName2>file2.sql
diff file1.sql file2.sql
compare file
命令。 - undefinedinformation_schema
的内容来比较列、数据类型和表。SET @database_current = '<production>';
SET @database_dev = '<development>';
-- column and datatype comparison
SELECT a.TABLE_NAME, a.COLUMN_NAME, a.DATA_TYPE, a.CHARACTER_MAXIMUM_LENGTH,
b.COLUMN_NAME, b.DATA_TYPE, b.CHARACTER_MAXIMUM_LENGTH
FROM information_schema.COLUMNS a
LEFT JOIN information_schema.COLUMNS b ON b.COLUMN_NAME = a.COLUMN_NAME
AND b.TABLE_NAME = a.TABLE_NAME
AND b.TABLE_SCHEMA = @database_current
WHERE a.TABLE_SCHEMA = @database_dev
AND (
b.COLUMN_NAME IS NULL
OR b.COLUMN_NAME != a.COLUMN_NAME
OR b.DATA_TYPE != a.DATA_TYPE
OR b.CHARACTER_MAXIMUM_LENGTH != a.CHARACTER_MAXIMUM_LENGTH
);
-- table comparison
SELECT a.TABLE_SCHEMA, a.TABLE_NAME, b.TABLE_NAME
FROM information_schema.TABLES a
LEFT JOIN information_schema.TABLES b ON b.TABLE_NAME = a.TABLE_NAME
AND b.TABLE_SCHEMA = @database_current
WHERE a.TABLE_SCHEMA = @database_dev
AND (
b.TABLE_NAME IS NULL
OR b.TABLE_NAME != a.TABLE_NAME
);
请查看针对.NET的Gemini Delta - SQL差异管理器。免费测试版可供下载,但完整版本距离公开发布仅有几天。
它不会比较行级数据差异,但它会比较表、函数、存储过程等,并且速度非常快。(新版本1.4在不到4秒的时间内加载和比较了1k个存储过程,而其他我测试过的工具需要超过10秒。)
尽管如此,大家都是正确的,RedGate确实制作出了很棒的工具。
根据您使用的数据库,可用的工具也会有所不同。
我使用 Embarcadero 的 ER/Studio。它具有比较和合并功能。
还有很多其他工具,例如 Toad for MySQL,也具有比较功能。我也同意 Red-Gate 的建议,但从未在 MySQL 上使用过它。