- 生成列不需要维护,依赖于一个已存在的列
- 生成分为两种:虚拟的、实际的。虚拟列不存储在磁盘中,实际的则和正常列一样存储在磁盘
语法
col_name data_type [GENERATED ALWAYS] AS (expr)
[VIRTUAL | STORED] [NOT NULL | NULL]
[UNIQUE [KEY]] [[PRIMARY] KEY]
[COMMENT 'string']
-
VIRTUAL
关键字指示如何存储列值, 这STORED
对列的使用有影响:-
VIRTUAL
: 不存储列值,而是在读取行时,在任何BEFORE
触发器之后立即评估。虚拟列不占用存储空间。
InnoDB
支持虚拟列的二级索引。请参阅 第 13.1.18.8 节,“二级索引和生成的列”。 -
STORED
:在插入或更新行时评估和存储列值。存储列确实需要存储空间并且可以被索引。
-
-
生成的列表达式必须遵守以下规则。如果表达式包含不允许的构造,则会发生错误。
-
允许使用文字、确定性内置函数和运算符。如果给定表中的相同数据,则函数是确定性的,多次调用产生相同的结果,独立于连接的用户。非确定性且不符合此定义的函数示例:
CONNECTION_ID()
,CURRENT_USER()
,NOW()
. -
不允许存储函数和可加载函数。
-
不允许使用存储过程和函数参数。
-
不允许使用变量(系统变量、用户定义变量和存储的程序局部变量)。
-
不允许子查询。
-
生成的列定义可以引用其他生成的列,但只能引用表定义中较早出现的列。生成的列定义可以引用表中的任何基本(非生成)列,无论其定义发生得早还是晚。
-
该
AUTO_INCREMENT
属性不能在生成的列定义中使用。 -
AUTO_INCREMENT
列不能用作生成的列定义中的基列 。 -
从 MySQL 5.7.10 开始,如果表达式求值导致截断或向函数提供不正确的输入,则
CREATE TABLE
语句以错误终止并且 DDL 操作被拒绝。
-
问题
增加虚拟列时,必须使用确定性的函数
- 例如
使用UNIX_TIMESTAMP(时间转时间戳)会报错
sql: alter table table add column int_value int(10) GENERATED ALWAYS AS (convert(UNIX_TIMESTAMP(ctime)) USING INT));
Expression of generated column 'pd_int1' contains a disallowed function.
但可以使用FROM_UNIXTIME(时间戳转时间)
网友评论