【问题标题】:Finding out which tables are different in two versions of a database找出数据库的两个版本中哪些表不同
【发布时间】:2015-04-17 19:10:40
【问题描述】:

我有 2 个版本的数据库(比如 db_devdb_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');

如何获取两个数据库版本中column_names 不匹配的table_names?

【问题讨论】:

  • 您在使用 Visual Studio 吗?如果是,请告诉我。

标签: mysql database database-schema information-schema


【解决方案1】:

以下解决方案没有像您尝试的那样使用 sql 查询,也没有为您提供真实的表列表,但它向您显示了两个数据库中的所有更改。

您可以对两种数据库结构进行sql dump

mysqldump -u root -p --no-data dbname > schema.sql

然后您可以比较两个文件,例如使用diff linux 工具。

【讨论】:

    【解决方案2】:

    有许多现成的工具可以通过比较两个数据库来改变架构。以下是一些可以为您服务的工具:

    Red-Gate's MySQL Schema & Data Compare

    Maatkit

    MySQL Diff

    SQL EDT

    Red-Gate 的 MySQL Compare 是实现此目的的最佳工具。虽然它是付费的,但如果你想做一些临时的事情,他们会提供 14 天的免费试用版。

    【讨论】:

    • “Maatkit”是旧的;它已被 Percona 接管并改进为 Percona 工具包。
    【解决方案3】:

    使用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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-14
      • 2019-07-16
      • 2020-11-15
      • 2020-11-03
      • 1970-01-01
      • 2015-12-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多