创建表(CREATE TABLE)

  1. CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
  2. (create_definition,...)
  3. [table_options]
  4. [partition_options]
  5. CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
  6. [(create_definition,...)]
  7. [table_options]
  8. [partition_options]
  9. [IGNORE | REPLACE]
  10. [AS] query_expression
  11. CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
  12. { LIKE old_tbl_name | (LIKE old_tbl_name) }
  13. create_definition:
  14. col_name column_definition
  15. | {INDEX|KEY} [index_name] [index_type] (key_part,...)
  16. [index_option] ...
  17. | {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (key_part,...)
  18. [index_option] ...
  19. | [CONSTRAINT [symbol]] PRIMARY KEY
  20. [index_type] (key_part,...)
  21. [index_option] ...
  22. | [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY]
  23. [index_name] [index_type] (key_part,...)
  24. [index_option] ...
  25. | [CONSTRAINT [symbol]] FOREIGN KEY
  26. [index_name] (col_name,...)
  27. reference_definition
  28. | CHECK (expr)
  29. column_definition:
  30. data_type [NOT NULL | NULL] [DEFAULT default_value]
  31. [AUTO_INCREMENT] [UNIQUE [KEY]] [[PRIMARY] KEY]
  32. [COMMENT 'string']
  33. [COLLATE collation_name]
  34. [COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}] #目前只对NDB有效
  35. [STORAGE {DISK|MEMORY}]
  36. [reference_definition]
  37. | data_type
  38. [COLLATE collation_name]
  39. [GENERATED ALWAYS] AS (expr)
  40. [VIRTUAL | STORED] [NOT NULL | NULL]
  41. [UNIQUE [KEY]] [[PRIMARY] KEY]
  42. [COMMENT 'string']
  43. [reference_definition]
  44. data_type:
  45. (see Chapter 11, Data Types)
  46. key_part:
  47. col_name [(length)] [ASC | DESC]
  48. index_type:
  49. USING {BTREE | HASH}
  50. index_option:
  51. KEY_BLOCK_SIZE [=] value
  52. | index_type
  53. | WITH PARSER parser_name #仅对全文索引有效
  54. | COMMENT 'string'
  55. reference_definition:
  56. REFERENCES tbl_name (key_part,...)
  57. [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]
  58. [ON DELETE reference_option]
  59. [ON UPDATE reference_option]
  60. reference_option:
  61. RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
  62. table_options:
  63. table_option [[,] table_option] ...
  64. table_option:
  65. AUTO_INCREMENT [=] value
  66. | AVG_ROW_LENGTH [=] value
  67. | [DEFAULT] CHARACTER SET [=] charset_name
  68. | CHECKSUM [=] {0 | 1}
  69. | [DEFAULT] COLLATE [=] collation_name
  70. | COMMENT [=] 'string'
  71. | COMPRESSION [=] {'ZLIB'|'LZ4'|'NONE'}
  72. | CONNECTION [=] 'connect_string'
  73. | {DATA|INDEX} DIRECTORY [=] 'absolute path to directory'
  74. | DELAY_KEY_WRITE [=] {0 | 1}
  75. | ENCRYPTION [=] {'Y' | 'N'}
  76. | ENGINE [=] engine_name
  77. | INSERT_METHOD [=] { NO | FIRST | LAST }
  78. | KEY_BLOCK_SIZE [=] value
  79. | MAX_ROWS [=] value
  80. | MIN_ROWS [=] value
  81. | PACK_KEYS [=] {0 | 1 | DEFAULT}
  82. | PASSWORD [=] 'string'
  83. | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}
  84. | STATS_AUTO_RECALC [=] {DEFAULT|0|1}
  85. | STATS_PERSISTENT [=] {DEFAULT|0|1}
  86. | STATS_SAMPLE_PAGES [=] value
  87. | TABLESPACE tablespace_name [STORAGE {DISK|MEMORY}]
  88. | UNION [=] (tbl_name[,tbl_name]...)
  89. partition_options:
  90. PARTITION BY
  91. { [LINEAR] HASH(expr)
  92. | [LINEAR] KEY [ALGORITHM={1|2}] (column_list)
  93. | RANGE{(expr) | COLUMNS(column_list)}
  94. | LIST{(expr) | COLUMNS(column_list)} }
  95. [PARTITIONS num]
  96. [SUBPARTITION BY
  97. { [LINEAR] HASH(expr)
  98. | [LINEAR] KEY [ALGORITHM={1|2}] (column_list) }
  99. [SUBPARTITIONS num]
  100. ]
  101. [(partition_definition [, partition_definition] ...)]
  102. partition_definition:
  103. PARTITION partition_name
  104. [VALUES
  105. {LESS THAN {(expr | value_list) | MAXVALUE}
  106. |
  107. IN (value_list)}]
  108. [[STORAGE] ENGINE [=] engine_name]
  109. [COMMENT [=] 'string' ]
  110. [DATA DIRECTORY [=] 'data_dir']
  111. [INDEX DIRECTORY [=] 'index_dir']
  112. [MAX_ROWS [=] max_number_of_rows]
  113. [MIN_ROWS [=] min_number_of_rows]
  114. [TABLESPACE [=] tablespace_name]
  115. [(subpartition_definition [, subpartition_definition] ...)]
  116. subpartition_definition:
  117. SUBPARTITION logical_name
  118. [[STORAGE] ENGINE [=] engine_name]
  119. [COMMENT [=] 'string' ]
  120. [DATA DIRECTORY [=] 'data_dir']
  121. [INDEX DIRECTORY [=] 'index_dir']
  122. [MAX_ROWS [=] max_number_of_rows]
  123. [MIN_ROWS [=] min_number_of_rows]
  124. [TABLESPACE [=] tablespace_name]
  125. query_expression:
  126. SELECT ... (Some valid select or union statement)

CREATE TABLE 创建具有给定名称的表。您必须具有该表的 CREATE 权限。
默认情况下,使用 InnoDB 存储引擎在默认数据库中创建表。如果表存在、没有默认数据库或数据库不存在,则会发生错误。
MySQL 对表的数量没有限制。底层文件系统可能对表示表的文件数量有限制。单个存储引擎可能会施加特定于引擎的约束。InnoDB 最多允许 40亿张表。
有关表的物理表示的信息,请参阅“Files Created by CREATE TABLE”

表名(Table Name)

  • tbl_name:表名可以指定为 db_name.tbl_name,以便在特定数据库中创建表。不管是否有默认数据库,假设数据库存在,这都是有效的。如果使用带引号的标识符,请分别引用数据库和表名称。例如,写 mydb`.`mytbl,而不是 mydb.Mytbl。表名称的规则在 “Schema Object Names”中给出。
  • IF NOT EXISTS:如果表不存在,防止发生错误。但是,没有验证现有表具有与 CREATE TABLE 语句指示的结构相同的结构。

    临时表(Temporary Tables)

    您可以在创建表时使用TEMPORARY关键字。TEMPORARY表仅在当前会话中可见,并在会话关闭时自动删除。有关详细信息,请参阅“CREATE TEMPORARY TABLE Statement”

    表的克隆和拷贝(Table Cloning and Copying)

  • LIKE:使用CREATE TABLE ... LIKE根据另一个表的定义创建一个空表,包括原始表中定义的任何列属性和索引:

    CREATE TABLE new_tbl LIKE orig_tbl;
    
    CREATE TABLE new_tbl LIKE orig_tbl;
    
  • 有关更多信息,请参见 “CREATE TABLE … LIKE Statement”

  • [AS] _queryexpression`:要从另一个表中创建一个表,请在CREATE TABLE语句的末尾添加一个SELECT` 语句:

    CREATE TABLE new_tbl AS SELECT * FROM orig_tbl;
    
  • 有关更多信息,请参见 “CREATE TABLE … SELECT Statement”

  • IGNORE|REPLACE:“IGNORE” 和 “REPLACE” 选项指示使用 SELECT 语句复制表时如何处理复制唯一键值的行。有关详细信息,请参阅 “CREATE TABLE … SELECT Statement”

    表数据类型和属性(Column Data Types and Attributes)

    每个表有 4096 列的限制,但是对于给定的表,有效的最大值可能更少,并且取决于“Limits on Table Column Count and Row Size”中讨论的因素”。

  • _datatype`Datatype`在列定义中显示数据类型。有关可用于指定列数据类型的语法的完整描述,以及有关每种类型的属性的信息,请参阅 [_Data Types](https://dev.mysql.com/doc/refman/5.7/en/data-types.html)。

    • AUTO_INCREMENT仅适用于整数和浮点类型。DEFAULT不适用于 BLOB文本GEOMETRYJSON 类型。
    • 字符数据类型 (CHARVARCHARTEXTENUMSET和任何同义词) 可以包括CHARACTER SET,以指定列的字符集。CHARSETCHARACTER SET的同义词。可以使用 COLLATE 属性以及任何其他属性指定字符集的排序规则。有关详细信息,请参见Character Sets, Collations, Unicode.。示例:

      CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);
      
    • MySQL 5.7使用字符来解释字符列中定义长度。BINARYVARBINARY 的长度以字节为单位。

    • 对于CHARVARCHARBINARYvarbinary 这些列,可以创建仅使用列值前缀部分的索引,使用 col_name(length)语法指定索引前缀长度。BLOBTEXT列也可以被索引,但是必须给出前缀长度。对于非二进制字符串类型,前缀长度以字符为单位,对于二进制字符串类型,前缀长度以字节为单位。也就是说,索引项包括CHARVARCHARTEXT列的每个列值的前**_length_**字符,以及BINARYVARBINARYBLOB列的每个列值的前**_length_**字节。只索引列值的前缀可以使索引文件小得多。有关索引前缀的其他信息,请参见创建索引 · 语雀
    • 只有InnoDB和MyISAM引擎支持在BLOBTEXT列上创建索引,示例:

      CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
      
    • 从MySQL 5.7.17开始,如果指定的索引前缀超过了最大的列数据类型大小,CREATE INDEX将按如下方式处理索引:

      • 对于非惟一索引,要么出现错误(如果启用了strict的SQL mode),要么将索引长度减少到列数据类型的最大大小以内,并产生一个警告(如果没有启用strict的SQL mode)。
      • 对于惟一索引,无论SQL模式如何,都会发生错误,因为减少索引长度可能会允许插入不满足指定惟一性要求的非惟一条目。
    • 无法索引 JSON 列。您可以通过在从 JSON 列中提取标量值的生成列上创建索引来解决此限制。参考: Indexing a Generated Column to Provide a JSON Column Index
  • NOT NULL | NULL
    • 如果既未指定 NULL 也未指定 NULL,默认为 NULL。
    • 在MySQL 5.7中,只有InnoDBMyISAMMEMORY存储引擎支持可以具有空值的列的索引。在其他情况下,您必须将索引列声明为 NOT NULL 否则将得到错误结果。
  • DEFAULT
    • 指定列的默认值。有关默认值处理的更多信息,参见Data Type Default Values
    • 如果启用了 NO_ZERO_DATENO_ZERO_IN_DATE SQL Mode,并且根据该模式,日期值默认值不正确,如果未启用严格的 SQL 模式,则 CREATE TABLE 会产生警告,如果启用了严格模式,则会产生错误。例如,启用 NO_ZERO_IN_DATE 后,c1 日期默认值 “2010-00” 会产生警告。
  • AUTO_INCREMENT

    • 整数或浮点列可以具有附加属性 AUTO_INCREMENT。当您将 NULL (推荐) 或 0 的值插入索引的 AUTO_INCREMENT 列时,该列将设置为下一个序列值。通常这是值 _value_+1,其中value是当前表中的列的最大值。自动增量序列以 1 开始。
    • 要在插入行后检索AUTO_INCREMENT值,请使用 LAST_INSERT_ID() SQL 函数或 mysql_insert_id()C API 函数。详情参见:“Information Functions”, 和 “mysql_insert_id()
    • 如果启用了 NO_AUTO_VALUE_ON_ZERO SQL Mode,则可以将 0 存储在AUTO_INCREMENT列中作为 0,而无需生成新的序列值。参见“Server SQL Modes”
    • 每个表只能有一个AUTO_INCREMENT,它必须被索引,并且不能有默认值。只有当AUTO_INCREMENT列仅包含正值时,它才能正常工作。插入负数被视为插入一个非常大的正数。这样做是为了避免数字从正数 “转换” 到负数时的精度问题,也是为了确保您不会意外获得包含 0 的自动增量列。
    • 对于 MyISAM 表,您可以在多列键(multiple-column key)中指定自动增量辅助列(secondary column)。参见第“Using AUTO_INCREMENT”
    • 为了使 MySQL 与某些 ODBC 应用程序兼容,您可以通过以下查询找到最后插入的行的 AUTO_INCREMENT 值(此方法要求 sql_auto_is_null 变量未设置为 0。参见第“Server System Variables”):

      SELECT * FROM tbl_name WHERE auto_col IS NULL
      
    • 有关 InnoDB 和AUTO_INCREMENT的信息,请参阅“AUTO_INCREMENT Handling in InnoDB””。有关“AUTO_INCREMENT Handling in InnoDB”和 MySQL 复制的信息,请参阅 “Replication and AUTO_INCREMENT””。

  • COMMENT
    • 可以使用COMMENT选项指定列的注释,长度最多为 1024 个字符。注释由 SHOW CREATE TABLESHOW FULL COLUMNS语句显示。
  • COLUMN_FORMAT
    • 在 NDB 集群中,也可以使用 COLUMN_FORMAT 为 NDB 表的各个列指定数据存储格式。允许的列格式是FIXEDDYNAMICDEFAULTFIXED用于指定固定宽度存储,DYNAMIC允许列可变宽度,和DEFAULT导致列使用固定宽度或可变宽度存储,由列的数据类型决定 (可能被 ROW_FORMAT 覆盖)。
    • 从 MySQL NDB 集群 7.5.4 开始,对于 NDB 表,COLUMN_FORMAT 的默认值是FIXED。(在 MySQL NDB 集群 7.5.1 中,默认值已切换到DYNAMIC,但该更改已恢复,以保持与现有 GA 发布系列的向后兼容性。)(Bug #24487363)
    • 在 NDB 集群中,用 COLUMN_FORMAT=FIXED定义的列的最大可能偏移量为 8188 字节。有关更多信息和可能的解决方法,请参见“Limits Associated with Database Objects in NDB Cluster”
    • COLUMN_FORMAT 目前对使用 NDB 以外的存储引擎的表的列没有影响。在 MySQL 5.7 及更高版本中,COLUMN_FORMAT 被静默忽略。
  • STORAGE
    • 对于 NDB 表,可以使用STORAGE子句指定列是存储在磁盘上还是存储在内存中。STORAGE DISK导致列存储在磁盘上,STORAGE MEMORY导致使用内存中存储。使用的 CREATE TABLE 语句仍然必须包含表空间子句: ```sql 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` 子句对使用 NDB 以外的存储引擎的表没有影响。`STORAGE`关键字仅在 `NDB` 集群提供的 `mysqld` 构建中受支持; 在任何其他版本的 MySQL 中都无法识别。任何使用 `STORAGE` 关键字的尝试都会导致语法错误。
- `GENERATED ALWAYS`
   - 用于指定生成的列表达式。有关生成列的信息,请参阅[“CREATE TABLE and Generated Columns”](https://dev.mysql.com/doc/refman/5.7/en/create-table-generated-columns.html)。
   - [Stored generated columns](https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_stored_generated_column)可以被索引。InnoDB 支持[virtual generated columns](https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_virtual_generated_column)的二级索引。参见:[“Secondary Indexes and Generated Columns”](https://dev.mysql.com/doc/refman/5.7/en/create-table-secondary-indexes.html)。
<a name="i9Swn"></a>
### 索引和外键(Indexes and Foreign Keys)
有几个关键字适用于创建索引和外键。除了以下描述之外,有关背景信息,请参见[创建索引 · 语雀](https://www.yuque.com/kylinxiang/mysql/axoxwg?view=doc_embed)和[FOREIGN KEY Constraints](https://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html)。

- `CONSTRAINT _`symbol`_`
   - 可以使用`CONSTRAINT _`symbol`_`子句来命名一个约束。如果没有给出子句,或者在`CONSTRAINT`关键字后面没有包含_`symbol`_,MySQL 会自动生成一个约束名称,除了下面提到的例外。如果使用_`symbol`_值,则每个schema (database) 中每个约束类型都必须是唯一的。重复的_`symbol`_会导致错误。另请参见[“Identifier Length Limits”](https://dev.mysql.com/doc/refman/5.7/en/identifier-length.html)” 中关于生成的约束标识符长度限制的讨论。
   - NOTE如果外键定义中没有给出`CONSTRAINT _`symbol`_`子句,或者`CONSTRAINT`关键字后面没有包含_`symbol`_,则 NDB 使用外键索引名称。
   - SQL 标准指定所有类型的约束 (主键、唯一索引、外键、检查) 都属于同一命名空间。在 MySQL 中,每个约束类型都有自己的命名空间。因此,每种约束类型的名称必须是每个schema唯一的。
- `PRIMARY KEY`
   - 一个唯一索引,其中所有键列都必须定义为 `NOT NULL`。如果它们没有被显式声明为 `NOT NULL`,MySQL 会隐式 (并且以静默方式) 声明它们。一个表只能有一个主键。主键的名称始终是 `PRIMARY`,因此不能用作任何其他类型索引的名称。
   - 如果没有主键,并且应用程序要求表中的主键,MySQL 将返回第一个没有空列的唯一索引作为主键。
   - 在 InnoDB 表中,保持主键短,以最大限度地减少二级索引的存储开销。每个二级索引条目都包含相应行的主键列的副本。(参见[“Clustered and Secondary Indexes”](https://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html)
   - BEST PRACTICE在创建的表中,首先放置`PRIMARY KEY`,然后放置所有`UNIQUE`索引,然后放置非唯一索引。这有助于 MySQL 优化器确定要使用的索引的优先级,并更快地检测重复的唯一键。
   - `PRIMARY KEY`可以是多列索引。但是,不能使用列规范中的`PRIMARY KEY`键属性创建多列索引。这样做只会将该单列标记为`primary`。您必须使用单独的 `PRIMARY KEY(_`key_part`_, ...)`子句。
   - 如果表有一个`PRIMARY KEY`或`UNIQUE NOT NULL` 索引,该索引由具有整数类型的单个列组成,则可以使用 `_ rowid` 引用 `SELECT` 语句中的索引列,如[Unique Indexe](https://dev.mysql.com/doc/refman/5.7/en/create-index.html#create-index-unique)中所述。
   - 在 MySQL 中,`PRIMARY KEY`的名称是 `PRIMARY`。对于其他索引,如果不指定名称,则为索引指定与第一个索引列相同的名称,并带有可选后缀 (`_2`,_`3`,`...`) 使其独特。您可以使用 `SHOW INDEX FROM _`tbl_name`_` 查看表的索引名称。参见见“[SHOW INDEX Statement](https://dev.mysql.com/doc/refman/5.7/en/show-index.html)”。
- `KEY | INDEX`

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

- `UNIQUE`
   - 唯一索引会创建约束,以便索引中的所有值都必须是不同的。如果尝试添加具有与现有行匹配的键值的新行,则会发生错误。对于所有引擎,唯一索引允许包含 `NULL` 的列有多个 `NULL` 值。如果在唯一索引中为列指定前缀值,则列值在前缀长度内必须是唯一的。
   - 如果表有一个主键或唯一的 `NOT NULL` 索引,该索引由具有整数类型的单个列组成,则可以使用 `_rowid` 引用 `SELECT` 语句中的索引列,如[Unique Indexe](https://dev.mysql.com/doc/refman/5.7/en/create-index.html#create-index-unique)中所述。
- `FULLTEXT`
   - 全文索引是一种用于全文搜索的特殊类型的索引。只有 InnoDB 和 MyISAM 存储引擎支持全文索引。它们只能从 `CHAR` 、`VARCHAR` 和 `TEXT` 列创建。索引总是发生在整个列上; 不支持列前缀索引,如果指定,则忽略任何前缀长度。有关操作的详细信息,请参见[“Full-Text Search Functions”](https://dev.mysql.com/doc/refman/5.7/en/fulltext-search.html)。如果全文索引和搜索操作需要特殊处理,可以将带有`PARSER`子句指定为 `index_option` 值,以将解析器插件与索引相关联。此子句仅对全文索引有效。InnoDB 和 MyISAM 都支持全文解析器插件。有关更多信息,请参见[Full-Text Parser Plugins](https://dev.mysql.com/doc/refman/5.7/en/plugin-types.html#full-text-plugin-type) 和[ “Writing Full-Text Parser Plugins”](https://dev.mysql.com/doc/refman/5.7/en/writing-full-text-plugins.html)。
- `SPATIAL`
   - 您可以在`Spatial`数据类型上创建`SPATIAL`索引。仅 MyISAM 和 InnoDB 表支持空间类型,索引列必须声明为 `NOT NULL`。参见:“[Spatial Data Types”](https://dev.mysql.com/doc/refman/5.7/en/spatial-types.html)。
- `FOREIGN KEY`
   - MySQL 支持外键,让你交叉参考相关数据表和外键约束,帮助传播数据一致。定义和选项信息,见 `reference_definition`,`reference_option`。
   - 分区表采用 InnoDB 存储引擎不支持外键。见 [“Restrictions and Limitations on Partitioning”](https://dev.mysql.com/doc/refman/5.7/en/partitioning-limitations.html)。
- `CHECK`
   - `CHECK` 子句只被解析,所有存储引擎都将忽略它。
- `_`key_part`_`
   - `key_part` 规范可以以 `ASC` 或 `DESC` 结尾。这些关键字允许用于将来指定升序或降序索引值存储的扩展。目前,它们被解析但被忽略; 索引值总是按升序存储。
   - 前缀由 `length` 属性定义,对于 InnoDB 表,长度最多为 `767` 字节,如果启用了 `innodb_large_prefix` 选项,则长度最多为 `3072` 字节。对于 MyISAM 表,前缀长度限制为 `1000` 字节。
   - 前缀限制以字节为单位。然而,`CREATE TABLE` 、 `ALTER TABLE` 和 `CREATE index` 语句中索引规范的前缀长度被解释为非二进制字符串类型 (`CHAR` 、 `VARCHAR` 、 `TEXT`) 的字符数和二进制字符串类型 (`BINARY`、 `VARBINARY` 、 `BLOB`) 的字节数。在为使用多字节字符集的非二进制字符串列指定前缀长度时考虑到这一点。
- `_`index_type`_`
   - 一些存储引擎允许您在创建索引时指定索引类型。`index_type` 说明符的语法是`USING type_name`。示例:
```sql
CREATE TABLE lookup
  (id INT, INDEX USING BTREE (id))
  ENGINE = MEMORY;
  • USING的首选位置在索引列列表之后。它可以在列之前给出,但是对在该位置使用该选项的支持已被弃用,并将在未来的 MySQL 版本中删除。

    • _indexoption`指定索引的其他选项`.
      index_option:
      KEY_BLOCK_SIZE [=] value
      | index_type
      | WITH PARSER parser_name  #仅对全文索引有效
      | COMMENT 'string'
      
  • KEY_BLOCK_SIZE

    • 对于 MyISAM 表,KEY_BLOCK_SIZE (可选) 指定用于索引键块的字节大小。该值被视为提示; 如果需要,可以使用不同的大小。为单个索引定义指定的 KEY_BLOCK_SIZE 值将覆盖表级 KEY_BLOCK_SIZE 值。有关表级 KEY_BLOCK_SIZE 属性的信息,请参Table Options
  • WITH PARSER
    • WITH PARSER选项只能与全文索引一起使用。如果全文索引和搜索操作需要特殊处理,它会将解析器插件与索引相关联。InnoDB 和 MyISAM 都支持全文解析器插件。如果您有一个带有相关全文解析器插件的 MyISAM 表,您可以使用 ALTER TABLE 将该表转换为 InnoDB。
  • COMMENT
  • 有关 index_option 的更多信息,请参阅创建索引 · 语雀,有关索引的更多信息,请参阅“How MySQL Uses Indexes”

    • _referencedefinition``
      reference_definition:
      REFERENCES tbl_name (key_part,...)
      [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]
      [ON DELETE reference_option]
      [ON UPDATE reference_option]
      
  • 有关reference_definition语法的详细信息和示例,请参见“FOREIGN KEY Constraints”

  • InnoDB 和 NDB 表支持外键约束的检查。引用表的列必须始终显式命名。支持对外键执行 ON DELETEON UPDATE 操作。有关更多详细信息和示例,请参见“FOREIGN KEY Constraints”
  • 对于其他存储引擎,MySQL 服务器解析并忽略 CREATE TABLE 语句中的FOREIGN KEYREFERENCES语法。参见FOREIGN KEY Constraint Differences””。
  • IMPORTANT对于熟悉 ANSI/ISO SQL 标准的用户,请注意,没有任何存储引擎 (包括 InnoDB) 识别或强制执行引用完整性约束定义中使用的MATCH子句。使用显式MATCH子句不会产生指定的效果,还会导致 ON DELETEON UPDATE 子句被忽略。由于这些原因,应避免指定MATCH
  • IMPORTANTSQL 标准中的 MATCH 子句控制在与主键进行比较时如何处理复合 (多列) 外键中的空值。InnoDB 本质上实现了 MATCH SIMPLE 定义的语义,这允许外键为全部或部分 NULL。在这种情况下,允许插入包含此类外键的 (子表) 行,并且与引用的 (父) 表中的任何行不匹配。可以使用触发器实现其他语义。
    IMPORTANT此外,为了性能,MySQL 要求对引用的列进行索引。但是,InnoDB 不强制任何要求引用的列被声明为UNIQUENOT NULL。对于UPDATE or DELETE CASCADE等操作,对非唯一键或包含 NULL 值的键的外键引用的处理没有很好地定义。建议您使用仅引用UNIQUE (或PRIMARY) 且NOT NULL的键的外键。(也就是说BEST PRACTICE外键引用的键最好为UNIQUENOT NULL,或者PRIMARY。)
  • IMPORTANTMySQL 解析但忽略 “内联REFERENCES规范” (在 SQL 标准中定义),其中引用被定义为列规范的一部分。仅当指定为单独的外键规范的一部分时,MySQL 才接受引用REFERENCES

    • _referenceoption``
      reference_option:
      RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
      
  • 有关RESTRICT, CASCADE, SET NULL, NO ACTION, 和 SET DEFAULT选项的信息,请参“FOREIGN KEY Constraints”

    表选项(Table Options)

    table_option:
    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
    | 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}
    | STATS_AUTO_RECALC [=] {DEFAULT|0|1}
    | STATS_PERSISTENT [=] {DEFAULT|0|1}
    | STATS_SAMPLE_PAGES [=] value
    | TABLESPACE tablespace_name [STORAGE {DISK|MEMORY}]
    | UNION [=] (tbl_name[,tbl_name]...)
    

    表选项用于优化表的行为。在大多数情况下,您不必指定其中的任何一个。除非另有说明,否则这些选项适用于所有存储引擎。不适用于给定存储引擎的选项可能会被接受并作为表定义的一部分被记住。如果您以后使用 ALTER TABLE 将表转换为使用不同的存储引擎,则会应用此类选项。

  • ENGINE

  • AUTO_INCREMENT
    • 表的初始AUTO_INCREMENT值。在 MySQL 5.7 中,这适用于MyISAM, MEMORY, InnoDB, 和 ARCHIVE 。要为不支持 AUTO_INCREMENT 表选项的引擎设置第一个自动增量值,请在创建表后插入一个值小于所需值 1 的 “dummy” 行,然后删除虚拟行。
    • 对于在 CREATE TABLE 语句中支持 AUTO_INCREMENT表选项的引擎,您也可以使用 ALTER TABLE tbl_name AUTO_INCREMENT = N 重置 AUTO_INCREMENT 值。该值不能设置为低于当前列中的最大值。
  • AVG_ROW_LENGTH
    • 表的平均行长度的近似值。您只需要对具有可变大小行的大表进行设置。
    • 创建 MyISAM 表时,MySQL 使用 MAX_ROWSAVG_ROW_LENGTH 选项的乘积来决定结果表的大小。如果未指定任一选项,则默认情况下 MyISAM 数据和索引文件的最大大小为 256TB。(如果您的操作系统不支持如此大的文件,则表大小受文件大小限制。)如果您想降低指针大小以使索引更小、更快,并且实际上不需要大文件,可以通过设置 myisam_data_pointer_size 系统变量来减小默认指针大小。(参见“Server System Variables”)如果您希望您的所有表能够超过默认限制,并且愿意让您的表比必要的稍慢和更大,您可以通过设置此变量来增加默认指针大小。将该值设置为 7 允许表大小高达 65,536TB
  • [DEFAULT] CHARACTER SET
    • 指定表的默认字符集。CHARSETCHARACTER SET的同义词。如果字符集名称为DEFAULT,则使用数据库字符集。
  • CHECKSUM
    • 如果您希望 MySQL 为所有行维护实时校验和 (即,当表发生变化时,MySQL 会自动更新的校验和),请将其设置为 1。这使得表的更新速度稍慢,但也更容易找到损坏的表。CHECKSUM TABLE语句报告校验和。(仅限 MyISAM。)