ALTER TABLE和生成的列
ALTER TABLE
允许生成的列操作是ADD
,MODIFY
,和CHANGE
。
可以添加生成的列。
CREATE TABLE t1 (c1 INT);ALTER TABLE t1ADD COLUMN c2 INTGENERATED ALWAYS AS (c1 + 1)STORED ;可以修改生成的列的数据类型和表达式。
CREATE TABLE t1 (c1 INT, c2 INTGENERATED ALWAYS AS (c1 + 1)STORED );ALTER TABLE t1MODIFY COLUMN c2 TINYINTGENERATED ALWAYS AS (c1 + 5)STORED ;如果没有其他列引用生成的列,则可以重命名或删除它们。
CREATE TABLE t1 (c1 INT, c2 INTGENERATED ALWAYS AS (c1 + 1)STORED );ALTER TABLE t1CHANGE c2 c3 INTGENERATED ALWAYS AS (c1 + 1)STORED ;ALTER TABLE t1DROP COLUMN c3;虚拟生成的列不能更改为存储的生成的列,反之亦然。要解决此问题,请删除该列,然后添加新定义。
CREATE TABLE t1 (c1 INT, c2 INTGENERATED ALWAYS AS (c1 + 1)VIRTUAL );ALTER TABLE t1DROP COLUMN c2;ALTER TABLE t1ADD COLUMN c2 INTGENERATED ALWAYS AS (c1 + 1)STORED ;可以将未生成的列更改为存储的,但不能更改为虚拟生成的列。
CREATE TABLE t1 (c1 INT, c2 INT);ALTER TABLE t1MODIFY COLUMN c2 INTGENERATED ALWAYS AS (c1 + 1)STORED ;可以将已存储但不是虚拟生成的列更改为未生成的列。存储的生成值成为非生成列的值。
CREATE TABLE t1 (c1 INT, c2 INTGENERATED ALWAYS AS (c1 + 1)STORED );ALTER TABLE t1MODIFY COLUMN c2 INT;ADD COLUMN
不是对存储的列的就地操作(无需使用临时表即可完成),因为表达式必须由服务器评估。对于存储的列,索引更改已就位,而表达式更改未就位。列注释的更改已就位。对于非分区表,
ADD COLUMN
并且DROP COLUMN
是虚拟列的就地操作。但是,添加或删除虚拟列不能与其他ALTER TABLE
操作结合使用。对于分区表,
ADD COLUMN
并DROP COLUMN
没有对虚拟列就地操作。InnoDB
支持虚拟生成的列上的二级索引。在虚拟生成的列上添加或删除二级索引是就地操作。有关更多信息,请参见“二级索引和生成的列”。将
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操作。 ALTER TABLE
更改列的默认值的语句col_name
也col_name
可能会更改使用引用该列的生成的列表达式的值,这可能会更改使用引用该列的生成的列表达式的值。因此,如果任何生成的列表达式使用,则更改列定义的操作将导致表重建。DEFAULT(col_name)
ALTER TABLE
DEFAULT()