Documentation Home
MySQL 8.0 参考手册  / 第 13 章 SQL 语句  / 13.1 数据定义语句  / 13.1.9 ALTER TABLE 语句  /  13.1.9.2 ALTER TABLE 和生成的列

13.1.9.2 ALTER TABLE 和生成的列

ALTER TABLE生成列允许的操作是ADDMODIFYCHANGE

  • 可以添加生成的列。

    CREATE TABLE t1 (c1 INT);
    ALTER TABLE t1 ADD COLUMN c2 INT GENERATED ALWAYS AS (c1 + 1) STORED;
  • 可以修改生成列的数据类型和表达式。

    CREATE TABLE t1 (c1 INT, c2 INT GENERATED ALWAYS AS (c1 + 1) STORED);
    ALTER TABLE t1 MODIFY COLUMN c2 TINYINT GENERATED ALWAYS AS (c1 + 5) STORED;
  • 如果没有其他列引用生成的列,则可以重命名或删除它们。

    CREATE TABLE t1 (c1 INT, c2 INT GENERATED ALWAYS AS (c1 + 1) STORED);
    ALTER TABLE t1 CHANGE c2 c3 INT GENERATED ALWAYS AS (c1 + 1) STORED;
    ALTER TABLE t1 DROP COLUMN c3;
  • 虚拟生成列不能更改为存储生成列,反之亦然。要解决此问题,请删除该列,然后使用新定义添加它。

    CREATE TABLE t1 (c1 INT, c2 INT GENERATED ALWAYS AS (c1 + 1) VIRTUAL);
    ALTER TABLE t1 DROP COLUMN c2;
    ALTER TABLE t1 ADD COLUMN c2 INT GENERATED ALWAYS AS (c1 + 1) STORED;
  • 非生成的列可以更改为存储的但不是虚拟生成的列。

    CREATE TABLE t1 (c1 INT, c2 INT);
    ALTER TABLE t1 MODIFY COLUMN c2 INT GENERATED ALWAYS AS (c1 + 1) STORED;
  • 存储但不是虚拟生成的列可以更改为非生成列。存储的生成值成为非生成列的值。

    CREATE TABLE t1 (c1 INT, c2 INT GENERATED ALWAYS AS (c1 + 1) STORED);
    ALTER TABLE t1 MODIFY COLUMN c2 INT;
  • ADD COLUMN不是存储列的就地操作(在不使用临时表的情况下完成),因为表达式必须由服务器计算。对于存储列,索引更改是就地完成的,而表达式更改不是就地完成的。对列注释的更改已就地完成。

  • 对于非分区表,ADD COLUMNDROP COLUMN对虚拟列的就地操作。但是,添加或删除虚拟列不能与其他ALTER TABLE操作结合使用。

    对于分区表,ADD COLUMN并且 DROP COLUMN不是虚拟列的就地操作。

  • InnoDB支持虚拟生成列的二级索引。在虚拟生成列上添加或删除二级索引是就地操作。有关详细信息,请参阅 第 13.1.20.9 节,“二级索引和生成的列”

  • VIRTUAL生成列添加到表或修改时,无法确保生成列表达式计算的数据不超出该列的范围。这可能导致返回不一致的数据和意外失败的语句。要允许控制是否对此类列、 ALTER TABLE支撑WITHOUT VALIDATIONWITH VALIDATION 子句进行验证:

    • 使用WITHOUT VALIDATION(如果未指定任何子句则为默认值),执行就地操作(如果可能),不检查数据完整性,并且语句完成得更快。但是,如果值超出范围,稍后从表中读取可能会报告该列的警告或错误。

    • 使用WITH VALIDATION,ALTER TABLE复制表格。如果发生超出范围或任何其他错误,该语句将失败。因为进行了表拷贝,语句耗时较长。

    WITHOUT VALIDATION并且WITH VALIDATION只允许与ADD COLUMNCHANGE COLUMNMODIFY COLUMN操作一起使用。否则, ER_WRONG_USAGE会发生错误。

  • 如果表达式求值导致截断或向函数提供不正确的输入,则该 ALTER TABLE语句将因错误而终止,并且 DDL 操作将被拒绝。

  • ALTER TABLE更改列默认值的语句也 可能col_name更改引用列 usingcol_name的生成列表达式的值,这可能会更改 引用列 using 的生成列表达式的值。因此, 如果任何生成的列表达式使用 ,则更改列定义的操作会导致表重建 。 DEFAULT(col_name)ALTER TABLEDEFAULT()