允许对生成列执行的 ALTER TABLE 操作包括 ADD、MODIFY 和 CHANGE。
可以添加生成列。
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 COLUMN和DROP COLUMN是虚拟列的就地操作。但是,添加或删除虚拟列不能与其他ALTER TABLE操作组合在一起就地执行。对于分区表,
ADD COLUMN和DROP COLUMN对虚拟列不是就地操作。InnoDB支持虚拟生成列的二级索引。在虚拟生成列上添加或删除二级索引是就地操作。有关更多信息,请参见 第 15.1.20.9 节,“二级索引和生成列”。当向表中添加
VIRTUAL生成列或修改VIRTUAL生成列时,无法确保生成列表达式计算的数据不会超出该列的范围。这可能导致返回不一致的数据,并意外导致语句失败。为了控制对这类列是否进行验证,ALTER TABLE支持WITHOUT VALIDATION和WITH VALIDATION子句。使用
WITHOUT VALIDATION(如果未指定任何子句,则为默认值),将执行就地操作(如果可能),不会检查数据完整性,并且语句执行速度更快。但是,如果值超出范围,以后从该表读取数据可能会报告警告或错误。使用
WITH VALIDATION,ALTER TABLE将复制表。如果出现超出范围错误或任何其他错误,则语句将失败。由于执行了表复制,因此该语句执行时间更长。
WITHOUT VALIDATION和WITH VALIDATION仅在ADD COLUMN、CHANGE COLUMN和MODIFY COLUMN操作中允许使用。否则,将发生ER_WRONG_USAGE错误。如果表达式求值导致截断或为函数提供不正确的输入,则
ALTER TABLE语句将以错误终止,并且 DDL 操作将被拒绝。更改列
col_name的默认值的ALTER TABLE语句还可能更改使用col_name引用该列的生成列表达式的值,这可能会更改使用DEFAULT(引用该列的生成列表达式的值。因此,更改列定义的col_name)ALTER TABLE操作如果任何生成列表达式使用DEFAULT(),则会导致表重建。