CREATE TABLE
supports the specification of generated columns. CREATE TABLE
支持指定生成的列。Values of a generated column are computed from an expression included in the column definition.生成的列的值是根据列定义中包含的表达式计算的。
Generated columns are also supported by the NDB
storage engine.NDB
存储引擎也支持生成的列。
The following simple example shows a table that stores the lengths of the sides of right triangles in the 下面的简单示例显示了一个表,该表存储了sidea
and sideb
columns, and computes the length of the hypotenuse in sidec
(the square root of the sums of the squares of the other sides):sidea
和sideb
列中直角三角形边的长度,并计算sidec
中斜边的长度(其他边的平方和的平方根):
CREATE TABLE triangle ( sidea DOUBLE, sideb DOUBLE, sidec DOUBLE AS (SQRT(sidea * sidea + sideb * sideb)) ); INSERT INTO triangle (sidea, sideb) VALUES(1,1),(3,4),(6,8);
Selecting from the table yields this result:从表中选择会产生以下结果:
mysql> SELECT * FROM triangle;
+-------+-------+--------------------+
| sidea | sideb | sidec |
+-------+-------+--------------------+
| 1 | 1 | 1.4142135623730951 |
| 3 | 4 | 5 |
| 6 | 8 | 10 |
+-------+-------+--------------------+
Any application that uses the 任何使用triangle
table has access to the hypotenuse values without having to specify the expression that calculates them.triangle
表的应用程序都可以访问斜边值,而无需指定计算斜边值的表达式。
Generated column definitions have this syntax:生成的列定义具有以下语法:
col_name
data_type
[GENERATED ALWAYS] AS (expr
) [VIRTUAL | STORED] [NOT NULL | NULL] [UNIQUE [KEY]] [[PRIMARY] KEY] [COMMENT 'string
']
AS (
expr
) indicates that the column is generated and defines the expression used to compute column values. 指示已生成列并定义用于计算列值的表达式。AS
may be preceded by GENERATED ALWAYS
to make the generated nature of the column more explicit. AS
前面可能会加上GENERATED ALWAYS
,以使列的生成性质更加明确。Constructs that are permitted or prohibited in the expression are discussed later.表达式中允许或禁止的构造将在后面讨论。
The VIRTUAL
or STORED
keyword indicates how column values are stored, which has implications for column use:VIRTUAL
或STORED
关键字表示列值的存储方式,这对列的使用有影响:
VIRTUAL
: Column values are not stored, but are evaluated when rows are read, immediately after any :不存储列值,而是在读取行时,在任何BEFORE
triggers. BEFORE
触发器之后立即计算列值。A virtual column takes no storage.虚拟列不占用存储空间。
InnoDB
supports secondary indexes on virtual columns. 支持虚拟列上的辅助索引。See Section 13.1.20.9, “Secondary Indexes and Generated Columns”.请参阅第13.1.20.9节,“二级索引和生成列”。
STORED
: Column values are evaluated and stored when rows are inserted or updated. :插入或更新行时,将计算和存储列值。A stored column does require storage space and can be indexed.存储列确实需要存储空间,并且可以编制索引。
The default is 如果两个关键字都未指定,则默认为VIRTUAL
if neither keyword is specified.VIRTUAL
。
It is permitted to mix 允许在表中混合VIRTUAL
and STORED
columns within a table.VIRTUAL
列和STORED
列。
Other attributes may be given to indicate whether the column is indexed or can be 可以提供其他属性来指示该列是否已编制索引或可以为NULL
, or provide a comment.NULL
,或者提供注释。
Generated column expressions must adhere to the following rules. An error occurs if an expression contains disallowed constructs.生成的列表达式必须遵守以下规则。如果表达式包含不允许的构造,则会发生错误。
Literals, deterministic built-in functions, and operators are permitted. 允许使用文字、确定性内置函数和运算符。A function is deterministic if, given the same data in tables, multiple invocations produce the same result, independently of the connected user. 如果给定表中相同的数据,多个调用产生相同的结果,而与连接的用户无关,则函数是确定的。Examples of functions that are nondeterministic and fail this definition: 不确定且未通过此定义的函数示例:CONNECTION_ID()
, CURRENT_USER()
, NOW()
.CONNECTION_ID()
、CURRENT_USER()
、NOW()
。
Stored functions and loadable functions are not permitted.不允许使用存储函数和可加载函数。
Stored procedure and function parameters are not permitted.不允许使用存储过程和函数参数。
Variables (system variables, user-defined variables, and stored program local variables) are not permitted.不允许使用变量(系统变量、用户定义变量和存储程序局部变量)。
Subqueries are not permitted.不允许子查询。
A generated column definition can refer to other generated columns, but only those occurring earlier in the table definition. 生成的列定义可以引用其他生成的列,但只能引用表定义中较早出现的列。A generated column definition can refer to any base (nongenerated) column in the table whether its definition occurs earlier or later.生成的列定义可以引用表中的任何基(未生成)列,无论其定义发生得更早还是更晚。
The AUTO_INCREMENT
attribute cannot be used in a generated column definition.AUTO_INCREMENT
属性不能用于生成的列定义中。
An AUTO_INCREMENT
column cannot be used as a base column in a generated column definition.AUTO_INCREMENT
列不能用作生成的列定义中的基列。
If expression evaluation causes truncation or provides incorrect input to a function, the 如果表达式求值导致截断或向函数提供不正确的输入,CREATE TABLE
statement terminates with an error and the DDL operation is rejected.CREATE TABLE
语句将以错误终止,DDL操作将被拒绝。
If the expression evaluates to a data type that differs from the declared column type, implicit coercion to the declared type occurs according to the usual MySQL type-conversion rules. 如果表达式的计算结果为与声明的列类型不同的数据类型,则会根据通常的MySQL类型转换规则对声明的类型进行隐式强制。See Section 12.3, “Type Conversion in Expression Evaluation”.请参阅第12.3节,“表达式计算中的类型转换”。
If a generated column uses the 如果生成的列使用TIMESTAMP
data type, the setting for explicit_defaults_for_timestamp
is ignored. TIMESTAMP
数据类型,则忽略explicit_defaults_for_timestamp
的设置。In such cases, if this variable is disabled then 在这种情况下,如果禁用此变量,则NULL
is not converted to CURRENT_TIMESTAMP
. NULL
不会转换为CURRENT_TIMESTAMP
。In MySQL 8.0.22 and later, if the column is also declared as 在MySQL 8.0.22及更高版本中,如果列也声明为NOT NULL
, attempting to insert NULL
is explicitly rejected with ER_BAD_NULL_ERROR.NOT NULL
,则尝试插入NULL
会被显式拒绝,并出现ER_BAD_NULL_ERROR
。
Expression evaluation uses the SQL mode in effect at evaluation time. 表达式求值使用求值时有效的SQL模式。If any component of the expression depends on the SQL mode, different results may occur for different uses of the table unless the SQL mode is the same during all uses.如果表达式的任何组件依赖于SQL模式,则表的不同使用可能会产生不同的结果,除非SQL模式在所有使用过程中都是相同的。
For 对于CREATE TABLE ... LIKE
, the destination table preserves generated column information from the original table.CREATE TABLE ... LIKE
,目标表保留从原始表生成的列信息。
For 对于CREATE TABLE ... SELECT
, the destination table does not preserve information about whether columns in the selected-from table are generated columns. CREATE TABLE ... SELECT
,目标表不会保留有关“从中选择”表中的列是否为生成列的信息。The 语句的SELECT
part of the statement cannot assign values to generated columns in the destination table.SELECT
部分无法为目标表中生成的列赋值。
Partitioning by generated columns is permitted. 允许按生成的列进行分区。See Table Partitioning.请参阅表分区。
A foreign key constraint on a stored generated column cannot use 存储的生成列上的外键约束不能在CASCADE
, SET NULL
, or SET DEFAULT
as ON UPDATE
referential actions, nor can it use SET NULL
or SET DEFAULT
as ON DELETE
referential actions.ON UPDATE
引用操作上使用CASCADE
、SET NULL
或SET DEFAULT
,也不能在ON DELETE
引用操作上使用SET NULL
或SET DEFAULT
。
A foreign key constraint on the base column of a stored generated column cannot use 存储的生成列的基列上的外键约束不能在CASCADE
, SET NULL
, or SET DEFAULT
as ON UPDATE
or ON DELETE
referential actions.ON UPDATE
或ON DELETE
引用操作时使用CASCADE
、SET NULL
或SET DEFAULT
。
A foreign key constraint cannot reference a virtual generated column.外键约束无法引用虚拟生成的列。
Triggers cannot use 触发器不能使用NEW.
or use col_name
OLD.
to refer to generated columns.col_name
NEW.
或使用col_name
OLD.
引用生成的列。col_name
For 对于INSERT
, REPLACE
, and UPDATE
, if a generated column is inserted into, replaced, or updated explicitly, the only permitted value is DEFAULT
.INSERT
、REPLACE
和UPDATE
,如果生成的列被显式插入、替换或更新,则唯一允许的值为DEFAULT
。
A generated column in a view is considered updatable because it is possible to assign to it. 视图中生成的列被认为是可更新的,因为它可以指定给它。However, if such a column is updated explicitly, the only permitted value is 但是,如果显式更新此列,则唯一允许的值为DEFAULT
.DEFAULT
。
Generated columns have several use cases, such as these:生成的列有几个用例,例如:
Virtual generated columns can be used as a way to simplify and unify queries. 虚拟生成的列可以用作简化和一致性查询的方法。A complicated condition can be defined as a generated column and referred to from multiple queries on the table to ensure that all of them use exactly the same condition.复杂条件可以定义为生成的列,并从表上的多个查询中引用,以确保所有查询使用完全相同的条件。
Stored generated columns can be used as a materialized cache for complicated conditions that are costly to calculate on the fly.存储生成的列可以用作复杂条件下的物化缓存,这些复杂条件需要动态计算。
Generated columns can simulate functional indexes: Use a generated column to define a functional expression and index it. 生成的列可以模拟函数索引:使用生成的列定义函数表达式并为其编制索引。This can be useful for working with columns of types that cannot be indexed directly, such as 这对于处理无法直接索引的列(例如JSON
columns; see Indexing a Generated Column to Provide a JSON Column Index, for a detailed example.JSON
列)非常有用;有关详细示例,请参阅为生成的列编制索引以提供JSON列索引。
For stored generated columns, the disadvantage of this approach is that values are stored twice; once as the value of the generated column and once in the index.对于存储生成的列,这种方法的缺点是值存储两次;一次作为生成列的值,一次作为索引。
If a generated column is indexed, the optimizer recognizes query expressions that match the column definition and uses indexes from the column as appropriate during query execution, even if a query does not refer to the column directly by name. 如果对生成的列进行了索引,则优化器会识别与列定义匹配的查询表达式,并在查询执行过程中根据需要使用来自该列的索引,即使查询没有直接按名称引用该列。For details, see Section 8.3.11, “Optimizer Use of Generated Column Indexes”.有关详细信息,请参阅第8.3.11节,“优化器使用生成的列索引”。
Example:例子:
Suppose that a table 假设表t1
contains first_name
and last_name
columns and that applications frequently construct the full name using an expression like this:t1
包含first_name
列和last_name
列,并且应用程序经常使用以下表达式构造全名:
SELECT CONCAT(first_name,' ',last_name) AS full_name FROM t1;
One way to avoid writing out the expression is to create a view 避免写出表达式的一种方法是在v1
on t1
, which simplifies applications by enabling them to select full_name
directly without using an expression:t1
上创建一个视图v1
,它通过允许应用程序直接选择full_name
而不使用表达式来简化应用程序:
CREATE VIEW v1 AS SELECT *, CONCAT(first_name,' ',last_name) AS full_name FROM t1; SELECT full_name FROM v1;
A generated column also enables applications to select 生成的列还允许应用程序直接选择full_name
directly without the need to define a view:full_name
,而无需定义视图:
CREATE TABLE t1 ( first_name VARCHAR(10), last_name VARCHAR(10), full_name VARCHAR(255) AS (CONCAT(first_name,' ',last_name)) ); SELECT full_name FROM t1;