CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
(create_definition,...)
[table_options]
[partition_options]
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
[(create_definition,...)]
[table_options]
[partition_options]
[IGNORE | REPLACE]
[AS] query_expression
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
{ LIKE old_tbl_name | (LIKE old_tbl_name) }
create_definition: {
col_name column_definition
| {INDEX | KEY} [index_name] [index_type] (key_part,...)
[index_option] ...
| {FULLTEXT | SPATIAL} [INDEX | KEY] [index_name] (key_part,...)
[index_option] ...
| [CONSTRAINT [symbol]] PRIMARY KEY
[index_type] (key_part,...)
[index_option] ...
| [CONSTRAINT [symbol]] UNIQUE [INDEX | KEY]
[index_name] [index_type] (key_part,...)
[index_option] ...
| [CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (col_name,...)
reference_definition
| check_constraint_definition
}
column_definition: {
data_type [NOT NULL | NULL] [DEFAULT {literal | (expr)} ]
[VISIBLE | INVISIBLE]
[AUTO_INCREMENT] [UNIQUE [KEY]] [[PRIMARY] KEY]
[COMMENT 'string']
[COLLATE collation_name]
[COLUMN_FORMAT {FIXED | DYNAMIC | DEFAULT}]
[ENGINE_ATTRIBUTE [=] 'string']
[SECONDARY_ENGINE_ATTRIBUTE [=] 'string']
[STORAGE {DISK | MEMORY}]
[reference_definition]
[check_constraint_definition]
| data_type
[COLLATE collation_name]
[GENERATED ALWAYS] AS (expr)
[VIRTUAL | STORED] [NOT NULL | NULL]
[VISIBLE | INVISIBLE]
[UNIQUE [KEY]] [[PRIMARY] KEY]
[COMMENT 'string']
[reference_definition]
[check_constraint_definition]
}
data_type:
(see Chapter 13, Data Types)
key_part: {col_name [(length)] | (expr)} [ASC | DESC]
index_type:
USING {BTREE | HASH}
index_option: {
KEY_BLOCK_SIZE [=] value
| index_type
| WITH PARSER parser_name
| COMMENT 'string'
| {VISIBLE | INVISIBLE}
|ENGINE_ATTRIBUTE [=] 'string'
|SECONDARY_ENGINE_ATTRIBUTE [=] 'string'
}
check_constraint_definition:
[CONSTRAINT [symbol]] CHECK (expr) [[NOT] ENFORCED]
reference_definition:
REFERENCES tbl_name (key_part,...)
[MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]
[ON DELETE reference_option]
[ON UPDATE reference_option]
reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
table_options:
table_option [[,] table_option] ...
table_option: {
AUTOEXTEND_SIZE [=] value
| AUTO_INCREMENT [=] value
| AVG_ROW_LENGTH [=] value
| [DEFAULT] CHARACTER SET [=] charset_name
| CHECKSUM [=] {0 | 1}
| [DEFAULT] COLLATE [=] collation_name
| COMMENT [=] 'string'
| COMPRESSION [=] {'ZLIB' | 'LZ4' | 'NONE'}
| CONNECTION [=] 'connect_string'
| {DATA | INDEX} DIRECTORY [=] 'absolute path to directory'
| DELAY_KEY_WRITE [=] {0 | 1}
| ENCRYPTION [=] {'Y' | 'N'}
| ENGINE [=] engine_name
| ENGINE_ATTRIBUTE [=] 'string'
| INSERT_METHOD [=] { NO | FIRST | LAST }
| KEY_BLOCK_SIZE [=] value
| MAX_ROWS [=] value
| MIN_ROWS [=] value
| PACK_KEYS [=] {0 | 1 | DEFAULT}
| PASSWORD [=] 'string'
| ROW_FORMAT [=] {DEFAULT | DYNAMIC | FIXED | COMPRESSED | REDUNDANT | COMPACT}
| START TRANSACTION
| SECONDARY_ENGINE_ATTRIBUTE [=] 'string'
| STATS_AUTO_RECALC [=] {DEFAULT | 0 | 1}
| STATS_PERSISTENT [=] {DEFAULT | 0 | 1}
| STATS_SAMPLE_PAGES [=] value
| tablespace_option
| UNION [=] (tbl_name[,tbl_name]...)
}
partition_options:
PARTITION BY
{ [LINEAR] HASH(expr)
| [LINEAR] KEY [ALGORITHM={1 | 2}] (column_list)
| RANGE{(expr) | COLUMNS(column_list)}
| LIST{(expr) | COLUMNS(column_list)} }
[PARTITIONS num]
[SUBPARTITION BY
{ [LINEAR] HASH(expr)
| [LINEAR] KEY [ALGORITHM={1 | 2}] (column_list) }
[SUBPARTITIONS num]
]
[(partition_definition [, partition_definition] ...)]
partition_definition:
PARTITION partition_name
[VALUES
{LESS THAN {(expr | value_list) | MAXVALUE}
|
IN (value_list)}]
[[STORAGE] ENGINE [=] engine_name]
[COMMENT [=] 'string' ]
[DATA DIRECTORY [=] 'data_dir']
[INDEX DIRECTORY [=] 'index_dir']
[MAX_ROWS [=] max_number_of_rows]
[MIN_ROWS [=] min_number_of_rows]
[TABLESPACE [=] tablespace_name]
[(subpartition_definition [, subpartition_definition] ...)]
subpartition_definition:
SUBPARTITION logical_name
[[STORAGE] ENGINE [=] engine_name]
[COMMENT [=] 'string' ]
[DATA DIRECTORY [=] 'data_dir']
[INDEX DIRECTORY [=] 'index_dir']
[MAX_ROWS [=] max_number_of_rows]
[MIN_ROWS [=] min_number_of_rows]
[TABLESPACE [=] tablespace_name]
tablespace_option:
TABLESPACE tablespace_name [STORAGE DISK]
| [TABLESPACE tablespace_name] STORAGE MEMORY
query_expression:
SELECT ... (Some valid select or union statement)
创建表 创建一个具有给定名称的表。你必须拥有该表的 创建 权限。
默认情况下,表是在默认数据库中创建的,使用 InnoDB 存储引擎。如果表已经存在,或者没有默认数据库,或者数据库不存在,将发生错误。
MySQL 没有表的数量限制。底层文件系统可能对表示表的文件数量有限。个别存储引擎可能会施加引擎特定的约束。InnoDB 允许最多 4 亿个表。
有关表的物理表示的信息,请参阅 第 15.1.20.1 节,“CREATE TABLE 创建的文件”。
CREATE TABLE 语句有几个方面,在本节的以下主题中描述:
表名
-
tbl_name可以指定表名为
db_name.tbl_name以在特定数据库中创建表。这适用于是否有默认数据库,假设数据库存在。如果使用引号标识符,分别引号数据库和表名。例如,写作`mydb`.`mytbl`,而不是`mydb.mytbl`。表名的规则在 第 11.2 节,“模式对象名称” 中给出。
-
IF NOT EXISTS防止表已经存在时发生错误。但是,不会验证现有表的结构是否与
CREATE TABLE语句中指定的结构相同。
临时表
您可以在创建表时使用 TEMPORARY 关键字。临时表仅在当前会话中可见,并在会话关闭时自动删除。有关更多信息,请参阅 第 15.1.20.2 节,“CREATE TEMPORARY TABLE 语句”。
表克隆和复制
-
LIKE使用
CREATE TABLE ... LIKE创建一个基于另一个表的空表,包括原始表中的列属性和索引:CREATE TABLE new_tbl LIKE orig_tbl;有关更多信息,请参阅 第 15.1.20.3 节,“CREATE TABLE ... LIKE 语句”。
-
[AS]query_expression要从另一个表创建一个表,请在
CREATE TABLE语句的末尾添加一个SELECT语句:CREATE TABLE new_tbl AS SELECT * FROM orig_tbl;有关更多信息,请参阅 第 15.1.20.4 节,“CREATE TABLE ... SELECT 语句”。
-
IGNORE | REPLACEIGNORE和REPLACE选项指示如何处理使用SELECT语句复制表时的唯一键值重复行。有关更多信息,请参阅 第 15.1.20.4 节,“CREATE TABLE ... SELECT 语句”。
列数据类型和属性
每个表的列数限制为 4096,但实际最大值可能小于该值,具体取决于 第 10.4.7 节,“表列数和行大小限制” 中讨论的因素。
-
data_type数据类型在列定义中表示数据类型。有关指定列数据类型的语法的完整描述,以及每种类型的属性信息,请参阅 第 13 章,数据类型。-
一些属性不适用于所有数据类型。
AUTO_INCREMENT只适用于整数和浮点数类型。使用AUTO_INCREMENT与FLOAT或DOUBLE列在 MySQL 8.0 中已弃用;预计在未来版本的 MySQL 中将删除对其的支持。 -
字符数据类型(
CHAR、VARCHAR、TEXT类型、ENUM、SET及其同义词)可以包括CHARACTER SET以指定列的字符集。CHARSET是CHARACTER SET的同义词。可以使用COLLATE属性指定字符集的排序规则,连同其他属性。有关详细信息,请参阅 第 12 章,字符集、排序规则、Unicode。示例:CREATE TABLE t (c CHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin);MySQL 8.3 将字符列定义中的长度规范解释为字符。
BINARY和VARBINARY的长度是以字节为单位的。 -
对于
CHAR,VARCHAR,BINARY和VARBINARY列,可以创建使用列值的前导部分的索引,使用语法指定索引前缀长度。col_name(length)BLOB和TEXT列也可以被索引,但必须指定前缀长度。前缀长度以字符为单位,对于非二进制字符串类型,以字节为单位,对于二进制字符串类型。也就是说,索引条目由每列值的前length个字符组成,对于CHAR,VARCHAR和TEXT列,和每列值的前length字节,对于BINARY,VARBINARY和BLOB列。这样索引文件可以变得非常小。有关索引前缀的更多信息,请参阅 第 15.1.15 节,“CREATE INDEX 语句”。只有
InnoDB和MyISAM存储引擎支持在BLOB和TEXT列上创建索引。例如:CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));如果指定的索引前缀超过了最大列数据类型大小,
CREATE TABLE将按照以下方式处理索引:-
对于非唯一索引,或者发生错误(如果启用了严格 SQL 模式),或者索引长度将被减少以在最大列数据类型大小内,并生成警告(如果未启用严格 SQL 模式)。
-
对于唯一索引,无论SQL模式如何,因为缩短索引长度可能会启用不满足唯一性要求的非唯一条目插入。
-
-
JSON列不能被索引。您可以通过创建一个从JSON列中提取标量值的生成列的索引来绕过这个限制。请参阅使用生成列提供JSON列索引,以获取详细的示例。
-
-
非空 | 空如果既没有指定
空也没有指定非空,则该列将被视为指定了空。在MySQL 8.3中,只有
InnoDB、MyISAM和MEMORY存储引擎支持对可能包含空值的列的索引。在其他情况下,您必须将索引列声明为非空,否则将出现错误。 -
默认值指定列的默认值。有关默认值处理的更多信息,包括列定义中没有明确指定
默认值的情况,请参阅第13.6节,“数据类型默认值”。如果启用了
NO_ZERO_DATE或NO_ZERO_IN_DATESQL模式,并且日期值默认值不符合该模式,CREATE TABLE将在严格SQL模式未启用时生成警告,在严格模式下生成错误。例如,在NO_ZERO_IN_DATE启用时,c1 DATE DEFAULT '2010-00-00'将生成警告。 -
可见、不可见指定列可见性。默认情况下,如果没有出现关键字,则为
可见。表必须至少有一个可见列。尝试使所有列不可见将产生错误。有关更多信息,请参阅第15.1.20.10节,“不可见列”。 -
自动递增整数或浮点数列可以具有附加属性
AUTO_INCREMENT。当您将值NULL(推荐) 或0插入到索引的AUTO_INCREMENT列中时,该列将设置为下一个序列值。通常这是,其中值+1值是表中当前的最大值。AUTO_INCREMENT序列从1开始。要检索插入行后的
AUTO_INCREMENT值,请使用LAST_INSERT_ID()SQL 函数或mysql_insert_id()C API 函数。见 第 14.15 节,“信息函数”,和 mysql_insert_id()。如果启用了
NO_AUTO_VALUE_ON_ZEROSQL 模式,您可以在AUTO_INCREMENT列中存储0作为0,而不生成新的序列值。见 第 7.1.11 节,“服务器 SQL 模式”。每个表只能有一个
AUTO_INCREMENT列,必须索引,并且不能有DEFAULT值。AUTO_INCREMENT列仅在包含正值时才正常工作。插入负数被视为插入非常大的正数。这是为了避免精度问题,当数字从正数“wrap”到负数时,也确保您不会意外地获得包含0的AUTO_INCREMENT列。对于
MyISAM表,您可以在多列键中指定AUTO_INCREMENT次要列。见 第 5.6.9 节,“使用 AUTO_INCREMENT”。要使 MySQL 与某些 ODBC 应用程序兼容,您可以使用以下查询来查找最后插入行的
AUTO_INCREMENT值:SELECT * FROM tbl_name WHERE auto_col IS NULL此方法要求
sql_auto_is_null变量不设置为 0。见 第 7.1.8 节,“服务器系统变量”。关于
InnoDB和AUTO_INCREMENT的信息,请参阅 第 17.6.1.6 节,“InnoDB 中的 AUTO_INCREMENT 处理”。关于AUTO_INCREMENT和 MySQL 复制的信息,请参阅 第 19.5.1.1 节,“复制和 AUTO_INCREMENT”。 -
COMMENT可以使用
COMMENT选项指定列的注释,长度最多为 1024 个字符。该注释将由SHOW CREATE TABLE和SHOW FULL COLUMNS语句显示。它也将显示在信息模式COLUMNS表的COLUMN_COMMENT列中。 -
COLUMN_FORMAT在 NDB Cluster 中,还可以使用
COLUMN_FORMAT指定单个列的数据存储格式。允许的列格式是FIXED、DYNAMIC和DEFAULT。FIXED用于指定固定宽度存储,DYNAMIC允许列变宽度存储,而DEFAULT导致列使用固定宽度或变宽度存储,具体取决于列的数据类型(可能被ROW_FORMAT指定符覆盖)。对于
NDB表,默认的COLUMN_FORMAT值是FIXED。在 NDB Cluster 中,使用
COLUMN_FORMAT=FIXED定义的列的最大可能偏移量为 8188 字节。有关更多信息和可能的解决方法,请参阅 第 25.2.7.5 节,“NDB Cluster 中的数据库对象限制”。COLUMN_FORMAT目前对使用存储引擎以外的NDB的表的列没有影响。MySQL 8.3 会默默忽略COLUMN_FORMAT。 -
ENGINE_ATTRIBUTE和SECONDARY_ENGINE_ATTRIBUTE选项用于指定主存储引擎和辅助存储引擎的列属性。这些选项保留供将来使用。允许的值是一个包含有效
JSON文档的字符串文字或空字符串 ('')。无效的JSON将被拒绝。CREATE TABLE t1 (c1 INT ENGINE_ATTRIBUTE='{"key":"value"}');ENGINE_ATTRIBUTE和SECONDARY_ENGINE_ATTRIBUTE值可以重复指定,而不报错。在这种情况下,将使用最后指定的值。ENGINE_ATTRIBUTE和SECONDARY_ENGINE_ATTRIBUTE值不会被服务器检查,也不会在更改表的存储引擎时被清除。 -
STORAGE对于
NDB表,可以使用STORAGE子句指定列是否存储在磁盘上或在内存中。STORAGE DISK导致列存储在磁盘上,而STORAGE MEMORY导致在内存中存储。用于创建表的CREATE TABLE语句仍然需要包含TABLESPACE子句:mysql> CREATE TABLE t1 ( -> c1 INT STORAGE DISK, -> c2 INT STORAGE MEMORY -> ) ENGINE NDB; ERROR 1005 (HY000): Can't create table 'c.t1' (errno: 140) mysql> CREATE TABLE t1 ( -> c1 INT STORAGE DISK, -> c2 INT STORAGE MEMORY -> ) TABLESPACE ts_1 ENGINE NDB; Query OK, 0 rows affected (1.06 sec)对于
NDB表,STORAGE DEFAULT等同于STORAGE MEMORY。对于使用其他存储引擎的表,
STORAGE子句没有任何效果。STORAGE关键字仅在与 NDB 集群一起提供的 mysqld 版本中受支持;在其他版本的 MySQL 中,尝试使用STORAGE关键字将导致语法错误。 -
GENERATED ALWAYS用于指定生成列表达式。有关 生成列 的信息,请参阅 第 15.1.20.8 节,“CREATE TABLE 和生成列”。
存储生成列 可以被索引。
InnoDB支持虚拟生成列的二级索引。见 第 15.1.20.9 节,“二级索引和生成列”。
索引、外键和 CHECK 约束
几个关键字应用于创建索引、外键和 CHECK 约束。除了以下描述外,还可以查看 第 15.1.15 节,“CREATE INDEX 语句”、第 15.1.20.5 节,“外键约束” 和 第 15.1.20.6 节,“CHECK 约束”。
-
约束符号该
约束子句可以用于命名约束。如果该子句未给出,或者符号符号未在约束关键字后面使用,MySQL 将自动生成一个约束名称,除非以下情况。该符号值,如果使用,必须在每个模式(数据库)中唯一,且每种约束类型中唯一。重复的符号将导致错误。见也 第 11.2.1 节,“标识符长度限制” 中关于生成约束标识符的长度限制的讨论。Note如果在外键定义中未给出
约束子句,或者符号符号未在约束关键字后面使用,MySQL 将自动生成一个约束名称。SQL 标准规定所有类型的约束(主键、唯一索引、外键、检查)属于同一个命名空间。在 MySQL 中,每种约束类型在每个模式中都有其自己的命名空间。因此,每种约束类型的名称必须在每个模式中唯一,但不同类型的约束可以具有相同的名称。
-
主键一个唯一索引,其中所有键列必须定义为
NOT NULL。如果它们没有明确声明为NOT NULL,MySQL 将隐式地(并且沉默地)声明它们。一个表只能有一个主键。主键的名称总是主键,因此不能用作其他类型索引的名称。如果您没有在表中指定
PRIMARY KEY,而应用程序请求表中的PRIMARY KEY,MySQL 将返回第一个没有NULL列的唯一索引作为PRIMARY KEY。在
InnoDB表中,请保持PRIMARY KEY短,以最小化次要索引的存储开销。每个次要索引条目都包含相应行的主键列的副本。(见 第 17.6.2.1 节,“聚簇索引和次要索引”。)在创建的表中,首先放置
PRIMARY KEY,然后是所有UNIQUE索引,最后是非唯一索引。这有助于 MySQL 优化器确定使用哪个索引,并更快地检测到重复的UNIQUE键。一个
PRIMARY KEY可以是一个多列索引。但是,您不能在列规范中使用PRIMARY KEY键属性来创建多列索引。这样做只标记该单个列为主键。您必须使用单独的PRIMARY KEY(子句。key_part, ...)如果表具有
PRIMARY KEY或UNIQUE NOT NULL索引,该索引由单个整数类型列组成,您可以在SELECT语句中使用_rowid引用该索引列,如 唯一索引 中所述。在 MySQL 中,
PRIMARY KEY的名称是PRIMARY。对于其他索引,如果您不分配名称,索引将被分配与第一个索引列相同的名称,带有可选的后缀 (_2,_3,...) 以使其唯一。您可以使用SHOW INDEX FROM查看表的索引名称。见 第 15.7.7.23 节,“SHOW INDEX 语句”。tbl_name -
KEY | INDEXKEY通常是INDEX的同义词。在列定义中,键属性PRIMARY KEY也可以指定为只是KEY。这是在与其他数据库系统兼容时实现的。 -
UNIQUE一个
UNIQUE索引创建了一个约束,使得索引中的所有值必须是不同的。如果您尝试添加一个新行,其中的键值与现有行匹配,将发生错误。对于所有引擎,UNIQUE索引允许包含NULL值的列中有多个NULL值。如果您为UNIQUE索引中的列指定了前缀值,则该列的值必须在前缀长度内唯一。如果一个表具有
PRIMARY KEY或UNIQUE NOT NULL索引,该索引由单个整数类型的列组成,您可以在SELECT语句中使用_rowid引用该索引列,如 唯一索引 中所述。 -
FULLTEXT一个
FULLTEXT索引是一种特殊类型的索引,用于全文搜索。只有InnoDB和MyISAM存储引擎支持FULLTEXT索引。它们只能从CHAR、VARCHAR和TEXT列中创建。索引总是整个列的;列前缀索引不支持,并且如果指定了前缀长度将被忽略。请参阅 第 14.9 节,“全文搜索函数”,了解详细信息。可以指定一个WITH PARSER子句作为index_option值,以关联一个解析器插件与索引,如果全文索引和搜索操作需要特殊处理。该子句仅对FULLTEXT索引有效。InnoDB和MyISAM支持全文解析器插件。请参阅 全文解析器插件 和 编写全文解析器插件,了解更多信息。 -
SPATIAL您可以在空间数据类型上创建
SPATIAL索引。空间类型仅支持InnoDB和MyISAM表,并且索引列必须声明为NOT NULL。请参阅 第 13.4 节,“空间数据类型”。 -
外键MySQL 支持外键,让您可以跨表引用相关数据,并且外键约束有助于保持这些分布式数据的一致性。有关定义和选项信息,请参阅
reference_definition和reference_option。使用
InnoDB存储引擎的分区表不支持外键。请参阅 第 26.6 节,“分区限制”,以获取更多信息。 -
CHECKCHECK子句启用了在表行中检查数据值的约束。请参阅 第 15.1.20.6 节,“CHECK 约束”。 -
key_part-
一个
key_part规范可以以ASC或DESC结尾,以指定索引值是否以升序或降序存储。默认情况下,如果没有指定顺序,则为升序。 -
前缀,由
length属性定义,可以长达 767 字节,用于InnoDB表,该表使用REDUNDANT或COMPACT行格式。对于使用DYNAMIC或COMPRESSED行格式的InnoDB表,前缀长度限制为 3072 字节。对于MyISAM表,前缀长度限制为 1000 字节。前缀 限制 以字节为单位测量。然而,前缀 长度 在
CREATE TABLE、ALTER TABLE和CREATE INDEX语句中被解释为非二进制字符串类型(CHAR、VARCHAR、TEXT)的字符数和二进制字符串类型(BINARY、VARBINARY、BLOB)的字节数。在指定非二进制字符串列的前缀长度时,请注意这一点。 -
表达式
expr对于key_part规范可以采用(CAST的形式,以在json_pathAStypeARRAY)JSON列上创建多值索引。多值索引 提供了有关创建、使用和多值索引的限制和限制的详细信息。
-
-
index_type一些存储引擎允许您在创建索引时指定索引类型。语法为
index_type规范是USING。type_name示例:
CREATE TABLE lookup (id INT, INDEX USING BTREE (id)) ENGINE = MEMORY;首选的
USING位置是在索引列列表之后。它可以在列列表之前给出,但支持在该位置使用该选项已经弃用,并且您应该期望在未来 MySQL 版本中删除该选项。 -
index_optionindex_option值指定索引的其他选项。-
KEY_BLOCK_SIZE对于
MyISAM表,KEY_BLOCK_SIZE可选地指定索引键块的大小(以字节为单位)。该值被视为提示;如果必要,可以使用不同的大小。单个索引定义中的KEY_BLOCK_SIZE值将覆盖表级KEY_BLOCK_SIZE值。有关表级
KEY_BLOCK_SIZE属性的信息,请参阅 表选项。 -
WITH PARSERWITH PARSER选项只能与FULLTEXT索引一起使用。它将解析器插件与索引关联,以便在全文索引和搜索操作需要特殊处理时使用。InnoDB和MyISAM都支持全文解析器插件。如果您有一个MyISAM表带有关联的全文解析器插件,可以使用ALTER TABLE将其转换为InnoDB。 -
COMMENT索引定义可以包括一个可选的注释,最多 1024 个字符。
您可以使用
COMMENT子句设置单个索引的InnoDBMERGE_THRESHOLD值。请参阅 第 17.8.11 节,“配置索引页合并阈值”。 -
VISIBLE,INVISIBLE指定索引可见性。索引默认情况下是可见的。不可见的索引不会被优化器使用。索引可见性规则适用于除主键(明确或隐式)以外的所有索引。有关更多信息,请参阅 第 10.3.12 节,“不可见索引”。
-
ENGINE_ATTRIBUTE和SECONDARY_ENGINE_ATTRIBUTE选项用于指定主存储引擎和次要存储引擎的索引属性。这些选项保留供将来使用。
有关允许的
index_option值的更多信息,请参阅 第 15.1.15 节,“CREATE INDEX 语句”。有关索引的更多信息,请参阅 第 10.3.1 节,“MySQL 如何使用索引”。 -
-
有关
引用定义语法详细信息和示例,请参阅 第 15.1.20.5 节,“外键约束”。InnoDB和NDB表支持外键约束的检查。被引用表的列必须始终被明确命名。同时支持ON DELETE和ON UPDATE动作对外键的支持。有关详细信息和示例,请参阅 第 15.1.20.5 节,“外键约束”。对于其他存储引擎,MySQL 服务器将解析并忽略
FOREIGN KEY语法在CREATE TABLE语句中。Important对于熟悉 ANSI/ISO SQL 标准的用户,请注意,无论是
InnoDB还是其他存储引擎,都不识别或执行MATCH子句在参照完整性约束定义中。使用明确的MATCH子句不会产生指定的效果,并且还会导致ON DELETE和ON UPDATE子句被忽略。因此,指定MATCH应该被避免。SQL 标准中的
MATCH子句控制在复合(多列)外键中如何处理 NULL 值的比较,以便与主键进行比较。InnoDB实质上实现了MATCH SIMPLE的语义,这允许外键全部或部分为 NULL。在这种情况下,包含这种外键的(子表)行将被允许插入,并且不匹配父表中的任何行。可以使用触发器来实现其他语义。此外,MySQL 还要求被引用的列被索引以提高性能。然而,
InnoDB不会强制被引用的列被声明为UNIQUE或NOT NULL。对于操作如UPDATE或DELETE CASCADE,外键引用非唯一键或包含 NULL 值的键的处理方式未定义。你被建议使用外键,仅引用唯一的(或 PRIMARY)且非 NULL 的键。MySQL 解析但忽略 “内联
REFERENCES规范”(如 SQL 标准所定义),其中引用是在列规范的一部分中定义的。MySQL 只接受REFERENCES子句,当它们作为单独的FOREIGN KEY规范的一部分时。有关更多信息,请参阅 第 1.6.2.3 节,“外键约束差异”。 -
有关
RESTRICT、CASCADE、SET NULL、NO ACTION和SET DEFAULT选项的信息,请参阅 第 15.1.20.5 节,“外键约束”。
表选项
表选项用于优化表的行为。在大多数情况下,您不需要指定任何选项。这些选项适用于所有存储引擎,除非另有说明。某些存储引擎不支持的选项将被接受和记忆为表定义的一部分。如果您稍后使用 ALTER TABLE 将表转换为使用不同的存储引擎,则这些选项将生效。
-
ENGINE指定表的存储引擎,使用以下表格中的一个名称。引擎名称可以是未引用的或引用的。引用的名称
'DEFAULT'将被识别但忽略。Storage Engine Description InnoDB事务安全的表,具有行锁定和外键。默认的存储引擎为新表。请参阅 第 17 章,《InnoDB 存储引擎》,特别是 第 17.1 节,“InnoDB 简介”,如果您有 MySQL 经验但对 InnoDB 不熟悉。 MyISAM二进制可移植存储引擎,主要用于只读或大多数读取工作负载。请参阅 第 18.2 节,“MyISAM 存储引擎”。 MEMORY该存储引擎的数据仅存储在内存中。请参阅 第 18.3 节,“MEMORY 存储引擎”。 CSV以逗号分隔值格式存储行的表格。见第 18.4 节,“CSV 存储引擎”。 ARCHIVE存档存储引擎。见第 18.5 节,“ARCHIVE 存储引擎”。 EXAMPLE示例引擎。见第 18.9 节,“EXAMPLE 存储引擎”。 FEDERATED访问远程表的存储引擎。见第 18.8 节,“FEDERATED 存储引擎”。 HEAP这是 MEMORY的同义词。MERGE多个 MyISAM表格组合成一个表格。也称为MRG_MyISAM。见第 18.7 节,“MERGE 存储引擎”。NDB集群、容错、基于内存的表格,支持事务和外键。也称为 NDBCLUSTER。见第 25 章,《MySQL NDB Cluster 8.3》。默认情况下,如果指定的存储引擎不可用,则语句将失败并显示错误。你可以通过从服务器 SQL 模式中删除
NO_ENGINE_SUBSTITUTION(见第 7.1.11 节,“服务器 SQL 模式”),以便 MySQL 允许将指定的引擎替换为默认存储引擎,而不是失败。在这种情况下,默认值通常是InnoDB,它是default_storage_engine系统变量的默认值。当NO_ENGINE_SUBSTITUTION被禁用时,如果存储引擎指定不被遵守,将发生警告。 -
AUTOEXTEND_SIZE定义了当
InnoDB表空间变满时扩展表空间的大小。该设置必须是4MB的倍数。默认设置为0,这将导致表空间根据隐式默认行为扩展。有关更多信息,请参阅第 17.6.3.9 节,“表空间 AUTOEXTEND_SIZE 配置”。 -
AUTO_INCREMENT表的初始
AUTO_INCREMENT值。在 MySQL 8.3 中,这适用于MyISAM、MEMORY、InnoDB和ARCHIVE表。要设置不支持AUTO_INCREMENT表选项的引擎的第一个自动递增值,请在创建表后插入一个值小于所需值的“dummy”行,然后删除 dummy 行。对于支持
AUTO_INCREMENT表选项的引擎,在CREATE TABLE语句中,您也可以使用ALTER TABLE重置tbl_nameAUTO_INCREMENT =NAUTO_INCREMENT值。该值不能设置为小于当前列中的最大值。 -
AVG_ROW_LENGTH表的平均行长度近似值。您只需要为具有可变大小行的大型表设置此值。
当您创建
MyISAM表时,MySQL 使用MAX_ROWS和AVG_ROW_LENGTH选项的乘积来确定结果表的大小。如果您不指定任何选项,默认情况下MyISAM数据和索引文件的最大大小为 256TB。(如果您的操作系统不支持如此大的文件,表大小将受到文件大小限制的约束。)如果您想减少指针大小以使索引变得更小和更快,并且您不需要大文件,可以通过设置myisam_data_pointer_size系统变量来实现。(见 第 7.1.8 节,“服务器系统变量”。)如果您想让所有表都可以增长到默认限制以上,并且您愿意让表变得稍慢一些和更大一些,可以通过设置该变量来实现。将该值设置为 7 可以使表大小达到 65,536TB。 -
[DEFAULT] 字符集指定表的默认字符集。
CHARSET是CHARACTER SET的同义词。如果字符集名称是DEFAULT,则使用数据库字符集。 -
CHECKSUM如果您想让 MySQL 为所有行维护实时校验和(即,随着表的变化自动更新的校验和),请将其设置为 1。这将使表更新速度变慢,但也使得发现损坏的表变得更容易。
CHECKSUM TABLE语句报告校验和。(仅适用于MyISAM。) -
[DEFAULT] COLLATE指定表的默认排序规则。
-
COMMENT表的注释,最长 2048 个字符。
您可以使用
COMMENT子句设置InnoDB的MERGE_THRESHOLD值。请参阅 第 17.8.11 节,“配置索引页合并阈值”。设置 NDB_TABLE 选项。 在创建
NDB表或修改表时,表注释也可以用于指定一个到四个NDB_TABLE选项NOLOGGING、READ_BACKUP、PARTITION_BALANCE或FULLY_REPLICATED,以逗号分隔的名称-值对,紧跟在以NDB_TABLE=开头的引号内的注释文本中。示例语句如下(加粗文本):CREATE TABLE t1 ( c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY, c2 VARCHAR(100), c3 VARCHAR(100) ) ENGINE=NDB COMMENT="NDB_TABLE=READ_BACKUP=0,PARTITION_BALANCE=FOR_RP_BY_NODE";引号字符串中不允许有空格。字符串不区分大小写。
注释将作为
SHOW CREATE TABLE输出的一部分显示。注释文本也可作为 MySQL 信息模式TABLES表的 TABLE_COMMENT 列。该注释语法也支持
ALTER TABLE语句用于NDB表。请注意,使用ALTER TABLE语句的表注释将替换表的任何现有注释。在表注释中设置
MERGE_THRESHOLD选项不支持NDB表(它将被忽略)。有关完整的语法信息和示例,请参阅 第 15.1.20.12 节,“设置 NDB 注释选项”。
-
COMPRESSION用于
InnoDB表的页面级压缩的压缩算法。支持的值包括Zlib、LZ4和None。COMPRESSION属性是在透明页压缩功能中引入的。页面压缩仅支持InnoDB表,该表驻留在 每个表文件 表空间中,并且仅在支持稀疏文件和 hole punching 的 Linux 和 Windows 平台上可用。有关更多信息,请参阅 第 17.9.2 节,“InnoDB 页压缩”。 -
CONNECTION联邦表的连接字符串。
Note旧版本的 MySQL 使用
COMMENT选项来指定连接字符串。 -
DATA DIRECTORY、INDEX DIRECTORY对于
InnoDB,DATA DIRECTORY='子句允许在数据目录外创建表。directory'innodb_file_per_table变量必须启用以使用DATA DIRECTORY子句。必须指定完整的目录路径,并且InnoDB必须知道该路径。有关更多信息,请参阅 第 17.6.1.2 节,“外部创建表”。创建
MyISAM表时,可以使用DATA DIRECTORY='子句、directory'INDEX DIRECTORY='子句或两者。它们指定了directory'MyISAM表的数据文件和索引文件的位置。与InnoDB表不同,MySQL 不会在创建带有DATA DIRECTORY或INDEX DIRECTORY选项的MyISAM表时创建对应数据库名称的子目录。文件将被创建在指定的目录中。您必须拥有
FILE权限以使用DATA DIRECTORY或INDEX DIRECTORY表选项。Important表级
DATA DIRECTORY和INDEX DIRECTORY选项将被忽略对于分区表。(Bug #32091)这些选项仅在不使用
--skip-symbolic-links选项时生效。您的操作系统还必须具有一个工作的、线程安全的realpath()调用。请参阅第 10.12.2.2 节,“使用 Unix 上的符号链接为 MyISAM 表”,以获取更多信息。如果创建了一个没有
DATA DIRECTORY选项的 MyISAM 表,则.MYD文件将在数据库目录中创建。默认情况下,如果 MyISAM 在这种情况下找到现有的.MYD文件,它将覆盖它。对于创建了没有INDEX DIRECTORY选项的表也是如此,.MYI文件也是如此。要抑制这种行为,请使用--keep_files_on_create选项启动服务器,在这种情况下 MyISAM 不会覆盖现有的文件,而是返回错误。如果创建了一个具有
DATA DIRECTORY或INDEX DIRECTORY选项的 MyISAM 表,并且找到现有的.MYD或.MYI文件,MyISAM 将总是返回错误,不会覆盖指定目录中的文件。Important您不能使用包含 MySQL 数据目录的路径名与
DATA DIRECTORY或INDEX DIRECTORY。这包括分区表和单个表分区。(参见 Bug #32167。) -
DELAY_KEY_WRITE如果您想延迟表的键更新直到表关闭,请将其设置为 1。请参阅
delay_key_write系统变量的描述,在第 7.1.8 节,“服务器系统变量”中。(仅适用于 MyISAM。) -
ENCRYPTIONENCRYPTION子句启用或禁用 InnoDB 表的页面级数据加密。必须安装并配置密钥环插件才能启用加密。ENCRYPTION子句可以在创建文件每个表的表空间或创建通用表空间中的表时指定。如果没有指定
ENCRYPTION子句,表将继承默认模式加密。如果启用了table_encryption_privilege_check变量,创建表时需要TABLE_ENCRYPTION_ADMIN权限,以便在加密设置与默认模式加密不同。当在通用表空间中创建表时,表和表空间加密必须匹配。在使用不支持加密的存储引擎时,不允许在
ENCRYPTION子句中指定除'N'或''以外的值。有关更多信息,请参阅第 17.13 节,“InnoDB 静态加密”。
-
选项
ENGINE_ATTRIBUTE和SECONDARY_ENGINE_ATTRIBUTE用于指定主存储引擎和次要存储引擎的表属性。这些选项保留供将来使用。允许的值是一个包含有效
JSON文档的字符串文字或空字符串('')。无效的JSON将被拒绝。CREATE TABLE t1 (c1 INT) ENGINE_ATTRIBUTE='{"key":"value"}';ENGINE_ATTRIBUTE和SECONDARY_ENGINE_ATTRIBUTE值可以重复指定,而不会出错。在这种情况下,将使用最后指定的值。ENGINE_ATTRIBUTE和SECONDARY_ENGINE_ATTRIBUTE值不会被服务器检查,也不会在更改表的存储引擎时被清除。 -
INSERT_METHOD如果要将数据插入
MERGE表,必须使用INSERT_METHOD指定要插入的表。INSERT_METHOD选项仅适用于MERGE表。使用FIRST或LAST值将插入到第一个或最后一个表中,或者使用NO值来防止插入。请参阅第 18.7 节,“MERGE 存储引擎”。 -
KEY_BLOCK_SIZE对于
MyISAM表,KEY_BLOCK_SIZE可选地指定索引键块的大小(以字节为单位)。该值被视为提示;如果必要,可以使用不同的大小。单个索引定义中的KEY_BLOCK_SIZE值将覆盖表级KEY_BLOCK_SIZE值。对于
InnoDB表,KEY_BLOCK_SIZE指定了以千字节为单位的 页 大小,以便于 压缩InnoDB表。KEY_BLOCK_SIZE值被视为提示;如果必要,InnoDB可能会使用不同的大小。KEY_BLOCK_SIZE只能小于或等于innodb_page_size值。 值为 0 代表默认的压缩页大小,即innodb_page_size值的一半。 根据innodb_page_size,可能的KEY_BLOCK_SIZE值包括 0、1、2、4、8 和 16。 请参阅 第 17.9.1 节,“InnoDB 表压缩” 以获取更多信息。Oracle 建议在指定
KEY_BLOCK_SIZE时启用innodb_strict_mode。 当innodb_strict_mode启用时,指定无效的KEY_BLOCK_SIZE值将返回错误。 如果innodb_strict_mode未启用,无效的KEY_BLOCK_SIZE值将导致警告,并且KEY_BLOCK_SIZE选项将被忽略。在响应
SHOW TABLE STATUS时,Create_options列将报告表实际使用的KEY_BLOCK_SIZE,同样也可以通过SHOW CREATE TABLE查看。InnoDB只支持表级别的KEY_BLOCK_SIZE。KEY_BLOCK_SIZE不支持 32KB 和 64KB 的innodb_page_size值。InnoDB表压缩不支持这些页大小。InnoDB不支持在创建临时表时使用KEY_BLOCK_SIZE选项。 -
MAX_ROWS您计划在表中存储的最大行数。这不是一个硬性限制,而是一个对存储引擎的提示,表明表必须能够存储至少这么多行。
Important使用
MAX_ROWS与NDB表来控制表分区的数量已经弃用。它在后续版本中仍然受到支持,以便向后兼容,但可能在未来版本中被删除。请使用 PARTITION_BALANCE 代替;请参阅 设置 NDB_TABLE 选项。NDB存储引擎将该值视为最大值。如果您计划创建非常大的 NDB 集群表(包含数百万行),您应该使用该选项,以确保NDB在哈希表中分配足够的索引槽,以存储主键的哈希值,方法是将MAX_ROWS = 2 *,其中rowsrows是您计划插入表中的行数。最大
MAX_ROWS值为 4294967295;较大的值将被截断到该限制。 -
MIN_ROWS您计划在表中存储的最小行数。
MEMORY存储引擎使用该选项作为内存使用的提示。 -
PACK_KEYS仅对
MyISAM表生效。如果您想拥有较小的索引,请将该选项设置为 1。这通常使更新变慢,读取变快。将该选项设置为 0 将禁用所有键的打包。将其设置为DEFAULT将告诉存储引擎仅打包长CHAR、VARCHAR、BINARY或VARBINARY列。如果您不使用
PACK_KEYS,则默认情况下将打包字符串,但不包括数字。如果您使用PACK_KEYS=1,数字也将被打包。在打包二进制数字键时,MySQL 使用前缀压缩:
-
每个键需要一个额外的字节来指示前一个键的多少字节与下一个键相同。
-
行指针以高字节优先顺序直接存储在键之后,以提高压缩率。
这意味着,如果您在两个连续的行上有许多相等的键,那么所有后续的“相同”的键通常只需要两个字节(包括指向行的指针)。将其与普通情况进行比较,其中后续键需要
storage_size_for_key + pointer_size(其中指针大小通常为 4)。相反,只有当您有许多相同的数字时,才会从前缀压缩中获得显著的益处。如果所有键完全不同,那么您将使用每个键多一个字节,除非该键不能具有NULL值。(在这种情况下,压缩键长度将存储在同一个字节中,该字节用于标记键是否为NULL。) -
-
密码此选项未使用。
-
行格式定义行以物理格式存储。
当创建表时禁用 严格模式,存储引擎的默认行格式将被使用,如果指定的行格式不受支持。实际的行格式将在
Row_format列中报告,以响应SHOW TABLE STATUS。Create_options列显示了在CREATE TABLE语句中指定的行格式,也显示在SHOW CREATE TABLE中。不同的存储引擎对行格式的选择不同。
对于
InnoDB表:-
默认的行格式由
innodb_default_row_format定义,默认设置为DYNAMIC。当ROW_FORMAT选项未定义或使用ROW_FORMAT=DEFAULT时,将使用默认行格式。如果
ROW_FORMAT选项未定义,或者使用ROW_FORMAT=DEFAULT,重建表的操作也将默默地将表的行格式更改为由innodb_default_row_format定义的默认行格式。有关更多信息,请参阅 定义表的行格式。 -
为了更高效地存储数据类型,特别是
BLOB类型,使用DYNAMIC。请参阅DYNAMIC 行格式以了解与DYNAMIC行格式相关的要求。 -
要为
InnoDB表启用压缩,请指定ROW_FORMAT=COMPRESSED。ROW_FORMAT=COMPRESSED选项不支持创建临时表。请参阅第 17.9 节,“InnoDB 表和页压缩”以了解与COMPRESSED行格式相关的要求。 -
旧版本 MySQL 中使用的行格式仍可以通过指定
REDUNDANT行格式来请求。 -
当您指定非默认的
ROW_FORMAT子句时,请考虑也启用innodb_strict_mode配置选项。 -
ROW_FORMAT=FIXED不支持。如果在innodb_strict_mode禁用时指定ROW_FORMAT=FIXED,InnoDB将发出警告并假设ROW_FORMAT=DYNAMIC。如果在innodb_strict_mode启用时指定ROW_FORMAT=FIXED,InnoDB将返回错误。 -
有关
InnoDB行格式的更多信息,请参阅第 17.10 节,“InnoDB 行格式”。
对于
MyISAM表,选项值可以是FIXED或DYNAMIC,用于静态或变长行格式。myisampack将类型设置为COMPRESSED。请参阅第 18.2.3 节,“MyISAM 表存储格式”。对于
NDB表,默认的ROW_FORMAT是DYNAMIC。 -
-
START TRANSACTION这是一个内部使用的表选项,用于允许在使用基于行的复制和支持原子DDL的存储引擎时,将
CREATE TABLE ... SELECT记录为单个原子事务在二进制日志中。只有BINLOG、COMMIT和ROLLBACK语句在CREATE TABLE ... START TRANSACTION后被允许。有关信息,请参阅第 15.1.1 节,“原子数据定义语句支持”。 -
STATS_AUTO_RECALC指定是否自动重新计算持久统计信息用于
InnoDB表。值DEFAULT导致表的持久统计信息设置由innodb_stats_auto_recalc配置选项确定。值1导致统计信息在表中的 10% 数据更改时重新计算。值0防止自动重新计算此表;使用此设置后,发出ANALYZE TABLE语句重新计算统计信息,after making substantial changes to the table。有关持久统计信息功能的更多信息,请参阅第 17.8.10.1 节,“配置持久优化器统计参数”。 -
STATS_PERSISTENT指定是否为 持久统计 启用
InnoDB表。值DEFAULT导致表的持久统计设置由innodb_stats_persistent配置选项确定。值1启用表的持久统计,而值0关闭该功能。在通过CREATE TABLE或ALTER TABLE语句启用持久统计后,发出ANALYZE TABLE语句来计算统计信息,在加载表中的代表性数据后。有关持久统计功能的更多信息,请参阅 第 17.8.10.1 节,“配置持久优化器统计参数”。 -
STATS_SAMPLE_PAGES当估算索引列的基数和其他统计信息时,采样索引页的数量,例如由
ANALYZE TABLE计算的统计信息。有关更多信息,请参阅 第 17.8.10.1 节,“配置持久优化器统计参数”。 -
TABLESPACE可以使用
TABLESPACE子句在现有的通用表空间、每个表文件表空间或系统表空间中创建InnoDB表。CREATE TABLE tbl_name ... TABLESPACE [=] tablespace_name在使用
TABLESPACE子句之前,必须先创建通用表空间。有关通用表空间的信息,请参阅 第 17.6.3.3 节,“通用表空间”。指定的
是一个区分大小写的标识符。它可以是带引号或不带引号的。斜杠字符 (“/”) 不允许使用。以 “innodb_” 开头的名称保留用于特殊用途。tablespace_name要在系统表空间中创建表,请指定
innodb_system作为表空间名称。CREATE TABLE tbl_name ... TABLESPACE [=] innodb_system使用
TABLESPACE [=] innodb_system,您可以将任何未压缩的行格式表放在系统表空间中,不管innodb_file_per_table设置如何。例如,您可以使用TABLESPACE [=] innodb_system将具有ROW_FORMAT=DYNAMIC的表添加到系统表空间中。要在每个表的表空间中创建表,请指定
innodb_file_per_table作为表空间名称。CREATE TABLE tbl_name ... TABLESPACE [=] innodb_file_per_tableNote如果
innodb_file_per_table已启用,则无需指定TABLESPACE=innodb_file_per_table来创建 InnoDB 每个表的表空间。InnoDB表默认情况下在每个表的表空间中创建,当innodb_file_per_table已启用时。在
CREATE TABLE ... TABLESPACE=innodb_file_per_table中允许使用DATA DIRECTORY子句,但否则不支持与TABLESPACE子句结合使用。DATA DIRECTORY子句中指定的目录必须是InnoDB已知的目录。有关更多信息,请参阅 使用 DATA DIRECTORY 子句。Note对
TABLESPACE = innodb_file_per_table和TABLESPACE = innodb_temporary子句与CREATE TEMPORARY TABLE的支持将被弃用;预计在未来版本的 MySQL 中删除。STORAGE表选项仅用于NDB表。STORAGE确定存储类型,可以是DISK或MEMORY。TABLESPACE ... STORAGE DISK将表分配给 NDB Cluster 磁盘数据表空间。STORAGE DISK不能在CREATE TABLE中使用,除非在TABLESPACEtablespace_name之前。对于
STORAGE MEMORY,表空间名称是可选的,因此您可以使用TABLESPACE或简单地使用tablespace_nameSTORAGE MEMORYSTORAGE MEMORY来明确指定表是在内存中的。请参阅 第 25.6.11 节,“NDB Cluster 磁盘数据表”,以获取更多信息。
-
用于访问一组相同的
MyISAM表作为一个表。这只适用于MERGE表。请参阅 第 18.7 节,“MERGE 存储引擎”。您必须拥有
SELECT、UPDATE和DELETE权限,以便在MERGE表中映射表。Note以前,所有用于映射的表都必须在与
MERGE表相同的数据库中。这项限制不再适用。
表分区
partition_options 可以用来控制使用 CREATE TABLE 创建的表的分区。
在本节开头显示的 partition_options 语法中,不是所有选项都适用于所有分区类型。请参阅每种类型的单独列表,以获取特定于每种类型的信息,并参阅 第 26 章,分区,以获取 MySQL 中分区的工作原理和用途的更多信息,以及 MySQL 分区相关的其他语句示例。
可以修改、合并、添加到表中和从表中删除分区。有关执行这些任务的 MySQL 语句的基本信息,请参阅 第 15.1.9 节,“ALTER TABLE 语句”。有关详细描述和示例,请参阅 第 26.3 节,“分区管理”。
-
PARTITION BY如果使用,
partition_options子句以PARTITION BY开头。该子句包含确定分区的函数,该函数返回一个从 1 到num的整数值,其中num是分区的数量。(用户定义的分区的最大数量为 1024;子分区的数量也包括在这个最大值中。)Note在
PARTITION BY子句中使用的表达式 (expr) 不能引用创建表以外的任何列;这种引用将导致语句失败并出现错误。(Bug #29444) -
HASH(expr)使用一个或多个列创建键以便放置和定位行。
expr是使用一个或多个表列的表达式。它可以是任何有效的 MySQL 表达式(包括 MySQL 函数),生成单个整数值。例如,这些都是使用PARTITION BY HASH的有效CREATE TABLE语句:CREATE TABLE t1 (col1 INT, col2 CHAR(5)) PARTITION BY HASH(col1); CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) PARTITION BY HASH ( YEAR(col3) );您不能在
PARTITION BY HASH中使用VALUES LESS THAN或VALUES IN子句。PARTITION BY HASH使用expr除以分区数(即余数)。有关示例和更多信息,请参阅 第 26.2.4 节,“HASH 分区”。关键字
LINEAR涉及到一种不同的算法。在这种情况下,行存储在哪个分区中的编号是通过一个或多个逻辑AND操作的结果计算得出。有关线性哈希的讨论和示例,请参阅 第 26.2.4.1 节,“LINEAR HASH 分区”。 -
KEY(column_list)这与
HASH相似,除了 MySQL 提供哈希函数以确保数据分布均匀。column_list参数只是一个表列的列表(最多 16 个)。这个示例显示了一个简单的按键分区的表,具有 4 个分区:CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY(col3) PARTITIONS 4;对于按键分区的表,您可以使用
LINEAR关键字来实现线性分区。这与使用HASH的效果相同,即使用&操作符而不是余数(参阅 第 26.2.4.1 节,“LINEAR HASH 分区” 和 第 26.2.5 节,“KEY 分区”,以获取详细信息)。这个示例使用线性按键分区将数据分布到 5 个分区中:CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY LINEAR KEY(col3) PARTITIONS 5;该
ALGORITHM={1 | 2}选项支持[SUB]PARTITION BY [LINEAR] KEY。ALGORITHM=1导致服务器使用与 MySQL 5.1 相同的键哈希函数;ALGORITHM=2表示服务器使用默认的键哈希函数,用于 MySQL 5.5 及更高版本的新建KEY分区表。(使用 MySQL 5.5 及更高版本的键哈希函数创建的分区表无法被 MySQL 5.1 服务器使用。)不指定该选项的效果与使用ALGORITHM=2相同。该选项主要用于在 MySQL 5.1 和更高版本之间升级或降级[LINEAR] KEY分区表,或者在 MySQL 5.5 或更高版本服务器上创建KEY或LINEAR KEY分区表,以便在 MySQL 5.1 服务器上使用。有关更多信息,请参阅 第 15.1.9.1 节,“ALTER TABLE 分区操作”。mysqldump 将该选项写入版本注释中。
ALGORITHM=1在必要时在SHOW CREATE TABLE的输出中使用版本注释,方式与 mysqldump 相同。ALGORITHM=2总是从SHOW CREATE TABLE输出中省略,即使在创建原始表时指定了该选项。您不能使用
VALUES LESS THAN或VALUES IN子句与PARTITION BY KEY。 -
RANGE(expr)在这种情况下,
expr显示了使用一组VALUES LESS THAN操作符的值范围。当使用范围分区时,您必须至少定义一个使用VALUES LESS THAN的分区。您不能使用VALUES IN与范围分区。Note对于按
RANGE分区的表,VALUES LESS THAN必须与整数文字值或评估为单个整数值的表达式一起使用。在 MySQL 8.3 中,您可以在使用PARTITION BY RANGE COLUMNS定义的表中克服这个限制,如本节后面所述。假设您有一个要根据年份值分区的表,按照以下方案。
Partition Number: Years Range: 0 1990 及更早 1 1991 到 1994 2 1995 到 1998 3 1999 到 2002 4 2003 到 2005 5 2006 及更晚 可以通过以下所示的
CREATE TABLE语句来实现这样一个分区方案:CREATE TABLE t1 ( year_col INT, some_data INT ) PARTITION BY RANGE (year_col) ( PARTITION p0 VALUES LESS THAN (1991), PARTITION p1 VALUES LESS THAN (1995), PARTITION p2 VALUES LESS THAN (1999), PARTITION p3 VALUES LESS THAN (2002), PARTITION p4 VALUES LESS THAN (2006), PARTITION p5 VALUES LESS THAN MAXVALUE );PARTITION ... VALUES LESS THAN ...语句以连续的方式工作。VALUES LESS THAN MAXVALUE用于指定大于其他指定的最大值的“剩余”值。VALUES LESS THAN子句以类似于编程语言(如 C、Java、PHP)中switch ... case块的方式工作,即每个子句必须按顺序排列,以便每个子句的上限值大于前一个子句的上限值,最后一个子句引用MAXVALUE。 -
RANGE COLUMNS(column_list)该
RANGE变体有助于对使用多个列的范围条件的查询进行分区修剪(即具有条件如WHERE a = 1 AND b < 10或WHERE a = 1 AND b = 10 AND c < 10)。它允许您在COLUMNS子句中指定多个列的值范围,并在每个PARTITION ... VALUES LESS THAN (分区定义子句中指定一组列值。(在最简单的情况下,该组仅包含一个列。)value_list)column_list和value_list中最多可以引用 16 个列。在
COLUMNS子句中使用的column_list只能包含列名;每个列必须是以下 MySQL 数据类型之一:整数类型;字符串类型;时间或日期列类型。不允许使用BLOB、TEXT、SET、ENUM、BIT或空间数据类型的列;也不允许在COLUMNS子句中使用函数或算术表达式。在分区定义中使用的
VALUES LESS THAN子句必须为COLUMNS()子句中的每一列指定一个文字值;也就是说,VALUES LESS THAN子句中的值列表必须包含与COLUMNS子句中列数相同的值。如果在VALUES LESS THAN子句中使用的值比COLUMNS子句中的列数多或少,将导致语句失败,出现错误 Inconsistency in usage of column lists for partitioning...。您不能在VALUES LESS THAN子句中使用NULL作为任何值。此外,您可以在第一列以外的列中多次使用MAXVALUE,如下例所示:CREATE TABLE rc ( a INT NOT NULL, b INT NOT NULL ) PARTITION BY RANGE COLUMNS(a,b) ( PARTITION p0 VALUES LESS THAN (10,5), PARTITION p1 VALUES LESS THAN (20,10), PARTITION p2 VALUES LESS THAN (50,MAXVALUE), PARTITION p3 VALUES LESS THAN (65,MAXVALUE), PARTITION p4 VALUES LESS THAN (MAXVALUE,MAXVALUE) );在
VALUES LESS THAN值列表中的每个值必须与对应列的类型完全匹配;不进行任何转换。例如,您不能使用字符串'1'作为与整数类型列匹配的值(您必须使用数字1),也不能使用数字1作为与字符串类型列匹配的值(在这种情况下,您必须使用带引号的字符串:'1')。有关更多信息,请参阅 第 26.2.1 节,“RANGE 分区” 和 第 26.4 节,“分区修剪”。
-
LIST(expr)这在根据表列的受限可能值分配分区时非常有用,例如州或国家代码。在这种情况下,所有与特定州或国家相关的行都可以分配到单个分区,或者可以为特定的一组州或国家保留一个分区。它与
RANGE相似,除了只能使用VALUES IN指定每个分区的允许值。VALUES IN用于与值列表匹配。例如,您可以创建以下分区方案:CREATE TABLE client_firms ( id INT, name VARCHAR(35) ) PARTITION BY LIST (id) ( PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21), PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22), PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23), PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24) );使用列表分区时,必须使用
VALUES IN定义至少一个分区。您不能与PARTITION BY LIST一起使用VALUES LESS THAN。Note对于按
LIST分区的表,VALUES IN中使用的值列表必须仅包含整数值。在 MySQL 8.3 中,您可以使用LIST COLUMNS分区来克服这个限制,该分区在本节后面描述。 -
LIST COLUMNS(column_list)该变体在
LIST上facilitates 分区修剪对于使用多个列的比较条件的查询(即,具有条件such asWHERE a = 5 AND b = 5或WHERE a = 1 AND b = 10 AND c = 5)。它使您可以通过在COLUMNS子句中指定多个列的值,并在每个PARTITION ... VALUES IN (分区定义子句中指定一组列值。value_list)用于
LIST COLUMNS(中的列列表和用于column_list)VALUES IN(中的值列表的数据类型规则与用于value_list)RANGE COLUMNS(中的列列表和用于column_list)VALUES LESS THAN(中的值列表的规则相同,除了在value_list)VALUES IN子句中,不允许使用MAXVALUE,并且可以使用NULL。使用
PARTITION BY LIST COLUMNS时,VALUES IN子句中的值列表与使用PARTITION BY LIST时的值列表有一个重要的区别。当与PARTITION BY LIST COLUMNS一起使用时,每个元素在VALUES IN子句中必须是一个 集合 的列值;每个集合中的值数量必须与COLUMNS子句中的列数量相同,并且这些值的数据类型必须与列的数据类型匹配(并且以相同的顺序出现)。在最简单的情况下,集合由单个列组成。可以在column_list和value_list中使用的最大列数为 16。以下
CREATE TABLE语句定义的表使用LIST COLUMNS分区:CREATE TABLE lc ( a INT NULL, b INT NULL ) PARTITION BY LIST COLUMNS(a,b) ( PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ), PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ), PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ), PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) ) ); -
PARTITIONSnum可以使用
PARTITIONS子句指定分区的数量,其中numnum是分区的数量。如果同时使用该子句和任何PARTITION子句,num必须等于使用PARTITION子句声明的所有分区的总数。Note无论您在创建表时是否使用
PARTITIONS子句,该表是否被RANGE或LIST分区,您都必须在表定义中包含至少一个PARTITION VALUES子句(见下文)。 -
SUBPARTITION BY一个分区可以可选地被分成多个子分区。这可以通过使用可选的
SUBPARTITION BY子句来指示。子分区可以通过HASH或KEY进行。这两种方式的工作方式与之前描述的相应分区类型相同。(不能通过LIST或RANGE进行子分区。)可以使用
SUBPARTITIONS关键字后跟一个整数值来指示子分区的数量。 -
对
PARTITIONS或SUBPARTITIONS子句中使用的值进行严格检查,该值必须遵守以下规则:-
该值必须是一个正整数。
-
不允许有前导零。
-
该值必须是一个整数文字,不能是一个表达式。例如,
PARTITIONS 0.2E+01不被允许,即使0.2E+01评估为2。(Bug #15890)
-
-
partition_definition每个分区可以使用一个
partition_definition子句单独定义。该子句的组成部分如下:-
PARTITIONpartition_name指定分区的逻辑名称。
-
VALUES对于范围分区,每个分区必须包含一个
VALUES LESS THAN子句;对于列表分区,您必须为每个分区指定一个VALUES IN子句。这用于确定哪些行将被存储在该分区中。请参阅 第 26 章 分区 中的语法示例。 -
[STORAGE] ENGINEMySQL 接受
[STORAGE] ENGINE选项用于PARTITION和SUBPARTITION。目前,该选项只能用于将所有分区或所有子分区设置为同一个存储引擎,并且尝试在同一个表中为分区或子分区设置不同的存储引擎将引发错误 ERROR 1469 (HY000): 在该版本的 MySQL 中不允许在分区中混合处理程序。 -
COMMENT可选的
COMMENT子句可以用于指定描述分区的字符串。示例:COMMENT = 'Data for the years previous to 1999'分区注释的最大长度为 1024 个字符。
-
DATA DIRECTORY和INDEX DIRECTORYDATA DIRECTORY和INDEX DIRECTORY可以用来指定该分区的数据和索引存储的目录。两个和data_dir都必须是绝对的系统路径名。index_dir在
DATA DIRECTORY子句中指定的目录必须是InnoDB已知的。有关更多信息,请参阅 使用 DATA DIRECTORY 子句。您必须拥有
FILE权限才能使用DATA DIRECTORY或INDEX DIRECTORY分区选项。示例:
CREATE TABLE th (id INT, name VARCHAR(30), adate DATE) PARTITION BY LIST(YEAR(adate)) ( PARTITION p1999 VALUES IN (1995, 1999, 2003) DATA DIRECTORY = '/var/appdata/95/data' INDEX DIRECTORY = '/var/appdata/95/idx', PARTITION p2000 VALUES IN (1996, 2000, 2004) DATA DIRECTORY = '/var/appdata/96/data' INDEX DIRECTORY = '/var/appdata/96/idx', PARTITION p2001 VALUES IN (1997, 2001, 2005) DATA DIRECTORY = '/var/appdata/97/data' INDEX DIRECTORY = '/var/appdata/97/idx', PARTITION p2002 VALUES IN (1998, 2002, 2006) DATA DIRECTORY = '/var/appdata/98/data' INDEX DIRECTORY = '/var/appdata/98/idx' );DATA DIRECTORY和INDEX DIRECTORY的行为与在CREATE TABLE语句的table_option子句中用于MyISAM表的方式相同。每个分区可以指定一个数据目录和一个索引目录。如果未指定,默认情况下数据和索引将存储在表的数据库目录中。
如果
NO_DIR_IN_CREATE生效,则将忽略创建分区表时的DATA DIRECTORY和INDEX DIRECTORY选项。 -
MAX_ROWS和MIN_ROWS可以分别指定分区中存储的最大和最小行数。
max_number_of_rows和min_number_of_rows的值必须是正整数。与表级选项相同,这些选项仅作为服务器的“建议”而不是硬性限制。 -
TABLESPACE可以用来指定分区的
InnoDB文件每表表空间,方法是指定TABLESPACE `innodb_file_per_table`。所有分区必须属于同一个存储引擎。不支持将
InnoDB表分区放在共享的InnoDB表空间中。共享表空间包括InnoDB系统表空间和通用表空间。
-
-
子分区定义分区定义可以选择包含一个或多个
子分区定义子句。每个子句至少包含子分区,其中名称名称是子分区的标识符。除了将分区关键字替换为子分区之外,子分区定义的语法与分区定义的语法相同。子分区必须使用
HASH或KEY进行,并且只能在RANGE或LIST分区上进行。请参阅 第 26.2.6 节,“子分区”。
根据生成的列进行分区
允许根据生成的列进行分区。例如:
CREATE TABLE t1 (
s1 INT,
s2 INT AS (EXP(s1)) STORED
)
PARTITION BY LIST (s2) (
PARTITION p1 VALUES IN (1)
);
分区视生成的列为普通列,这使得可以绕过函数的限制(参见 第 26.6.3 节,“分区函数限制”)。前面的示例演示了这种技术:EXP() 不能直接在 PARTITION BY 子句中使用,但是使用 EXP() 定义的生成的列是允许的。