Table 在 ALTER 中使用多个操作遍历 TABLE

Table traversing with multiple operations in ALTER TABLE

一些数据库,例如 MySQL [1] 和 PostgreSQL [2],支持捆绑某些兼容的 ALTER TABLE 语句(作为非标准 SQL)。

例如我们可以有:

ALTER TABLE `my_table`
    DROP COLUMN `column_1`,
    DROP COLUMN `column_2`,
    ...

ALTER TABLE
    MODIFY `column_1` ... ,
    MODIFY `column_2` ... ,

而不是单独的陈述:

ALTER TABLE `my_table` DROP COLUMN `column_1`;
ALTER TABLE `my_table` DROP COLUMN `column_2`;

ALTER TABLE `my_table` MODIFY `column_1` ... ;
ALTER TABLE `my_table` MODIFY `column_2` ... ;

等等

为了比较相同的功能,PostgreSQL [2] 也实现了这一点,将在一次扫描中执行所有操作:

The main reason for providing the option to specify multiple changes in a single ALTER TABLE is that multiple table scans or rewrites can thereby be combined into a single pass over the table.

虽然对于 DROP COLUMN 来说通常甚至不需要这样做:

The DROP COLUMN form does not physically remove the column, but simply makes it invisible to SQL operations...

问题:

假设:

参考文献:

MySQL 的 InnoDB:

(这 不是 真正回答了问题,但提供了对 ALTER 更大问题的更多见解。)

  • 如果任何更改需要复制 table,您 可能 最好将所有更改放在同一个语句中。例如,更改 PRIMARY KEY 需要重建与 PK 聚类的数据。

  • 一些改变可以通过简单地改变模式来实现;这些几乎是瞬时的,可以通过单独的 alter 语句来完成。添加选项 ENUM 很久以前就实现了。

  • 一些 alter 需要某种形式的扫描,但可以做到 "in the background"。 DROP INDEX 可以通过快速 "hiding" 完成,然后在后台释放 BTree。

  • 我遗漏了一个灰色区域,您可以在其中批量 'simple' 更改。人们希望 ALTER 足够聪明,可以简单地快速浏览它们,而不是决定将 table 复制过来。

我得到了一些有用的反馈,但决定回答我自己的问题以提供更具体的答案。

Would the multi-column statement result in traversing all the rows just once and performing all changes needed?

,如果alter语句导致重建table那么它只需要做一次。*

* 这个答案来自我自己的测试和其他主要是轶事证据(包括@Uueerdo 在这个 post 中)。如果有一些官方文档会很有用...

How does MySQL actually perform DROP COLUMN? Does it also "hide" the columns first, or does it delete the data straight away?

MySQL 将为大多数列操作就地重建 table(而不是创建副本或仅更改元数据)。每个具体案例都可以在 Online DDL docs for InnoDB.

中找到

重命名列或设置默认值等一些操作只会更改元数据,因此不需要 table 重建。

但是,删除列确实需要完整的table重建