13.1.8.2 ALTER TABLE 和生成的列
生成的列允许的ALTER TABLE
个操作是ADD
,MODIFY
和CHANGE
。
- 可以添加生成的列。
CREATE TABLE t1 (c1 INT);
ALTER TABLE t1 ADD COLUMN c2 INT GENERATED ALWAYS AS (c1 + 1) STORED;
- 可以修改生成的列的数据类型和 table 达式。
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
不是已存储列的就地操作(不使用临时 table 完成),因为该 table 达式必须由服务器评估。对于存储的列,索引更改已就位,而 table 达式更改未就位。列 Comments 的更改已就位。 -
对于非分区 table,
ADD COLUMN
和DROP COLUMN
是虚拟列的就地操作。但是,添加或删除虚拟列不能与其他ALTER TABLE操作结合执行。
对于分区 table,ADD COLUMN
和DROP COLUMN
不是虚拟列的就地操作。
-
InnoDB
支持虚拟生成的列上的二级索引。在虚拟生成的列上添加或删除二级索引是就地操作。有关更多信息,请参见第 13.1.18.8 节“辅助索引和生成的列”。 -
将
VIRTUAL
生成的列添加到 table 中或进行修改时,不能确保生成的列 table 达式所计算的数据不会超出该列的范围。这可能导致返回不一致的数据以及意外失败的语句。为了允许控制是否对此类列进行验证,ALTER TABLE
支持WITHOUT VALIDATION
和WITH VALIDATION
子句: -
使用
WITHOUT VALIDATION
(如果未指定任何子句则为默认值),将执行就地操作(如果可能的话),不检查数据完整性,并且语句执行更快。但是,如果值超出范围,以后从 table 中读取数据可能会报告该列的警告或错误。- 使用
WITH VALIDATION
,ALTER TABLE
复制 table。如果发生超出范围的错误或任何其他错误,该语句将失败。因为执行了 table 复制,所以语句花费的时间更长。
- 使用
WITHOUT VALIDATION
和WITH VALIDATION
仅允许用于ADD COLUMN
,CHANGE COLUMN
和MODIFY COLUMN
操作。否则,将发生ER_WRONG_USAGE错误。
-
从 MySQL 5.7.10 开始,如果 table 达式求值导致截断或向函数提供不正确的 Importing,则ALTER TABLE语句将以错误终止并拒绝 DDL 操作。
-
更改列默认值*
col_name
*的ALTER TABLE语句也可以更改使用DEFAULT(col_name)引用该列的生成的列 table 达式的值。因此,从 MySQL 5.7.13 开始,如果任何生成的列 table 达式使用DEFAULT(),则更改列定义的ALTER TABLE操作将导致 table 重建。