Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  CREATE TABLE Statement

15.1.20 创建表语句

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 语句”

表克隆和复制

列数据类型和属性

每个表的列数限制为 4096,但实际最大值可能小于该值,具体取决于 第 10.4.7 节,“表列数和行大小限制” 中讨论的因素。

  • data_type

    数据类型 在列定义中表示数据类型。有关指定列数据类型的语法的完整描述,以及每种类型的属性信息,请参阅 第 13 章,数据类型

    • 一些属性不适用于所有数据类型。AUTO_INCREMENT 只适用于整数和浮点数类型。使用 AUTO_INCREMENTFLOATDOUBLE 列在 MySQL 8.0 中已弃用;预计在未来版本的 MySQL 中将删除对其的支持。

    • 字符数据类型(CHARVARCHARTEXT 类型、ENUMSET 及其同义词)可以包括 CHARACTER SET 以指定列的字符集。CHARSETCHARACTER SET 的同义词。可以使用 COLLATE 属性指定字符集的排序规则,连同其他属性。有关详细信息,请参阅 第 12 章,字符集、排序规则、Unicode。示例:

      CREATE TABLE t (c CHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin);

      MySQL 8.3 将字符列定义中的长度规范解释为字符。 BINARYVARBINARY 的长度是以字节为单位的。

    • 对于 CHARVARCHARBINARYVARBINARY 列,可以创建使用列值的前导部分的索引,使用 col_name(length) 语法指定索引前缀长度。 BLOBTEXT 列也可以被索引,但必须指定前缀长度。前缀长度以字符为单位,对于非二进制字符串类型,以字节为单位,对于二进制字符串类型。也就是说,索引条目由每列值的前 length 个字符组成,对于 CHARVARCHARTEXT 列,和每列值的前 length 字节,对于 BINARYVARBINARYBLOB 列。这样索引文件可以变得非常小。有关索引前缀的更多信息,请参阅 第 15.1.15 节,“CREATE INDEX 语句”

      只有 InnoDBMyISAM 存储引擎支持在 BLOBTEXT 列上创建索引。例如:

      CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));

      如果指定的索引前缀超过了最大列数据类型大小, CREATE TABLE 将按照以下方式处理索引:

      • 对于非唯一索引,或者发生错误(如果启用了严格 SQL 模式),或者索引长度将被减少以在最大列数据类型大小内,并生成警告(如果未启用严格 SQL 模式)。

      • 对于唯一索引,无论SQL模式如何,因为缩短索引长度可能会启用不满足唯一性要求的非唯一条目插入。

    • JSON列不能被索引。您可以通过创建一个从JSON列中提取标量值的生成列的索引来绕过这个限制。请参阅使用生成列提供JSON列索引,以获取详细的示例。

  • 非空 | 空

    如果既没有指定也没有指定非空,则该列将被视为指定了

    在MySQL 8.3中,只有InnoDBMyISAMMEMORY存储引擎支持对可能包含值的列的索引。在其他情况下,您必须将索引列声明为非空,否则将出现错误。

  • 默认值

    指定列的默认值。有关默认值处理的更多信息,包括列定义中没有明确指定默认值的情况,请参阅第13.6节,“数据类型默认值”

    如果启用了NO_ZERO_DATENO_ZERO_IN_DATE SQL模式,并且日期值默认值不符合该模式,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_ZERO SQL 模式,您可以在 AUTO_INCREMENT 列中存储 0 作为 0,而不生成新的序列值。见 第 7.1.11 节,“服务器 SQL 模式”

    每个表只能有一个 AUTO_INCREMENT 列,必须索引,并且不能有 DEFAULT 值。AUTO_INCREMENT 列仅在包含正值时才正常工作。插入负数被视为插入非常大的正数。这是为了避免精度问题,当数字从正数“wrap”到负数时,也确保您不会意外地获得包含 0AUTO_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 节,“服务器系统变量”

    关于 InnoDBAUTO_INCREMENT 的信息,请参阅 第 17.6.1.6 节,“InnoDB 中的 AUTO_INCREMENT 处理”。关于 AUTO_INCREMENT 和 MySQL 复制的信息,请参阅 第 19.5.1.1 节,“复制和 AUTO_INCREMENT”

  • COMMENT

    可以使用 COMMENT 选项指定列的注释,长度最多为 1024 个字符。该注释将由 SHOW CREATE TABLESHOW FULL COLUMNS 语句显示。它也将显示在信息模式 COLUMNS 表的 COLUMN_COMMENT 列中。

  • COLUMN_FORMAT

    在 NDB Cluster 中,还可以使用 COLUMN_FORMAT 指定单个列的数据存储格式。允许的列格式是 FIXEDDYNAMICDEFAULTFIXED 用于指定固定宽度存储,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_ATTRIBUTESECONDARY_ENGINE_ATTRIBUTE 选项用于指定主存储引擎和辅助存储引擎的列属性。这些选项保留供将来使用。

    允许的值是一个包含有效 JSON 文档的字符串文字或空字符串 ('')。无效的 JSON 将被拒绝。

    CREATE TABLE t1 (c1 INT ENGINE_ATTRIBUTE='{"key":"value"}');

    ENGINE_ATTRIBUTESECONDARY_ENGINE_ATTRIBUTE 值可以重复指定,而不报错。在这种情况下,将使用最后指定的值。

    ENGINE_ATTRIBUTESECONDARY_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 KEYUNIQUE NOT NULL 索引,该索引由单个整数类型列组成,您可以在 SELECT 语句中使用 _rowid 引用该索引列,如 唯一索引 中所述。

    在 MySQL 中,PRIMARY KEY 的名称是 PRIMARY。对于其他索引,如果您不分配名称,索引将被分配与第一个索引列相同的名称,带有可选的后缀 (_2, _3, ...) 以使其唯一。您可以使用 SHOW INDEX FROM tbl_name 查看表的索引名称。见 第 15.7.7.23 节,“SHOW INDEX 语句”

  • KEY | INDEX

    KEY 通常是 INDEX 的同义词。在列定义中,键属性 PRIMARY KEY 也可以指定为只是 KEY。这是在与其他数据库系统兼容时实现的。

  • UNIQUE

    一个 UNIQUE 索引创建了一个约束,使得索引中的所有值必须是不同的。如果您尝试添加一个新行,其中的键值与现有行匹配,将发生错误。对于所有引擎,UNIQUE 索引允许包含 NULL 值的列中有多个 NULL 值。如果您为 UNIQUE 索引中的列指定了前缀值,则该列的值必须在前缀长度内唯一。

    如果一个表具有 PRIMARY KEYUNIQUE NOT NULL 索引,该索引由单个整数类型的列组成,您可以在 SELECT 语句中使用 _rowid 引用该索引列,如 唯一索引 中所述。

  • FULLTEXT

    一个 FULLTEXT 索引是一种特殊类型的索引,用于全文搜索。只有 InnoDBMyISAM 存储引擎支持 FULLTEXT 索引。它们只能从 CHARVARCHARTEXT 列中创建。索引总是整个列的;列前缀索引不支持,并且如果指定了前缀长度将被忽略。请参阅 第 14.9 节,“全文搜索函数”,了解详细信息。可以指定一个 WITH PARSER 子句作为 index_option 值,以关联一个解析器插件与索引,如果全文索引和搜索操作需要特殊处理。该子句仅对 FULLTEXT 索引有效。InnoDBMyISAM 支持全文解析器插件。请参阅 全文解析器插件编写全文解析器插件,了解更多信息。

  • SPATIAL

    您可以在空间数据类型上创建 SPATIAL 索引。空间类型仅支持 InnoDBMyISAM 表,并且索引列必须声明为 NOT NULL。请参阅 第 13.4 节,“空间数据类型”

  • 外键

    MySQL 支持外键,让您可以跨表引用相关数据,并且外键约束有助于保持这些分布式数据的一致性。有关定义和选项信息,请参阅 reference_definitionreference_option

    使用 InnoDB 存储引擎的分区表不支持外键。请参阅 第 26.6 节,“分区限制”,以获取更多信息。

  • CHECK

    CHECK 子句启用了在表行中检查数据值的约束。请参阅 第 15.1.20.6 节,“CHECK 约束”

  • key_part

    • 一个 key_part 规范可以以 ASCDESC 结尾,以指定索引值是否以升序或降序存储。默认情况下,如果没有指定顺序,则为升序。

    • 前缀,由 length 属性定义,可以长达 767 字节,用于 InnoDB 表,该表使用 REDUNDANTCOMPACT 行格式。对于使用 DYNAMICCOMPRESSED 行格式的 InnoDB 表,前缀长度限制为 3072 字节。对于 MyISAM 表,前缀长度限制为 1000 字节。

      前缀 限制 以字节为单位测量。然而,前缀 长度CREATE TABLEALTER TABLECREATE INDEX 语句中被解释为非二进制字符串类型(CHARVARCHARTEXT)的字符数和二进制字符串类型(BINARYVARBINARYBLOB)的字节数。在指定非二进制字符串列的前缀长度时,请注意这一点。

    • 表达式 expr 对于 key_part 规范可以采用 (CAST json_path AS type ARRAY) 的形式,以在 JSON 列上创建多值索引。多值索引 提供了有关创建、使用和多值索引的限制和限制的详细信息。

  • index_type

    一些存储引擎允许您在创建索引时指定索引类型。语法为 index_type 规范是 USING type_name

    示例:

    CREATE TABLE lookup
      (id INT, INDEX USING BTREE (id))
      ENGINE = MEMORY;

    首选的 USING 位置是在索引列列表之后。它可以在列列表之前给出,但支持在该位置使用该选项已经弃用,并且您应该期望在未来 MySQL 版本中删除该选项。

  • index_option

    index_option 值指定索引的其他选项。

    • KEY_BLOCK_SIZE

      对于 MyISAM 表, KEY_BLOCK_SIZE 可选地指定索引键块的大小(以字节为单位)。该值被视为提示;如果必要,可以使用不同的大小。单个索引定义中的 KEY_BLOCK_SIZE 值将覆盖表级 KEY_BLOCK_SIZE 值。

      有关表级 KEY_BLOCK_SIZE 属性的信息,请参阅 表选项

    • WITH PARSER

      WITH PARSER 选项只能与 FULLTEXT 索引一起使用。它将解析器插件与索引关联,以便在全文索引和搜索操作需要特殊处理时使用。InnoDBMyISAM 都支持全文解析器插件。如果您有一个 MyISAM 表带有关联的全文解析器插件,可以使用 ALTER TABLE 将其转换为 InnoDB

    • COMMENT

      索引定义可以包括一个可选的注释,最多 1024 个字符。

      您可以使用 COMMENT 子句设置单个索引的 InnoDB MERGE_THRESHOLD 值。请参阅 第 17.8.11 节,“配置索引页合并阈值”

    • VISIBLE, INVISIBLE

      指定索引可见性。索引默认情况下是可见的。不可见的索引不会被优化器使用。索引可见性规则适用于除主键(明确或隐式)以外的所有索引。有关更多信息,请参阅 第 10.3.12 节,“不可见索引”

    • ENGINE_ATTRIBUTESECONDARY_ENGINE_ATTRIBUTE 选项用于指定主存储引擎和次要存储引擎的索引属性。这些选项保留供将来使用。

    有关允许的 index_option 值的更多信息,请参阅 第 15.1.15 节,“CREATE INDEX 语句”。有关索引的更多信息,请参阅 第 10.3.1 节,“MySQL 如何使用索引”

  • 引用定义

    有关 引用定义 语法详细信息和示例,请参阅 第 15.1.20.5 节,“外键约束”

    InnoDBNDB 表支持外键约束的检查。被引用表的列必须始终被明确命名。同时支持 ON DELETEON UPDATE 动作对外键的支持。有关详细信息和示例,请参阅 第 15.1.20.5 节,“外键约束”

    对于其他存储引擎,MySQL 服务器将解析并忽略 FOREIGN KEY 语法在 CREATE TABLE 语句中。

    Important

    对于熟悉 ANSI/ISO SQL 标准的用户,请注意,无论是 InnoDB 还是其他存储引擎,都不识别或执行 MATCH 子句在参照完整性约束定义中。使用明确的 MATCH 子句不会产生指定的效果,并且还会导致 ON DELETEON UPDATE 子句被忽略。因此,指定 MATCH 应该被避免。

    SQL 标准中的 MATCH 子句控制在复合(多列)外键中如何处理 NULL 值的比较,以便与主键进行比较。InnoDB 实质上实现了 MATCH SIMPLE 的语义,这允许外键全部或部分为 NULL。在这种情况下,包含这种外键的(子表)行将被允许插入,并且不匹配父表中的任何行。可以使用触发器来实现其他语义。

    此外,MySQL 还要求被引用的列被索引以提高性能。然而,InnoDB 不会强制被引用的列被声明为 UNIQUENOT NULL。对于操作如 UPDATEDELETE CASCADE,外键引用非唯一键或包含 NULL 值的键的处理方式未定义。你被建议使用外键,仅引用唯一的(或 PRIMARY)且非 NULL 的键。

    MySQL 解析但忽略 内联 REFERENCES 规范(如 SQL 标准所定义),其中引用是在列规范的一部分中定义的。MySQL 只接受 REFERENCES 子句,当它们作为单独的 FOREIGN KEY 规范的一部分时。有关更多信息,请参阅 第 1.6.2.3 节,“外键约束差异”

  • reference_option

    有关 RESTRICTCASCADESET NULLNO ACTIONSET 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 中,这适用于 MyISAMMEMORYInnoDBARCHIVE 表。要设置不支持 AUTO_INCREMENT 表选项的引擎的第一个自动递增值,请在创建表后插入一个值小于所需值的“dummy”行,然后删除 dummy 行。

    对于支持 AUTO_INCREMENT 表选项的引擎,在 CREATE TABLE 语句中,您也可以使用 ALTER TABLE tbl_name AUTO_INCREMENT = N 重置 AUTO_INCREMENT 值。该值不能设置为小于当前列中的最大值。

  • AVG_ROW_LENGTH

    表的平均行长度近似值。您只需要为具有可变大小行的大型表设置此值。

    当您创建 MyISAM 表时,MySQL 使用 MAX_ROWSAVG_ROW_LENGTH 选项的乘积来确定结果表的大小。如果您不指定任何选项,默认情况下 MyISAM 数据和索引文件的最大大小为 256TB。(如果您的操作系统不支持如此大的文件,表大小将受到文件大小限制的约束。)如果您想减少指针大小以使索引变得更小和更快,并且您不需要大文件,可以通过设置 myisam_data_pointer_size 系统变量来实现。(见 第 7.1.8 节,“服务器系统变量”。)如果您想让所有表都可以增长到默认限制以上,并且您愿意让表变得稍慢一些和更大一些,可以通过设置该变量来实现。将该值设置为 7 可以使表大小达到 65,536TB。

  • [DEFAULT] 字符集

    指定表的默认字符集。CHARSETCHARACTER SET的同义词。如果字符集名称是DEFAULT,则使用数据库字符集。

  • CHECKSUM

    如果您想让 MySQL 为所有行维护实时校验和(即,随着表的变化自动更新的校验和),请将其设置为 1。这将使表更新速度变慢,但也使得发现损坏的表变得更容易。CHECKSUM TABLE语句报告校验和。(仅适用于 MyISAM。)

  • [DEFAULT] COLLATE

    指定表的默认排序规则。

  • COMMENT

    表的注释,最长 2048 个字符。

    您可以使用 COMMENT 子句设置 InnoDBMERGE_THRESHOLD 值。请参阅 第 17.8.11 节,“配置索引页合并阈值”

    设置 NDB_TABLE 选项。 在创建 NDB 表或修改表时,表注释也可以用于指定一个到四个 NDB_TABLE 选项 NOLOGGINGREAD_BACKUPPARTITION_BALANCEFULLY_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 表的页面级压缩的压缩算法。支持的值包括 ZlibLZ4NoneCOMPRESSION 属性是在透明页压缩功能中引入的。页面压缩仅支持 InnoDB 表,该表驻留在 每个表文件 表空间中,并且仅在支持稀疏文件和 hole punching 的 Linux 和 Windows 平台上可用。有关更多信息,请参阅 第 17.9.2 节,“InnoDB 页压缩”

  • CONNECTION

    联邦表的连接字符串。

    Note

    旧版本的 MySQL 使用 COMMENT 选项来指定连接字符串。

  • DATA DIRECTORYINDEX DIRECTORY

    对于 InnoDBDATA DIRECTORY='directory' 子句允许在数据目录外创建表。innodb_file_per_table 变量必须启用以使用 DATA DIRECTORY 子句。必须指定完整的目录路径,并且 InnoDB 必须知道该路径。有关更多信息,请参阅 第 17.6.1.2 节,“外部创建表”

    创建 MyISAM 表时,可以使用 DATA DIRECTORY='directory' 子句、INDEX DIRECTORY='directory' 子句或两者。它们指定了 MyISAM 表的数据文件和索引文件的位置。与 InnoDB 表不同,MySQL 不会在创建带有 DATA DIRECTORYINDEX DIRECTORY 选项的 MyISAM 表时创建对应数据库名称的子目录。文件将被创建在指定的目录中。

    您必须拥有FILE权限以使用DATA DIRECTORYINDEX DIRECTORY表选项。

    Important

    表级DATA DIRECTORYINDEX 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 DIRECTORYINDEX DIRECTORY选项的 MyISAM 表,并且找到现有的.MYD.MYI文件,MyISAM 将总是返回错误,不会覆盖指定目录中的文件。

    Important

    您不能使用包含 MySQL 数据目录的路径名与DATA DIRECTORYINDEX DIRECTORY。这包括分区表和单个表分区。(参见 Bug #32167。)

  • DELAY_KEY_WRITE

    如果您想延迟表的键更新直到表关闭,请将其设置为 1。请参阅delay_key_write系统变量的描述,在第 7.1.8 节,“服务器系统变量”中。(仅适用于 MyISAM。)

  • ENCRYPTION

    ENCRYPTION子句启用或禁用 InnoDB 表的页面级数据加密。必须安装并配置密钥环插件才能启用加密。ENCRYPTION子句可以在创建文件每个表的表空间或创建通用表空间中的表时指定。

    如果没有指定ENCRYPTION子句,表将继承默认模式加密。如果启用了table_encryption_privilege_check变量,创建表时需要TABLE_ENCRYPTION_ADMIN权限,以便在加密设置与默认模式加密不同。当在通用表空间中创建表时,表和表空间加密必须匹配。

    在使用不支持加密的存储引擎时,不允许在ENCRYPTION子句中指定除'N'''以外的值。

    有关更多信息,请参阅第 17.13 节,“InnoDB 静态加密”

  • 选项ENGINE_ATTRIBUTESECONDARY_ENGINE_ATTRIBUTE用于指定主存储引擎和次要存储引擎的表属性。这些选项保留供将来使用。

    允许的值是一个包含有效JSON文档的字符串文字或空字符串('')。无效的JSON将被拒绝。

    CREATE TABLE t1 (c1 INT) ENGINE_ATTRIBUTE='{"key":"value"}';

    ENGINE_ATTRIBUTESECONDARY_ENGINE_ATTRIBUTE值可以重复指定,而不会出错。在这种情况下,将使用最后指定的值。

    ENGINE_ATTRIBUTESECONDARY_ENGINE_ATTRIBUTE值不会被服务器检查,也不会在更改表的存储引擎时被清除。

  • INSERT_METHOD

    如果要将数据插入MERGE表,必须使用INSERT_METHOD指定要插入的表。INSERT_METHOD选项仅适用于MERGE表。使用FIRSTLAST值将插入到第一个或最后一个表中,或者使用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_ROWSNDB 表来控制表分区的数量已经弃用。它在后续版本中仍然受到支持,以便向后兼容,但可能在未来版本中被删除。请使用 PARTITION_BALANCE 代替;请参阅 设置 NDB_TABLE 选项

    NDB 存储引擎将该值视为最大值。如果您计划创建非常大的 NDB 集群表(包含数百万行),您应该使用该选项,以确保 NDB 在哈希表中分配足够的索引槽,以存储主键的哈希值,方法是将 MAX_ROWS = 2 * rows,其中 rows 是您计划插入表中的行数。

    最大 MAX_ROWS 值为 4294967295;较大的值将被截断到该限制。

  • MIN_ROWS

    您计划在表中存储的最小行数。MEMORY 存储引擎使用该选项作为内存使用的提示。

  • PACK_KEYS

    仅对 MyISAM 表生效。如果您想拥有较小的索引,请将该选项设置为 1。这通常使更新变慢,读取变快。将该选项设置为 0 将禁用所有键的打包。将其设置为 DEFAULT 将告诉存储引擎仅打包长 CHARVARCHARBINARYVARBINARY 列。

    如果您不使用 PACK_KEYS,则默认情况下将打包字符串,但不包括数字。如果您使用 PACK_KEYS=1,数字也将被打包。

    在打包二进制数字键时,MySQL 使用前缀压缩:

    • 每个键需要一个额外的字节来指示前一个键的多少字节与下一个键相同。

    • 行指针以高字节优先顺序直接存储在键之后,以提高压缩率。

    这意味着,如果您在两个连续的行上有许多相等的键,那么所有后续的“相同”的键通常只需要两个字节(包括指向行的指针)。将其与普通情况进行比较,其中后续键需要 storage_size_for_key + pointer_size(其中指针大小通常为 4)。相反,只有当您有许多相同的数字时,才会从前缀压缩中获得显著的益处。如果所有键完全不同,那么您将使用每个键多一个字节,除非该键不能具有 NULL 值。(在这种情况下,压缩键长度将存储在同一个字节中,该字节用于标记键是否为 NULL。)

  • 密码

    此选项未使用。

  • 行格式

    定义行以物理格式存储。

    当创建表时禁用 严格模式,存储引擎的默认行格式将被使用,如果指定的行格式不受支持。实际的行格式将在 Row_format 列中报告,以响应 SHOW TABLE STATUSCreate_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=COMPRESSEDROW_FORMAT=COMPRESSED选项不支持创建临时表。请参阅第 17.9 节,“InnoDB 表和页压缩”以了解与COMPRESSED行格式相关的要求。

    • 旧版本 MySQL 中使用的行格式仍可以通过指定REDUNDANT行格式来请求。

    • 当您指定非默认的ROW_FORMAT子句时,请考虑也启用innodb_strict_mode配置选项。

    • ROW_FORMAT=FIXED不支持。如果在innodb_strict_mode禁用时指定ROW_FORMAT=FIXEDInnoDB将发出警告并假设ROW_FORMAT=DYNAMIC。如果在innodb_strict_mode启用时指定ROW_FORMAT=FIXEDInnoDB将返回错误。

    • 有关InnoDB行格式的更多信息,请参阅第 17.10 节,“InnoDB 行格式”

    对于MyISAM表,选项值可以是FIXEDDYNAMIC,用于静态或变长行格式。myisampack将类型设置为COMPRESSED。请参阅第 18.2.3 节,“MyISAM 表存储格式”

    对于NDB表,默认的ROW_FORMATDYNAMIC

  • START TRANSACTION

    这是一个内部使用的表选项,用于允许在使用基于行的复制和支持原子DDL的存储引擎时,将CREATE TABLE ... SELECT记录为单个原子事务在二进制日志中。只有BINLOGCOMMITROLLBACK语句在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 TABLEALTER 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 节,“通用表空间”

    指定的 tablespace_name 是一个区分大小写的标识符。它可以是带引号或不带引号的。斜杠字符 (/) 不允许使用。以 innodb_ 开头的名称保留用于特殊用途。

    要在系统表空间中创建表,请指定 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_table
    Note

    如果 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_tableTABLESPACE = innodb_temporary 子句与 CREATE TEMPORARY TABLE 的支持将被弃用;预计在未来版本的 MySQL 中删除。

    STORAGE 表选项仅用于 NDB 表。STORAGE 确定存储类型,可以是 DISKMEMORY

    TABLESPACE ... STORAGE DISK 将表分配给 NDB Cluster 磁盘数据表空间。STORAGE DISK 不能在 CREATE TABLE 中使用,除非在 TABLESPACE tablespace_name 之前。

    对于 STORAGE MEMORY,表空间名称是可选的,因此您可以使用 TABLESPACE tablespace_name STORAGE MEMORY 或简单地使用 STORAGE MEMORY 来明确指定表是在内存中的。

    请参阅 第 25.6.11 节,“NDB Cluster 磁盘数据表”,以获取更多信息。

  • UNION

    用于访问一组相同的 MyISAM 表作为一个表。这只适用于 MERGE 表。请参阅 第 18.7 节,“MERGE 存储引擎”

    您必须拥有 SELECTUPDATEDELETE 权限,以便在 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 THANVALUES 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] KEYALGORITHM=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 或更高版本服务器上创建 KEYLINEAR KEY 分区表,以便在 MySQL 5.1 服务器上使用。有关更多信息,请参阅 第 15.1.9.1 节,“ALTER TABLE 分区操作”

    mysqldump 将该选项写入版本注释中。

    ALGORITHM=1 在必要时在 SHOW CREATE TABLE 的输出中使用版本注释,方式与 mysqldump 相同。ALGORITHM=2 总是从 SHOW CREATE TABLE 输出中省略,即使在创建原始表时指定了该选项。

    您不能使用 VALUES LESS THANVALUES 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 < 10WHERE a = 1 AND b = 10 AND c < 10)。它允许您在 COLUMNS 子句中指定多个列的值范围,并在每个 PARTITION ... VALUES LESS THAN (value_list) 分区定义子句中指定一组列值。(在最简单的情况下,该组仅包含一个列。)column_listvalue_list 中最多可以引用 16 个列。

    COLUMNS 子句中使用的 column_list 只能包含列名;每个列必须是以下 MySQL 数据类型之一:整数类型;字符串类型;时间或日期列类型。不允许使用 BLOBTEXTSETENUMBIT 或空间数据类型的列;也不允许在 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 as WHERE a = 5 AND b = 5WHERE 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_listvalue_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) )
    );
  • PARTITIONS num

    可以使用 PARTITIONS num 子句指定分区的数量,其中 num 是分区的数量。如果同时使用该子句和任何 PARTITION 子句,num 必须等于使用 PARTITION 子句声明的所有分区的总数。

    Note

    无论您在创建表时是否使用 PARTITIONS 子句,该表是否被 RANGELIST 分区,您都必须在表定义中包含至少一个 PARTITION VALUES 子句(见下文)。

  • SUBPARTITION BY

    一个分区可以可选地被分成多个子分区。这可以通过使用可选的 SUBPARTITION BY 子句来指示。子分区可以通过 HASHKEY 进行。这两种方式的工作方式与之前描述的相应分区类型相同。(不能通过 LISTRANGE 进行子分区。)

    可以使用 SUBPARTITIONS 关键字后跟一个整数值来指示子分区的数量。

  • PARTITIONSSUBPARTITIONS 子句中使用的值进行严格检查,该值必须遵守以下规则:

    • 该值必须是一个正整数。

    • 不允许有前导零。

    • 该值必须是一个整数文字,不能是一个表达式。例如,PARTITIONS 0.2E+01 不被允许,即使 0.2E+01 评估为 2。(Bug #15890)

  • partition_definition

    每个分区可以使用一个 partition_definition 子句单独定义。该子句的组成部分如下:

    • PARTITION partition_name

      指定分区的逻辑名称。

    • VALUES

      对于范围分区,每个分区必须包含一个 VALUES LESS THAN 子句;对于列表分区,您必须为每个分区指定一个 VALUES IN 子句。这用于确定哪些行将被存储在该分区中。请参阅 第 26 章 分区 中的语法示例。

    • [STORAGE] ENGINE

      MySQL 接受 [STORAGE] ENGINE 选项用于 PARTITIONSUBPARTITION。目前,该选项只能用于将所有分区或所有子分区设置为同一个存储引擎,并且尝试在同一个表中为分区或子分区设置不同的存储引擎将引发错误 ERROR 1469 (HY000): 在该版本的 MySQL 中不允许在分区中混合处理程序

    • COMMENT

      可选的 COMMENT 子句可以用于指定描述分区的字符串。示例:

      COMMENT = 'Data for the years previous to 1999'

      分区注释的最大长度为 1024 个字符。

    • DATA DIRECTORYINDEX DIRECTORY

      DATA DIRECTORYINDEX DIRECTORY 可以用来指定该分区的数据和索引存储的目录。两个 data_dirindex_dir 都必须是绝对的系统路径名。

      DATA DIRECTORY 子句中指定的目录必须是 InnoDB 已知的。有关更多信息,请参阅 使用 DATA DIRECTORY 子句

      您必须拥有 FILE 权限才能使用 DATA DIRECTORYINDEX 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 DIRECTORYINDEX DIRECTORY 的行为与在 CREATE TABLE 语句的 table_option 子句中用于 MyISAM 表的方式相同。

      每个分区可以指定一个数据目录和一个索引目录。如果未指定,默认情况下数据和索引将存储在表的数据库目录中。

      如果 NO_DIR_IN_CREATE 生效,则将忽略创建分区表时的 DATA DIRECTORYINDEX DIRECTORY 选项。

    • MAX_ROWSMIN_ROWS

      可以分别指定分区中存储的最大和最小行数。max_number_of_rowsmin_number_of_rows 的值必须是正整数。与表级选项相同,这些选项仅作为服务器的“建议”而不是硬性限制。

    • TABLESPACE

      可以用来指定分区的 InnoDB 文件每表表空间,方法是指定 TABLESPACE `innodb_file_per_table`。所有分区必须属于同一个存储引擎。

      不支持将 InnoDB 表分区放在共享的 InnoDB 表空间中。共享表空间包括 InnoDB 系统表空间和通用表空间。

  • 子分区定义

    分区定义可以选择包含一个或多个 子分区定义 子句。每个子句至少包含 子分区 名称,其中 名称 是子分区的标识符。除了将 分区 关键字替换为 子分区 之外,子分区定义的语法与分区定义的语法相同。

    子分区必须使用 HASHKEY 进行,并且只能在 RANGELIST 分区上进行。请参阅 第 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() 定义的生成的列是允许的。