找出数据库的两个版本中哪些表不同
Finding out which tables are different in two versions of a database
我有 2 个版本的数据库(比如 db_dev
和 db_beta
)。我在 db_dev
数据库中做了一些更改 - 添加了一些 table,并更改了一些现有 table 中的几列。我需要找出已进行更改的 table 个名称的列表。
我可以通过 运行 对 information_schema
数据库的以下查询轻松找出我添加的 tables:
SELECT table_name
FROM tables
WHERE table_schema = 'db_dev'
AND table_name NOT IN (SELECT table_name
FROM tables
WHERE table_schema = 'db_beta');
如何获取两个数据库版本中 column_name
不匹配的 table_name
?
以下解决方案不像您尝试的那样使用 sql 查询,也不会为您提供真实的表列表,但它会向您显示两个数据库中的所有更改。
您可以 sql dump 两种数据库结构:
mysqldump -u root -p --no-data dbname > schema.sql
然后您可以比较两个文件,例如使用 diff
linux 工具。
有许多现成的工具可以通过比较两个数据库来为您提供更改后的架构。以下是一些可以满足您的目的的工具:
Red-Gate's MySQL Schema & Data Compare
Red-Gate 的 MySQL 比较是实现此目的的最佳工具。虽然它是付费的,但如果你想做一些临时的事情,他们会提供 14 天的免费试用版。
使用 information_schema
,这是它的工作原理。
首先,您知道 information_schema.COLUMNS
table 包含列定义。如果某一列已更改,或者 table 不存在,它将反映在 information_schema.COLUMNS
table.
困难的部分是您必须比较 COLUMNS
table 的所有列。所以,你必须 select TABLE_CATALOG,TABLE_NAME,COLUMN_NAME,ORDINAL_POSITION,COLUMN_DEFAULT,
等等(这取决于你的 MySQL 版本)。
列列表是以下查询的结果:
SELECT GROUP_CONCAT(column_name)
FROM information_schema.COLUMNS
WHERE table_schema="information_schema"
AND table_name="COLUMNS" AND column_name!='TABLE_SCHEMA';
之后,我们只需要 SELECT TABLE_NAME, <column_list>
并搜索出现过一次的列(其他 table 中不存在的列),或者具有两个不同定义的列(更改的列)。所以我们将在结果查询中有两个不同的计数来考虑这两种情况。
我们将使用准备好的语句来检索我们想要的列的列表,并对结果进行分组。
生成的查询会为您完成所有过程:
SELECT CONCAT(
"SELECT DISTINCT TABLE_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA IN('db_dev', 'db_beta')
GROUP BY table_name, COLUMN_NAME
HAVING count(*)=1 OR
COUNT(DISTINCT CONCAT_WS(',', NULL, ",
GROUP_CONCAT(column_name)
,"))=2;")
FROM information_schema.COLUMNS
WHERE table_schema="information_schema"
AND table_name="COLUMNS" AND column_name!='TABLE_SCHEMA'
INTO @sql;
PREPARE stmt FROM @sql;
EXECUTE @sql;
我有 2 个版本的数据库(比如 db_dev
和 db_beta
)。我在 db_dev
数据库中做了一些更改 - 添加了一些 table,并更改了一些现有 table 中的几列。我需要找出已进行更改的 table 个名称的列表。
我可以通过 运行 对 information_schema
数据库的以下查询轻松找出我添加的 tables:
SELECT table_name
FROM tables
WHERE table_schema = 'db_dev'
AND table_name NOT IN (SELECT table_name
FROM tables
WHERE table_schema = 'db_beta');
如何获取两个数据库版本中 column_name
不匹配的 table_name
?
以下解决方案不像您尝试的那样使用 sql 查询,也不会为您提供真实的表列表,但它会向您显示两个数据库中的所有更改。
您可以 sql dump 两种数据库结构:
mysqldump -u root -p --no-data dbname > schema.sql
然后您可以比较两个文件,例如使用 diff
linux 工具。
有许多现成的工具可以通过比较两个数据库来为您提供更改后的架构。以下是一些可以满足您的目的的工具:
Red-Gate's MySQL Schema & Data Compare
Red-Gate 的 MySQL 比较是实现此目的的最佳工具。虽然它是付费的,但如果你想做一些临时的事情,他们会提供 14 天的免费试用版。
使用 information_schema
,这是它的工作原理。
首先,您知道 information_schema.COLUMNS
table 包含列定义。如果某一列已更改,或者 table 不存在,它将反映在 information_schema.COLUMNS
table.
困难的部分是您必须比较 COLUMNS
table 的所有列。所以,你必须 select TABLE_CATALOG,TABLE_NAME,COLUMN_NAME,ORDINAL_POSITION,COLUMN_DEFAULT,
等等(这取决于你的 MySQL 版本)。
列列表是以下查询的结果:
SELECT GROUP_CONCAT(column_name)
FROM information_schema.COLUMNS
WHERE table_schema="information_schema"
AND table_name="COLUMNS" AND column_name!='TABLE_SCHEMA';
之后,我们只需要 SELECT TABLE_NAME, <column_list>
并搜索出现过一次的列(其他 table 中不存在的列),或者具有两个不同定义的列(更改的列)。所以我们将在结果查询中有两个不同的计数来考虑这两种情况。
我们将使用准备好的语句来检索我们想要的列的列表,并对结果进行分组。
生成的查询会为您完成所有过程:
SELECT CONCAT(
"SELECT DISTINCT TABLE_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA IN('db_dev', 'db_beta')
GROUP BY table_name, COLUMN_NAME
HAVING count(*)=1 OR
COUNT(DISTINCT CONCAT_WS(',', NULL, ",
GROUP_CONCAT(column_name)
,"))=2;")
FROM information_schema.COLUMNS
WHERE table_schema="information_schema"
AND table_name="COLUMNS" AND column_name!='TABLE_SCHEMA'
INTO @sql;
PREPARE stmt FROM @sql;
EXECUTE @sql;