我有两个版本的数据库(比如db_dev
和db_beta
)。我在db_dev
数据库中做了一些更改 - 添加了一些表,并在一些现有表中更改了几列。我需要找出已经进行了更改的表名列表。
我可以通过在information_schema
数据库上运行以下查询来轻松找到我添加的表格:
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');
如何获取table_name
在两个数据库版本中不匹配的column_name
?
答案 0 :(得分:2)
有许多现成的工具可以通过比较两个数据库来为您提供更改的模式。以下是一些可以满足您目的的工具:
Red-Gate's MySQL Schema & Data Compare
Red-Gate的MySQL Compare是用于此目的的最佳工具。尽管如此,但如果你想做一些临时的事情,它们会提供14天的免费试用版。
答案 1 :(得分:1)
以下解决方案不会像您尝试的那样使用sql查询,也不会为您提供真正的表列表,但它会显示两个数据库中的所有更改。
您可以对这两种数据库结构执行sql dump:
mysqldump -u root -p --no-data dbname > schema.sql
然后你可以比较两个文件,例如使用diff
linux工具。
答案 2 :(得分:1)
使用information_schema
,以下是它的工作原理。
首先,您知道information_schema.COLUMNS
表包含列定义。如果一个列已更改,或者表不存在,则它将反映在information_schema.COLUMNS
表中。
困难的是你必须比较COLUMNS
表的所有列。因此,您必须选择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>
并搜索出现一次的列(其他表中不存在列),或者列有两个不同的定义(列已更改)。因此,我们将在结果查询中有两个不同的计数来考虑这两种情况。
我们将使用预准备语句来检索我们想要的列列表,并对结果进行分组。
生成的查询会为您完成所有过程:
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;