查询以比较MySQL中两个表的结构


18

为了自动执行一个MySQL数据库的备份过程,我想比较两个表的结构(当前版本与旧版本)。

您能想到一个可以比较两个表的查询吗?

这是您可以比较的一些示例表。

CREATE TABLE product_today
(
  pname VARCHAR(150),
  price int,
  PRIMARY KEY (pname)
);

CREATE TABLE product_yesterday
(
  pname VARCHAR(150),
  price int,
  PRIMARY KEY (pname)
);

CREATE TABLE product_2days_back
(
  pname VARCHAR(15),
  price int,
  PRIMARY KEY (pname)
);

前两个表具有相同的结构。最后一个是不同的。我只需要知道两个表是否具有不同的结构。我对它们之间的差异不感兴趣。


@ yagmoth555假设我的问题对于SF来说足够了,如果您想在这里输入类似的答案,我会接受。否则,我今天晚些时候会回答我自己的问题。

我不确定它是否适合那里,但是我会写一个答案,因为它无论如何都可以适合,因为无论如何它都可能是服务器管理员的问题:)就像,如果我愿意做一个表结构的转储,以及两者之间的grep,就很合适。我个人认为这是一条灰线

1
这不可能可靠地做到。并非所有软件版本之间的数据结构更改实际上都将自身表现为架构更改。只有应用程序的开发人员才知道确切的更改。如果开发人员尚未为您提供正式的迁移工具,则需要询问他们如何在特定版本的应用程序之间迁移。
卡巴斯德(Kasperd),2015年

1
我制作了一个免费工具,该工具将生成alter语句,以使第二个表与第一个表tablediff.com相同。仍然是alpha。
Mihai

Answers:


34

当前数据库中的两个表

如果您想知道两个表是否不同,请运行此命令

SELECT IF(COUNT(1)>0,'Differences','No Differences') Comparison FROM
(
    SELECT
        column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE table_schema=DATABASE()
    AND table_name IN ('product_today','product_yesterday')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

如果您确实需要查看差异,请运行此

SELECT column_name,ordinal_position,data_type,column_type FROM
(
    SELECT
        column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE table_schema=DATABASE()
    AND table_name IN ('product_today','product_yesterday')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

特定数据库中的两张表

如果您想知道数据库中两个表是否不同mydb,请运行此命令

SELECT IF(COUNT(1)>0,'Differences','No Differences') Comparison FROM
(
    SELECT
        column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE table_schema='mydb'
    AND table_name IN ('product_today','product_yesterday')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

如果您确实需要查看差异,请运行此

SELECT column_name,ordinal_position,data_type,column_type FROM
(
    SELECT
        column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE table_schema='mydb'
    AND table_name IN ('product_today','product_yesterday')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

两种不同数据库中的两张表

如果您想知道db1.tb1db2.tb2是否不同,请运行此命令

SELECT IF(COUNT(1)>0,'Differences','No Differences') Comparison FROM
(
    SELECT
        column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE
    (
        (table_schema='db1' AND table_name='tb1') OR
        (table_schema='db2' AND table_name='tb2')
    )
    AND table_name IN ('product_today','product_yesterday')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

如果您确实需要查看差异,请运行此

SELECT column_name,ordinal_position,data_type,column_type FROM
(
    SELECT
        column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE
    (
        (table_schema='db1' AND table_name='tb1') OR
        (table_schema='db2' AND table_name='tb2')
    )
    AND table_name IN ('product_today','product_yesterday')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

试试看 !!!


我需要对两个具有相同状态的相同表的开发数据库进行并行比较,我能够对其进行修改以很好地实现该目标。
杰森

1
@Jason很高兴我可以帮忙!
RolandoMySQLDBA

非常有帮助,为我节省了一些宝贵的时间
Nikita Kurtin

如何在选择的列中显示架构名称,表名称
iCoders

2

您可以比较SHOW CREATE TABLE product_today输出的校验和

# mysql -NBe "SHOW CREATE TABLE sakila.actor"| sed -r 's/AUTO_INCREMENT=[0-9]+/AUTO_INCREMENT=XXX/g' | md5sum
# 1bc0d72b294d1a93ce01b9a2331111cc  -

1
如果有一个AUTO_INCREMENT,它可能会妨碍您。
RolandoMySQLDBA 2014年

是的,然后您切下自动增量值
akuzminsky 2014年

现在,那又快又脏。+1 !!!
RolandoMySQLDBA

如果您正在使用Shell,这似乎是一个聪明的解决方案。谢谢。
sjdh 2014年

2
不能保证列的顺序相同,因此规范方面相同的架构可以产生不同的校验和。
Zds

1

扩展RolandoMySQLDBA的答案:

要同时查看表名称,请查询以下内容:

SELECT table_name, column_name,ordinal_position,data_type,column_type FROM
(
    SELECT
        table_name, column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE table_schema=DATABASE()
    AND table_name IN ('table_1','table_2')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1
) A;

0

看一下information_schema-column_type字段中的columns表。这样您就可以比较表结构。


0

我比较2个数据库(DB1,DB2)的最终方法-仅包括表/视图,约束和外键。就我而言,我总是使用以下SQL将PRODUCTION与UAT或UAT与DEV进行比较。

DB DIFF(比较表/视图)

select x.* from (
SELECT a.table_name, a.column_name,
    max(IF(b.TS='S1',b.ordinal_position,null)) as S1_ordinal_position,
    max(IF(b.TS='S2',b.ordinal_position,null)) as S2_ordinal_position,
    max(IF(b.TS='S1',b.data_type       ,null)) as S1_data_type,
    max(IF(b.TS='S2',b.data_type       ,null)) as S2_data_type,
    max(IF(b.TS='S1',b.column_type     ,null)) as S1_column_type,
    max(IF(b.TS='S2',b.column_type     ,null)) as S2_column_type
FROM
(SELECT DISTINCT table_name, column_name
 FROM information_schema.columns
 WHERE table_schema IN ('DB1','DB2')
) a
INNER JOIN
(SELECT IF(table_schema='DB1','S1','S2') as TS,
    table_schema,table_name,column_name,ordinal_position,data_type,column_type
 FROM information_schema.columns
 WHERE table_schema IN ('DB1','DB2')
) b
on (a.table_name = b.table_name and a.column_name = b.column_name)
group by a.table_name, a.column_name
) x
where x.S1_ordinal_position != x.S2_ordinal_position or x.S1_ordinal_position is null or x.S2_ordinal_position is null
or    x.S1_data_type        != x.S2_data_type
or    x.S1_column_type      != x.S2_column_type
ORDER BY x.table_name;

-2

对于两个数据库的表结构的所有更改:

SELECT table_schema, table_name, column_name,ordinal_position,data_type,column_type FROM (
    SELECT
        table_schema, table_name, column_name,ordinal_position,
        data_type,column_type,COUNT(1) rowcount
    FROM information_schema.columns
    WHERE table_schema IN ('database1', 'database2')
    GROUP BY
        column_name,ordinal_position,
        data_type,column_type
    HAVING COUNT(1)=1 ) A;

参考:从RolandoMySQLDBA ans


这到底是什么?Rolando的答案有所改善吗?
ypercubeᵀᴹ

没有改进,但可以查看两个数据库之间所有表的直接更改。
murtaza.webdev,2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.