【问题标题】:Mysql : how to update table structure from another database table?Mysql:如何从另一个数据库表更新表结构?
【发布时间】:2020-09-23 09:51:02
【问题描述】:

我有 2 个包含表的数据库:table1

DB1 : table1: 字段1 字段2 字段3 字段4 .. 字段99

DB2 : table2: 字段1 字段2 字段3

(所以要手动添加 96 个新字段!)

我继续在 DB1 上的 table1 中添加新字段 例如:DB1.table1 现在有 99 个字段,DB2.table2 有 3 个字段

有没有办法在不删除数据或删除表的情况下“快速”更新 DB2.table,从而添加 96 个新字段? (一种不丢失数据的结构同步)

我正在手动添加一个又一个字段是浪费时间。

【问题讨论】:

  • 没有内置的方式来同步 DDL,您要么手动执行,要么编码 - 可能基于 infomation_schema.columns。
  • 有没有办法在不删除数据或删除表的情况下“快速”更新 DB2.table - 什么是“快速”?更少的手工或更少的锁桌时间?
  • 快速 = 不花 1 小时输入要添加的新字段
  • 我手动在一个字段后添加字段是浪费时间。 ALTER TABLE 允许在同一个语句中添加多个(甚至全部)字段。
  • '快速 = 不花 1 小时输入要添加的新字段' - 你为什么要显示 create table 然后将结果复制并粘贴到 alter 语句中 - 工作完成

标签: mysql mariadb


【解决方案1】:

示例。

问题中提到了两个表。

我们执行:

SHOW CREATE TABLE table1;
SHOW CREATE TABLE table2;

并接收

CREATE TABLE `table1` (
  `field1` int DEFAULT NULL,
  `field2` char(2) DEFAULT NULL,
  `field3` datetime DEFAULT NULL,
  `field4` bit(1) DEFAULT NULL,
  -- .....
  `field99` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

CREATE TABLE `table2` (
  `field1` int DEFAULT NULL,
  `field2` char(2) DEFAULT NULL,
  `field3` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

我们删除所有行,除了描述 table1 中列的行,而这些行在任何文本编辑器中获取的 table2 中都不存在

  `field4` bit(1) DEFAULT NULL,
  -- .....
  `field99` int DEFAULT NULL

然后我们在开头添加 ALTER TABLE 行,在每行开头添加 COLUMN 并指定 INSTANT 操作。

ALTER TABLE table2
ADD COLUMN
  `field4` bit(1) DEFAULT NULL,
  -- .....
ADD COLUMN
  `field99` int DEFAULT NULL
, ALGORITHM=INSTANT;

就是这样。可以执行。

sample fiddle

【讨论】:

    【解决方案2】:

    如果您有两个表(本例中只有 5 个字段):

    create table table1 (field1 integer, field2 integer, field3 integer, field4 integer, field5 varchar(20));
    
    create table table2 (field1 integer, field2 integer, field3 integer);
    

    然后您可以使用此 SQL 查看“缺失”列:

    select c1.column_name, c2.column_name
    from information_schema.columns  c1
    left join information_schema.columns  c2 on c2.table_schema=c1.table_schema and c2.table_name='table2' and c2.column_name=c1.column_name
    where c1.table_schema='test' and c1.table_name = 'table1' ;
    
    +-------------+-------------+
    | COLUMN_NAME | COLUMN_NAME |
    +-------------+-------------+
    | field1      | field1      |
    | field2      | field2      |
    | field3      | field3      |
    | field4      | NULL        |
    | field5      | NULL        |
    +-------------+-------------+
    

    如果存储过程是这样创建的:

    DELIMITER //
    
    CREATE PROCEDURE AddFields (IN Table1 VARCHAR(200), IN Table2 VARCHAR(200))
        BEGIN
            select 
               CONCAT("ALTER TABLE ",Table2," ADD COLUMN ",c1.COLUMN_NAME," ",c1.column_type) as AlterStatement
            from information_schema.columns  c1
            left join information_schema.columns  c2 on 
                c2.table_schema=c1.table_schema and 
                c2.table_name=Table2 and c2.column_name=c1.column_name
            where 
                c1.table_schema='test' and 
                c1.table_name = Table1 and
                c2.column_name is null;
        END//
           
    DELIMITER ;
    

    一个人可以做到:

    mysql> call Addfields('Table1','Table2');
    +--------------------------------------------------+
    | AlterStatement                                   |
    +--------------------------------------------------+
    | ALTER TABLE Table2 ADD COLUMN field4 int         |
    | ALTER TABLE Table2 ADD COLUMN field5 varchar(20) |
    +--------------------------------------------------+
    

    这让ALTER TABLE 语句进行更改。

    可能需要进行一些更改以考虑默认值,但是....?

    附加信息:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-25
      • 2018-06-17
      • 1970-01-01
      相关资源
      最近更新 更多