Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  ALTER TABLE and Generated Columns

15.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 COLUMNDROP COLUMN 对虚拟列不是原地操作。

  • InnoDB支持虚拟生成列的次要索引。添加或删除虚拟生成列的次要索引是一个原地操作。更多信息,请参见第15.1.20.9节,“次要索引和生成列”

  • 当添加或修改虚拟生成列时,不保证由生成列表达式计算的数据不超出该列范围,这可能导致返回不一致的数据和意外失败语句。为了控制是否对这些列进行验证,ALTER TABLE支持WITHOUT VALIDATIONWITH VALIDATION子句:

    • 使用WITHOUT VALIDATION(如果不指定则默认),执行原地操作(如果可能),不检查数据完整性,语句更快完成。然而,后续从表读取可能报告警告或错误,如果值超出范围。

    • 使用WITH VALIDATIONALTER TABLE将复制表。如果超出范围或其他错误发生,语句失败。因为执行了表复制,语句需要更长时间。

    WITHOUT VALIDATIONWITH VALIDATION只能与ADD COLUMNCHANGE COLUMNMODIFY COLUMN操作一起使用。否则,出现ER_WRONG_USAGE错误。

  • 如果表达式评估导致截断或提供给函数错误的输入,ALTER TABLE语句将以错误终止并拒绝DDL操作。

  • 修改列的默认值的ALTER TABLE语句也可能会更改使用该列的生成列表达式的值,后者可能会更改使用DEFAULT()函数的值。因此,修改列定义的ALTER TABLE操作如果有使用DEFAULT()函数的生成列表达式,会导致表重建。