MySQL supports invisible columns as of MySQL 8.0.23. 从MySQL 8.0.23开始,MySQL支持不可见列。An invisible column is normally hidden to queries, but can be accessed if explicitly referenced. 不可见列通常对查询隐藏,但如果显式引用,则可以访问该列。Prior to MySQL 8.0.23, all columns are visible.在MySQL 8.0.23之前,所有列都是可见的。
As an illustration of when invisible columns may be useful, suppose that an application uses 作为不可见列何时有用的说明,假设应用程序使用SELECT *
queries to access a table, and must continue to work without modification even if the table is altered to add a new column that the application does not expect to be there. SELECT *
查询访问表,并且必须在不进行修改的情况下继续工作,即使该表被更改为添加应用程序不希望出现的新列。In a 在SELECT *
query, the *
evaluates to all table columns, except those that are invisible, so the solution is to add the new column as an invisible column. SELECT *
查询中,*
将计算所有表列(不可见列除外),因此解决方案是将新列添加为不可见列。The column remains “hidden” from 该列在SELECT *
queries, and the application continues to work as previously. SELECT *
查询中保持“隐藏”,并且应用程序继续像以前一样工作。A newer version of the application can refer to the invisible column if necessary by explicitly referencing it.如果需要,应用程序的较新版本可以通过显式引用不可见列来引用该列。
The following sections detail how MySQL treats invisible columns.以下各节详细介绍了MySQL如何处理不可见列。
Columns are visible by default. 默认情况下,列是可见的。To explicitly specify visibility for a new column, use a 要显式指定新列的可见性,请在VISIBLE
or INVISIBLE
keyword as part of the column definition for CREATE TABLE
or ALTER TABLE
:CREATE TABLE
或ALTER TABLE
的列定义中使用VISIBLE
或INVISIBLE
关键字:
CREATE TABLE t1 ( i INT, j DATE INVISIBLE ) ENGINE = InnoDB; ALTER TABLE t1 ADD COLUMN k INT INVISIBLE;
To alter the visibility of an existing column, use a 要更改现有列的可见性,请在VISIBLE
or INVISIBLE
keyword with one of the ALTER TABLE
column-modification clauses:ALTER TABLE
列修饰子句中使用VISIBLE
或INVISIBLE
关键字:
ALTER TABLE t1 CHANGE COLUMN j j DATE VISIBLE; ALTER TABLE t1 MODIFY COLUMN j DATE INVISIBLE; ALTER TABLE t1 ALTER COLUMN j SET VISIBLE;
A table must have at least one visible column. Attempting to make all columns invisible produces an error.表必须至少有一个可见列。试图使所有列不可见会产生错误。
Invisible columns support the usual column attributes: 不可见列支持常用的列属性:NULL
, NOT NULL
, AUTO_INCREMENT
, and so forth.NULL
、NOT NULL
、AUTO_INCREMENT
等等。
Generated columns can be invisible.生成的列可以不可见。
Index definitions can name invisible columns, including definitions for 索引定义可以命名不可见列,包括PRIMARY KEY
and UNIQUE
indexes. PRIMARY KEY
和UNIQUE
索引的定义。Although a table must have at least one visible column, an index definition need not have any visible columns.尽管表必须至少有一个可见列,但索引定义不需要有任何可见列。
An invisible column dropped from a table is dropped in the usual way from any index definition that names the column.从表中删除的不可见列以通常的方式从命名该列的任何索引定义中删除。
Foreign key constraints can be defined on invisible columns, and foreign key constraints can reference invisible columns.可以在不可见列上定义外键约束,并且外键约束可以引用不可见列。
可以在不可见列上定义CHECK
constraints can be defined on invisible columns. CHECK
约束。For new or modified rows, violation of a 对于新行或修改行,违反不可见列上的CHECK
constraint on an invisible column produces an error.CHECK
约束会产生错误。
CREATE TABLE ... LIKE
includes invisible columns, and they are invisible in the new table.CREATE TABLE ... LIKE
包含不可见列,它们在新表中不可见。
CREATE TABLE ... SELECT
does not include invisible columns, unless they are explicitly referenced in the SELECT
part. CREATE TABLE ... SELECT
不包括不可见列,除非它们在SELECT
部分中被明确引用。However, even if explicitly referenced, a column that is invisible in the existing table is visible in the new table:但是,即使显式引用,在现有表中不可见的列在新表中也是可见的:
mysql>CREATE TABLE t1 (col1 INT, col2 INT INVISIBLE);
mysql>CREATE TABLE t2 AS SELECT col1, col2 FROM t1;
mysql>SHOW CREATE TABLE t2\G
*************************** 1. row *************************** Table: t2 Create Table: CREATE TABLE `t2` ( `col1` int DEFAULT NULL, `col2` int DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
If invisibility should be preserved, provide a definition for the invisible column in the 如果应保留不可见性,请在CREATE TABLE
part of the CREATE TABLE ... SELECT
statement:CREATE TABLE ... SELECT
语句的CREATE TABLE
部分中为不可见列提供定义:
mysql>CREATE TABLE t1 (col1 INT, col2 INT INVISIBLE);
mysql>CREATE TABLE t2 (col2 INT INVISIBLE) AS SELECT col1, col2 FROM t1;
mysql>SHOW CREATE TABLE t2\G
*************************** 1. row *************************** Table: t2 Create Table: CREATE TABLE `t2` ( `col1` int DEFAULT NULL, `col2` int DEFAULT NULL /*!80023 INVISIBLE */ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
Views can refer to invisible columns by explicitly referencing them in the 视图可以通过在定义视图的SELECT
statement that defines the view. SELECT
语句中显式引用不可见列来引用这些列。Changing a column's visibility subsequent to defining a view that references the column does not change view behavior.在定义引用列的视图之后更改列的可见性不会更改视图行为。
For 对于SELECT
statements, an invisible column is not part of the result set unless explicitly referenced in the select list. SELECT
语句,不可见列不是结果集的一部分,除非在选择列表中显式引用。In a select list, the 在选择列表中,*
and
shorthands do not include invisible columns. tbl_name
.**
和tbl_name.*
缩写不包括不可见列。Natural joins do not include invisible columns.自然连接不包括不可见的列。
Consider the following statement sequence:考虑下面的语句序列:
mysql>CREATE TABLE t1 (col1 INT, col2 INT INVISIBLE);
mysql>INSERT INTO t1 (col1, col2) VALUES(1, 2), (3, 4);
mysql>SELECT * FROM t1;
+------+ | col1 | +------+ | 1 | | 3 | +------+ mysql>SELECT col1, col2 FROM t1;
+------+------+ | col1 | col2 | +------+------+ | 1 | 2 | | 3 | 4 | +------+------+
The first 第一个SELECT
does not reference the invisible column col2
in the select list (because *
does not include invisible columns), so col2
does not appear in the statement result. SELECT
不引用选择列表中的不可见列col2
(因为*
不包括不可见列),因此col2
不会出现在语句结果中。The second 第二个SELECT
does reference col2
, so it does appear in the result.SELECT
引用col2
,因此它确实出现在结果中。
For statements that create new rows, an invisible column is assigned its implicit default value unless explicitly referenced and assigned a value. 对于创建新行的语句,除非显式引用并指定值,否则将为不可见列指定其隐式默认值。For information about implicit defaults, see Implicit Default Handling.有关隐式默认值的信息,请参阅隐式默认值处理。
For 对于INSERT
(and REPLACE
, for non-replaced rows), implicit default assignment occurs with a missing column list, an empty column list, or a nonempty column list that does not include the invisible column:INSERT
(和REPLACE
,对于未替换的行),隐式默认赋值发生在缺少列列表、空列列表或不包含不可见列的非空列列表中:
CREATE TABLE t1 (col1 INT, col2 INT INVISIBLE); INSERT INTO t1 VALUES(...); INSERT INTO t1 () VALUES(...); INSERT INTO t1 (col1) VALUES(...);
For the first two 对于前两个INSERT
statements, the VALUES()
list must provide a value for each visible column and no invisible column. INSERT
语句,VALUES()
列表必须为每个可见列和不可见列提供一个值。For the third 对于第三条INSERT
statement, the VALUES()
list must provide the same number of values as the number of named columns.INSERT
语句,VALUES()
列表必须提供与命名列数相同的值数。
For 对于LOAD DATA
and LOAD XML
, implicit default assignment occurs with a missing column list or a nonempty column list that does not include the invisible column. LOAD DATA
和LOAD XML
,隐式默认赋值会在缺少列列表或不包含不可见列的非空列列表中发生。Input rows should not include a value for the invisible column.输入行不应包含不可见列的值。
To assign a value other than the implicit default for the preceding statements, explicitly name the invisible column in the column list and provide a value for it.要为前面的语句指定非隐式默认值的值,请在列列表中显式命名不可见列并为其提供值。
INSERT INTO ... SELECT *
and REPLACE INTO ... SELECT *
do not include invisible columns because *
does not include invisible columns. INSERT INTO ... SELECT *
和REPLACE INTO ... SELECT *
不包括不可见列,因为*
不包括不可见列。Implicit default assignment occurs as described previously.隐式默认赋值如前所述发生。
For statements that insert or ignore new rows, or that replace or modify existing rows, based on values in a 对于基于PRIMARY KEY
or UNIQUE
index, MySQL treats invisible columns the same as visible columns: Invisible columns participate in key value comparisons. PRIMARY KEY
或UNIQUE
索引中的值插入或忽略新行,或替换或修改现有行的语句,MySQL将不可见列视为与可见列相同:不可见列参与键值比较。Specifically, if a new row has the same value as an existing row for a unique key value, these behaviors occur whether the index columns are visible or invisible:具体地说,如果新行具有与唯一键值的现有行相同的值,则无论索引列是可见的还是不可见的,都会发生以下行为:
With the 使用IGNORE
modifier, INSERT
, LOAD DATA
, and LOAD XML
ignore the new row.IGNORE
修饰符,INSERT
、LOAD DATA
和LOAD XML
忽略新行。
REPLACE
replaces the existing row with the new row. REPLACE
将现有行替换为新行。With the 使用REPLACE
modifier, LOAD DATA
and LOAD XML
do the same.REPLACE
修饰符,LOAD DATA
和LOAD XML
的操作相同。
INSERT ... ON DUPLICATE KEY UPDATE
updates the existing row.INSERT ... ON DUPLICATE KEY UPDATE
更新现有行。
To update invisible columns for 要更新UPDATE
statements, name them and assign a value, just as for visible columns.UPDATE
语句的不可见列,请将它们命名并赋值,就像对可见列一样。
Information about whether a column is visible or invisible is available from the 有关列是可见还是不可见的信息可从EXTRA
column of the INFORMATION_SCHEMA.COLUMNS
table or SHOW COLUMNS
output. INFORMATION_SCHEMA.COLUMNS
表的EXTRA
列或SHOW COLUMNS
输出中获得。For example:例如:
mysql>SELECT TABLE_NAME, COLUMN_NAME, EXTRA
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'test' AND TABLE_NAME = 't1';
+------------+-------------+-----------+ | TABLE_NAME | COLUMN_NAME | EXTRA | +------------+-------------+-----------+ | t1 | i | | | t1 | j | | | t1 | k | INVISIBLE | +------------+-------------+-----------+
Columns are visible by default, so in that case, 默认情况下,列是可见的,因此在这种情况下,EXTRA
displays no visibility information. EXTRA
不显示可见性信息。For invisible columns, 对于不可见列,EXTRA
displays INVISIBLE
.EXTRA
显示不可见。
SHOW CREATE TABLE
displays invisible columns in the table definition, with the INVISIBLE
keyword in a version-specific comment:SHOW CREATE TABLE
在表定义中显示不可见列,在特定于版本的注释中使用INVISIBLE
关键字:
mysql> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`i` int DEFAULT NULL,
`j` int DEFAULT NULL,
`k` int DEFAULT NULL /*!80023 INVISIBLE */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
mysqldump and mysqldump和mysqlpump使用mysqlpump
use SHOW CREATE TABLE
, so they include invisible columns in dumped table definitions. SHOW CREATE TABLE
表,因此它们在转储表定义中包含不可见列。They also include invisible column values in dumped data.它们还包括转储数据中不可见的列值。
Reloading a dump file into an older version of MySQL that does not support invisible columns causes the version-specific comment to be ignored, which creates any invisible columns as visible.将转储文件重新加载到不支持不可见列的旧版本MySQL中会导致忽略特定于版本的注释,从而将任何不可见列创建为可见。
MySQL treats invisible columns as follows with respect to events in the binary log:MySQL对二进制日志中的事件处理不可见列如下:
Table-creation events include the 表创建事件包括不可见列的INVISIBLE
attribute for invisible columns.INVISIBLE
属性。
Invisible columns are treated like visible columns in row events. 不可见列被视为行事件中的可见列。They are included if needed according to the 根据系统变量binlog_row_image
system variable setting.binlog_row_image
设置,如果需要,可将其包括在内。
When row events are applied, invisible columns are treated like visible columns in row events. 应用行事件时,不可见列将被视为行事件中的可见列。In particular, the algorithm and index to use are chosen according to the 特别是,要使用的算法和索引是根据系统变量slave_rows_search_algorithms
system variable setting.slave_rows_search_algorithms
设置来选择的。
Invisible columns are treated like visible columns when computing writesets. 在计算写集时,不可见列被视为可见列。In particular, writesets include indexes defined on invisible columns.特别是,WriteSet包括在不可见列上定义的索引。
The mysqlbinlog command includes visibility in column metadata.mysqlbinlog命令包含列元数据中的可见性。