文档:https://dev.mysql.com/doc/refman/5.7/en/create-table.html
CREATE TABLE
主题:介绍 MySQL 中的 CREATE TABLE 的语法;
吐槽一下自己,下面是我能写出的最复杂的 CREATE TABLE 语句了:
CREATE TABLE DEMO( ID INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(16) NOT NULL DEFAULT '' COMMENT 'Username', ....... )ENGINE=INNODB DEFAULT CHARSET UTF8
语法
这个的语法功能可是很长的,远比想想中多得多,而平时用的却是基础中的基础:
语句结构概览
…
权限
CREATE TABLE 时必须有 CREATE 权限;
默认情况下,表创建在当前数据库中,存储引擎为 InnoDB。表已经存在,或者没有选择当前数据库,或者数据不存在则报错;
在硬盘中,CREATE TABLE 创建的文件
MySQL 通过.frm 表格式(定义)文件表示每张表,默认使位于 data 目录的。所以.frm 文件使共有的。但是存储引擎可能会创建其他文件;
对于 MyISAM 存储引擎
会在硬盘上创建三个文件:
tbl_name.MYD 数据文件
tbl_name.MYI 索引文件
对于 InnoDB 存储引擎
对于在独立表文件表空间中创建的 InnoDB 表或者一般表空间,表数据和关联的索引存储在 ibd 文件中。当在系统表空间中创建了 InnoDB 表,表数据和索引存储在表示系统表空间的 ibdata* 文件中。innodb_file_per_table 选项控制了在默认情况下是创建独立表文件表空间还是系统表空间。TABLESPACE 选项可以无视 innodb_file_per_table 选项的设置,控制表存放在独立表文件表空间、一般表空间、系统表空间;
其他存储引擎
对于其他存储引擎创建的文件,查看:https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html
如果表名中含有特殊字符,表文件名称会包含这些字符的编码版本,查看:https://dev.mysql.com/doc/refman/5.7/en/identifier-mapping.html
ibdata 文件
文件名为 ibdata1、ibdata2…的文件集合组成了 InnoDB 的系统表空间。文件包含了 InnoDB 表的元数据、用于一个或多个 undo 日志的存储区域、变更缓冲、双写缓冲。他们也可以包含一些或者全部的表数据(取决于当表创建时吃否受独立表文件模式的影响)。当启用了 innodb_file_per_table option 选项,对于新创建的表,数据和索引被保存在独立的.ibd 文件而不是系统表空间;
ibdata 文件的增长受 innodb_autoextend_increment 选项的影响;
ibd 文件
用于独立表文件表空间和一般表空间的数据文件。独立表文件表空间的.ibd 文件包含了单个表和关联的索引数据。一般表空间的.ibd 文件可能包含了用于多张表的表和索引数据。一般表空间在 MySQL5.7.6 中引入的;
.ibd 文件扩展名不会应用于系统表空间,系统表空间由一个或多个 ibdata 文件组成;
如果一个独立表文件表空间或者一般表空间在创建的时候使用了 DATA DIRECTORY = clause,.ibd 文件会放在指定的路径,通常数据目录的外边,并且被一个.isl 文件指向;
当.ibd 文件包含在由 MySQL Enterprise Backup 产品压缩的备份中时,压缩等价于.ibz 文件;
isl 文件
对于在 MySQL 5.6 中创建 InnoDB 表时使用了“DATA DIRECTORY =”或者在 MySQL 5.7.8+中使用了“CREATE TABLESPACE … ADD DATAFILE”,该文件指明了.ibd 文件的位置,它的功能有点像符号链接,没有平台限制的实际符号链接机制。您可以将 InnoDB 表空间存储在数据库目录之外,比如,在特别大或快速的存储设备上,具体取决于表的用途。如何在数据目录之外创建独立表文件表空间,查看:https://dev.mysql.com/doc/refman/5.7/en/tablespace-placing.html%E3%80%82InnoDB%E7%9A%84%E4%B8%80%E8%88%AC%E8%A1%A8%E7%A9%BA%E9%97%B4%EF%BC%8C%E6%9F%A5%E7%9C%8B%EF%BC%9Ahttps://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html
建表语句的存储
创建表时,原始的 CREATE TABLE 语句(包括所有规范和表选项)由 MySQL 存储。详细信息参考文档:https://dev.mysql.com/doc/refman/5.7/en/create-table-statement-retention.html
临时表
创建表的时候可以使用TEMPORARY关键字。此时会创建一个只有当前 session 可见的临时表,在 session 关闭的时候会自动删除。这就表示两个不同的 session 可以使用相同的表名而不会产生混乱,或者和一张已经存在的非临时表具有相同的名字(注意:在临时表删除之前,同名的非临时表是不可见的)。如果要创建临时表必须要有 CREATE TEMPORARY TABLES 权限;
如果使用了 TEMPORARY 关键字,CREATE TABLE 不会自动提交当前活动的事物;
TEMPORARY 表和当前数据库的关系非常松散。删除某个数据库不会删除当前数据库下的临时表。此外,如果使用 CREATE TABLE 语句中的数据库名称限定表名,则可以在不存在的数据库中创建 TEMPORARY 表,在这种情况下,对表的所有后续引用必须使用数据库名称进行限定;
表名
tbl_name
以 db_name.tbl_name 的形式指定在哪个库中创建表,当然,数据库必须是存在的。如果要引用标识符,正确的格式是`mydb`.`mytbl`,而非 `mydb.mytbl`;
关于合法的表明,查看:https://dev.mysql.com/doc/refman/5.7/en/identifiers.html
IF NOT EXISTS
防止由于表存在而产生的错误。这个只是简单的检查表名是否存在,并不会去检查表的结构;
列 | Column
ON UPDATE
ALTER TABLE samaritan.phonenumber ADD COLUMN modify_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
克隆或复制表
LIKE
使用 CREATE TABLE … LIKE 创建一张基于另一个表的定义的空表,包含了源表的列属性、索引定义:
更多信息及语法,查看:https://dev.mysql.com/doc/refman/5.7/en/create-table-like.html
[AS] query_expression
从另一张表中创建一张表,在 CREATE TABLE 后面添加一个 SELECT 语句:
更多的信息及语法,查看:
https://dev.mysql.com/doc/refman/5.7/en/create-table-select.html
IGNORE|REPLACE
IGNORE 和 REPLACE 选项指示在使用 SELECT 语句复制表时如何处理重复唯一键值的行;
更多的信息及语法,查看:https://dev.mysql.com/doc/refman/5.7/en/create-table-select.html
列数据类型和属性
每个表最多有 4096 个列,但对于给定表格的有效最大值可能较少,并且取决于某些因素,详情查看:https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html
data_type
data_type 表示列定义的数据类型。spatial_type 表示空间数据类型。关于数据类型的详细介绍,查看《Data Type》;
有些属性并不能用于所有的数据类型。AUTO_INCREMENT 只能用于浮点数和整数。DEFAULT 不能应用于 BLOB,、TEXT、GEOMETRY、JSON 类型;
字符数据类型 (CHAR, VARCHAR, TEXT)可以包含 CHARACTER SET 和 COLLATE 属性用于指定字符集和校对规则。详细查看:https://dev.mysql.com/doc/refman/5.7/en/charset.html CHARSET 和 CHARACTER SET 是同义的。看 Demo:
MySQL 5.7 以字符为单位解释字符列定义中的长度规范。BINARY 和 VARBINARY 的长度以字节为单位;
对于 CHAR, VARCHAR, BINARY, VARBINARY 类型的列,索引只能使列值的前缀部分,使用 col_name(length)语法指定索引前缀的长度。BLOB 和 TEXT 类型的列亦是。对于非二进制类型给出的前缀长度指的是字符个数,而二进制类型的字符串指的是字节数。关于索引的更多内容,查看:《CREATE INDEX》
只有 InnoDB 和 MyISAM 存储引擎支持在 BLOB 和 TEXT 上创建索引,Demo:
NOT NULL | NULL
如果未指定,则默认为 NULL,表示列值允许为 NULL;
在 MySQL 5.7 中,只有 InnoDB, MyISAM, MEMORY 存储引擎支持在可为 NULL 的列上创建索引。其他的情况下,只能在非空的列上创建索引;
DEFAULT
指定列的默认值。默认值必须是常量,不能是表达式或者函数。意思是说,不能将 DATE 类型的列的默认值设置为诸如 NOW()或 CURRENT_DATE 之类的函数的值。例外是可以将 CURRENT_TIMESTAMP 指定为 TIMESTAMP 或 DATETIME 类型的列的默认值。关于“为 TIMESTAMP 和 DATETIME 自动初始化和更新”,查看:https://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html
如果没有指定默认值,各个数据类型的默认值是不同的,详细查看:《Data Type》
BLOB, TEXT, JSON 类型列不能设置默认值;
如果 SQL mode 设置了 NO_ZERO_DATE 或 NO_ZERO_IN_DATE,并且在该模式下,如果 DATA 的默认值不正确,那么:如果未启用严格 SQL mode,则 CREATE TABLE 会生成警告,如果启用了严格模式,则会产生错误。例如,启用了 NO_ZERO_IN_DATE,col1 DATE DEFAULT ‘2010-00-00’会产生警告;
AUTO_INCREMENT
整数或浮点列可以具有 AUTO_INCREMENT。将 NULL(推荐的值)或 0 值插入索引的AUTO_INCREMENT 列时,列被设置为下一个序列值(通常是表中当前列的最大值+1)。AUTO_INCREMENT 序列从 1 开始;
要在插入行之后检索 AUTO_INCREMENT 值,使用 LAST_INSERT_ID()(SQL 函数)或 mysql_insert_id()(C 的 API 函数)。详情查看:https://dev.mysql.com/doc/refman/5.7/en/information-functions.html%EF%BC%8C%E4%BB%A5%E5%8F%8A%EF%BC%9Ahttps://dev.mysql.com/doc/refman/5.7/en/mysql-insert-id.html
如果 SQL mode 设置了 NO_AUTO_VALUE_ON_ZERO,则在 AUTO_INCREMENT 列中可以将 0 存储为 0,而不生成新的序列值。详情:https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html
每个表只能有一个 AUTO_INCREMENT 列,它必须被索引,并且它不能有一个 DEFAULT 值。仅在包含正值时,AUTO_INCREMENT 的列才能正常工作。插入负数被认为是插入非常大的正数。这样做是为了避免在数字从“正”到负”之间的精确度问题,并确保 AUTO_INCREMENT 列不会有 0;
对于 MyISAM 表,可以在多列索引中指定 AUTO_INCREMENT 辅助列。详情:https://dev.mysql.com/doc/refman/5.7/en/example-auto-increment.html
要使 MySQL 与某些 ODBC 应用程序兼容,可以使用以下 SELECT 找到最后插入的行的 AUTO_INCREMENT 值:
但是,此方法要求 sql_auto_is_null 变量未设置为 0。详情查看:https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html
关于 InnoDB 和 AUTO_INCREMENT 的更多内容可以查看文档:https://dev.mysql.com/doc/refman/5.7/en/innodb-auto-increment-handling.html
AUTO_INCREMENT 和 MySQL Replication 可以查看文档:https://dev.mysql.com/doc/refman/5.7/en/replication-features-auto-increment.html
COMMENT
通过 COMMENT 可以为列添加注释,最多 1024 个字符。可以通过 SHOW CREATE TABLE 和 SHOW FULL COLUMNS 查看注释;
COLUMN_FORMAT
在 NDB 集群中,也可以使用 COLUMN_FORMAT 为 NDB 表的各列指定数据存储格式。允许列格式有:FIXED,DYNAMIC 和 DEFAULT。FIXED 用于指定固定宽度存储,DYNAMIC 允许列为可变宽度,DEFAULT 使列使用由列的数据类型定义的固定宽度或可变宽度来存储(可能被 ROW_FORMAT 说明符覆盖);
从 MySQL NDB Cluster 7.5.4 开始,COLUMN_FORMAT 的默认值为 FIXED,MySQL NDB Cluster 7.5.1 中的默认值已切换到 DYNAMIC,但是这种更改已恢复,以保持与现有 GA 版本系列的向后兼容性。(Bug #24487363)
COLUMN_FORMAT 目前对使用 NDB 以外的存储引擎的表的列没有影响。在 MySQL 5.7+版本中,COLUMN_FORMAT 被忽略;
STORAGE
对于 NDB 表,可以通过使用 STORAGE 来指定列是存储在 disk 上还是 memory 中。STORAGE DISK 导致列存储在磁盘上,STORAGE MEMORY 导致使用内存中的存储空间。并且使用的 CREATE TABLE 语句必须包含 TABLESPACE。对于 NDB 表,STORAGE DEFAULT 等同于 STORAGE MEMORY;
STORAGE 对使用 NDB 以外的存储引擎的表不起作用。STORAGE 关键字仅在提供了 NDB Cluster 的 mysqld 的构建中受到支持;在任何其他版本的 MySQL 中都不会识别,因为任何对 STORAGE 关键字的使用都会导致语法错误;
GENERATED ALWAYS
用于指定生成的列表达式。相关内容查看:
https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_generated_column
https://dev.mysql.com/doc/refman/5.7/en/create-table-generated-columns.html
存储的生成列(Stored generated columns)可以索引。InnoDB 支持在虚拟生成列(virtual generated columns)上的辅助索引。相关内容可以查看:
https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_stored_generated_column
https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_virtual_generated_column
https://dev.mysql.com/doc/refman/5.7/en/create-table-secondary-indexes.html
索引和外键
CONSTRAINT symbol
如果给出了CONSTRAINT symbol,如果使用了 symbol,那么 symbol 在数据库中必须是唯一的。重复的 symbol 会导致错误。如果没有给出子句,或者在 CONSTRAINT 后没有给出 symbol,则会自动创建约束的名称;
PRIMARY KEY
唯一索引的所有索引列必须定义为 NOT NULL。如果没有被明确声明为 NOT NULL,MySQL 就会隐式地声明它们(并且默认地)。表只能有一个 PRIMARY KEY。PRIMARY KEY 的名称始终为 PRIMARY,因此不能将其用作任何其他类型的索引的名称;
如果没有 PRIMARY KEY,并且应用程序要求表中的 PRIMARY KEY,MySQL 将返回没有 NULL 列的第一个 UNIQUE 索引作为 PRIMARY KEY;
在 InnoDB 表中,保持 PRIMARY KEY 短小,可以减少辅助索引的存储开销。每个辅助索引条目包含相应行的主键列的副本。详细内容:https://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html
在创建的表中,建议首先设置 PRIMARY KEY,然后设置所有 UNIQUE 索引,然后是非唯一索引。这有助于 MySQL 优化器优先使用哪个索引,也可以更快地检测重复的 UNIQUE 索引;
PRIMARY KEY 可以是多列索引。但是,不能使用列规范中的 PRIMARY KEY 键属性创建多列索引,这样做只会将单列标记为主要列。必须使用单独的 PRIMARY KEY(index_col_name,…)子句;
如果一个 PRIMARY KEY 只包含一个具有整数类型的列,那么也可以在 SELECT 语句中引用列为_rowid。详细内容查看文档:https://dev.mysql.com/doc/refman/5.7/en/select.html
在 MySQL 中,PRIMARY KEY 的名称为 PRIMARY。对于其他索引,如果不指定名称,索引名为第一个索引列的名称,并具有可选的后缀(_2,_3,…),以保证其唯一。可以使用 SHOW INDEX FROM tbl_name 查看表的索引名称。SHOW 的语法详细内容可以查看文档:https://dev.mysql.com/doc/refman/5.7/en/show-index.html
KEY | INDEX
KEY 通常是 INDEX 的同义词。在列定义中给出时,PRIMARY KEY 也可以指定为 KEY。这是为了和其他数据库兼容;
UNIQUE
UNIQUE 索引会创建一个约束,使得索引中的所有值必须是不同的。如果要插入的行中的唯一索引列的值已经在存在于索引中,会导致错误。对于所有引擎,UNIQUE 索引允许可以包含 NULL 的列的多个 NULL 值;
如果一个 UNIQUE 索引只包含一个具有整数类型的列,那么也可以在 SELECT 语句中将该列引用为_rowid。详细内容查看文档:https://dev.mysql.com/doc/refman/5.7/en/select.html
FULLTEXT
FULLTEXT 索引是用于全文搜索的特殊类型的索引。只有 InnoDB 和 MyISAM 存储引擎支持 FULLTEXT 索引。只有 CHAR,VARCHAR 和 TEXT 列支持创建 FULLTEXT。索引总是发生在整个列上;不支持列前缀索引,如果指定了,任何前缀长度都将被忽略。有关操作的详细信息,请参见:https://dev.mysql.com/doc/refman/5.7/en/fulltext-search.html
如果全文索引和搜索操作需要特殊处理,则可以将 WITH PARSER 指定为 index_option 值,将解析器插件与索引相关联。此子句仅对 FULLTEXT 索引有效。InnoDB 和 MyISAM 都支持全文解析器插件。其他的全文转化插件信息,请参见文档:
https://dev.mysql.com/doc/refman/5.7/en/plugin-types.html#full-text-plugin-type
https://dev.mysql.com/doc/refman/5.7/en/writing-full-text-plugins.html
SPATIAL
可以在空间数据类型上创建 SPATIAL 索引。空间类型仅支持 MyISAM 和 InnoDB 表,索引列必须声明为 NOT NULL。详细内容参见文档中“空间数据扩展”:https://dev.mysql.com/doc/refman/5.7/en/spatial-extensions.html
CHECK
CHECK 子句被解析,但被所有存储引擎忽略。详细内容查看文档中“外键差异”:https://dev.mysql.com/doc/refman/5.7/en/ansi-diff-foreign-keys.html
FOREIGN KEY
MySQL 支持外键,可让您跨表参考相关数据和外键限制,有助于保持这种扩展数据的一致性;
关于定义和选项的信息,查看:
https://dev.mysql.com/doc/refman/5.7/en/create-table.html#create-table-reference-definition
https://dev.mysql.com/doc/refman/5.7/en/create-table.html#create-table-reference-option
采用 InnoDB 存储引擎的分区表不支持外键。关于分区的限制,查看文档:
https://dev.mysql.com/doc/refman/5.7/en/partitioning-limitations.html
index_col_name
index_col_name 规范可以以 ASC 或 DESC 结尾。这些关键字被允许用于指定升序或降序索引值存储的未来扩展。目前,他们被解析,但被忽视;索引值始终以升序存储;
对于 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。例如:
(id INT, INDEX USING BTREE (id))
ENGINE = MEMORY;
使用的首选位置在索引列列表之后。它可以在列列表之前给出,但支持使用该位置的选项已被弃用,并将在将来的 MySQL 版本中被删除;
index_option
index_option 的值指定了一个索引的附加选项:
KEY_BLOCK_SIZE
对于 MyISAM 表,KEY_BLOCK_SIZE 可选地指定要用于索引 key 块的大小(以字节为单位)。该值被视为提示;如果需要,可以使用不同的尺寸。为单个索引定义指定的 KEY_BLOCK_SIZE 值将覆盖表级别的 KEY_BLOCK_SIZE 值。更多表级 KEY_BLOCK_SIZE 的信息,查看:https://dev.mysql.com/doc/refman/5.7/en/create-table.html#create-table-options
WITH PARSER
WITH PARSER 选项只能与 FULLTEXT 索引一起使用。如果全文索引和搜索操作需要特殊处理,它会将解析器插件与索引相关联。InnoDB 和 MyISAM 都支持全文解析器插件。如果一个 MyISAM 表包含相关全文解析器插件,则可以使用 ALTER TABLE 将表转换为 InnoDB;
COMMENT
在 MySQL 5.7 中,索引定义可以包含最多 1024 个字符的可选注释。可以使用 index_option COMMENT 子句为单个索引设置 InnoDB MERGE_THRESHOLD 值。参见“配置索引页面的合并阈值”:https://dev.mysql.com/doc/refman/5.7/en/index-page-merge-threshold.html
有关允许的 index_option 值的更多信息,参见:https://dev.mysql.com/doc/refman/5.7/en/create-index.html%EF%BC%9B
有关索引的更多信息,参见:https://dev.mysql.com/doc/refman/5.7/en/mysql-indexes.html
reference_definition
有关 reference_definition 语法详细信息和示例,参见“使用 FOREIGN KEY 约束”:https://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html
有关 InnoDB 中外键的信息,参见“InnoDB 和 FOREIGN KEY 约束”:https://dev.mysql.com/doc/refman/5.7/en/innodb-foreign-key-constraints.html
InnoDB 和 NDB 表支持检查外键约束。引用表的列必须始终被明确命名。支持对外键的 ON DELETE 和 ON UPDATE 操作。有关更多详细信息和示例,参见“使用 FOREIGN KEY 约束”:https://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html%E3%80%82%E6%9C%89%E5%85%B3 InnoDB 中外键的信息,参见“InnoDB 和 FOREIGN KEY 约束”:https://dev.mysql.com/doc/refman/5.7/en/innodb-foreign-key-constraints.html
对于其他存储引擎,MySQL Server 解析并忽略 CREATE TABLE 语句中的 FOREIGN KEY 和 REFERENCES 语法。“外键差异”:https://dev.mysql.com/doc/refman/5.7/en/ansi-diff-foreign-keys.html
注意:对于熟悉 ANSI/ISO SQL 标准的用户,请注意,没有存储引擎(包括 InnoDB)可以识别或强制引用完整性约束定义中使用的 MATCH 子句。使用明确的 MATCH 子句将不具有指定的效果,也会导致 ON DELETE 和 ON UPDATE 子句被忽略。由于这些原因,应避免指定 MATCH。SQL 标准中的 MATCH 子句控制在与主键进行比较时处理复合(多列)外键中的 NULL 值。InnoDB 基本上实现了 MATCH SIMPLE 定义的语义,允许外键全部或部分为空。在这种情况下,允许插入包含这样的外键的(子表)行,并且与引用(父)表中的任何行不匹配。可以使用触发器实现其他语义。另外,MySQL 要求将引用的列编入索引以实现性能。但是,InnoDB 不强制执行引用的列被声明为 UNIQUE 或 NOT NULL 的任何要求。对包含 NULL 值的非唯一键或键的外键引用的处理对于诸如 UPDATE 或 DELETE CASCADE 的操作没有很好地定义。建议您使用仅引用 UNIQUE(或 PRIMARY)和 NOT NULL 的键的外键。MySQL 解析,但忽略“引用”作为列规范的一部分定义的“内联参考规范”(在 SQL 标准中定义)。仅当指定为单独的 FOREIGN KEY 规范的一部分时,MySQL 才接受 REFERENCES 子句;
reference_option
有关 RESTRICT,CASCADE,SET NULL,NO ACTION 和 SET DEFAULT 选项的信息,参见“使用 FOREIGN KEY 约束”:https://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html
表选项
表选项的内容相对较多一些。表选项用于优化表的行为。在大多数情况下,不必指定任何一个。这些选项适用于所有存储引擎,除非另有说明。不适用于给定存储引擎的选项可被接受并记住作为表定义的一部分。如果以后使用 ALTER TABLE 将表转换为使用不同的存储引擎,则这些选项将适用;
ENGINE
使用下面所示的名称指定表的存储引擎。引擎名称可以不引用或引用。引用的名称“DEFAULT”被识别但被忽略;
InnoDB:具有行锁定和外键的事务安全表。新表的默认存储引擎。关于 InnoDB 的信息,参见:https://dev.mysql.com/doc/refman/5.7/en/innodb-storage-engine.html
https://dev.mysql.com/doc/refman/5.7/en/innodb-introduction.html
MyISAM:主要用于只读或大部分读取工作负载的二进制便携式存储引擎。请参见第 16.2 节“MyISAM 存储引擎”。参见:https://dev.mysql.com/doc/refman/5.7/en/myisam-storage-engine.html
MEMORY:此存储引擎的数据仅存储在内存中。参见“存储器存储引擎”:https://dev.mysql.com/doc/refman/5.7/en/memory-storage-engine.html
CSV:以逗号分隔的值格式存储行的表。参见“CSV 存储引擎”:https://dev.mysql.com/doc/refman/5.7/en/csv-storage-engine.html
ARCHIVE:归档存储引擎。参见“ARCHIVE 存储引擎”:https://dev.mysql.com/doc/refman/5.7/en/archive-storage-engine.html
EXAMPLE:一个示例引擎。参见“示例存储引擎”:https://dev.mysql.com/doc/refman/5.7/en/example-storage-engine.html
FEDERATED:访问远程表的存储引擎。参见“联合存储引擎”:https://dev.mysql.com/doc/refman/5.7/en/federated-storage-engine.html
HEAP:这是 MEMORY 的同义词;
MERGE:用作一个表的 MyISAM 表的集合。也称为 MRG_MyISAM。参见“MERGE 存储引擎”:https://dev.mysql.com/doc/refman/5.7/en/merge-storage-engine.html
NDB:集群,容错,基于内存的表,支持事务和外键。又称为 NDBCLUSTER。参见 MySQL NDB Cluster 7.5:https://dev.mysql.com/doc/refman/5.7/en/mysql-cluster.html
默认情况下,如果指定的存储引擎不可用,语句将失败并显示错误。您可以通过从服务器 SQL 模式中删除 NO_ENGINE_SUBSTITUTION 来覆盖此行为(参见“服务器 SQL 模式”:https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html%EF%BC%89%EF%BC%8C%E4%BB%A5%E4%BE%BFMySQL%E5%85%81%E8%AE%B8%E4%BD%BF%E7%94%A8%E9%BB%98%E8%AE%A4%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E%E6%9B%BF%E6%8D%A2%E6%8C%87%E5%AE%9A%E7%9A%84%E5%BC%95%E6%93%8E%E3%80%82%E9%80%9A%E5%B8%B8%E5%9C%A8%E8%BF%99%E7%A7%8D%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8Cdefault_storage_engine%E7%B3%BB%E7%BB%9F%E5%8F%98%E9%87%8F%E7%9A%84%E9%BB%98%E8%AE%A4%E5%80%BC%E6%98%AFInnoDB%E3%80%82%E5%BD%93NO_ENGINE_SUBSTITUTION%E8%A2%AB%E7%A6%81%E7%94%A8%E6%97%B6%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%B8%8D%E9%81%B5%E5%AE%88%E5%AD%98%E5%82%A8%E5%BC%95%E6%93%8E%E8%A7%84%E8%8C%83%EF%BC%8C%E5%88%99%E4%BC%9A%E5%8F%91%E7%94%9F%E8%AD%A6%E5%91%8A%EF%BC%9B
AUTO_INCREMENT
表的初始 AUTO_INCREMENT 值。在 MySQL 5.7 中,适用于 MyISAM,MEMORY,InnoDB 和 ARCHIVE 表。要为不支持 AUTO_INCREMENT 的引擎设置第一个自动增量值,请在创建表之后插入一个值小于所需值的“虚拟行“,然后删除”虚拟行“;
对于支持 CREATE TABLE 语句中的 AUTO_INCREMENT 表选项的引擎,还可以使用ALTER TABLE tbl_name AUTO_INCREMENT=N来重置 AUTO_INCREMENT 值。该值不能设置为低于列中当前的最大值;
AVG_ROW_LENGTH
表的平均行长的近似值。只有具有可变大小行的大表,才需要设置此值;
当创建 MyISAM 表时,MySQL 使用 MAX_ROWS 和 AVG_ROW_LENGTH 选项的结果来确定生成的表有多大。如果不指定任一选项,默认情况下,MyISAM 数据和索引文件的最大大小为 256TB(前提是操作系统支持)。如果要缩小指针大小以使索引更小更快,并且不需要大文件,则可以通过设置 myisam_data_pointer_size 系统变量来减小默认指针大小。(见“服务器系统变量”:https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html%EF%BC%89%E5%A6%82%E6%9E%9C%E5%B8%8C%E6%9C%9B%E6%89%80%E6%9C%89%E7%9A%84%E8%A1%A8%E9%83%BD%E8%83%BD%E5%A4%9F%E8%B6%85%E8%BF%87%E9%BB%98%E8%AE%A4%E9%99%90%E5%88%B6%EF%BC%8C%E5%B9%B6%E4%B8%94%E6%84%BF%E6%84%8F%E8%AE%A9%E8%A1%A8%E7%9A%84%E9%80%9F%E5%BA%A6%E7%A8%8D%E5%A4%A7%E4%BA%8E%E5%BF%85%E8%A6%81%E7%9A%84%EF%BC%8C%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E8%AE%BE%E7%BD%AE%E6%AD%A4%E5%8F%98%E9%87%8F%E6%9D%A5%E5%A2%9E%E5%8A%A0%E9%BB%98%E8%AE%A4%E7%9A%84%E6%8C%87%E9%92%88%E5%A4%A7%E5%B0%8F%E3%80%82%E5%B0%86%E5%80%BC%E8%AE%BE%E7%BD%AE%E4%B8%BA7%E5%8F%AF%E5%85%81%E8%AE%B8%E8%A1%A8%E6%A0%BC%E5%A4%A7%E5%B0%8F%E4%B8%BA65,536TB%EF%BC%9B
[DEFAULT] CHARACTER SET
指定表的默认字符集。CHARSET 是 CHARACTER SET 的同义词。如果字符集名称为 DEFAULT,则使用数据库字符集;
CHECKSUM
如果您希望 MySQL 维护所有行的实时校验和(即,随着表更改,MySQL 会自动更新的校验和),请将其设置为 1。这会导致表更新更慢一点,但也使得更容易找到损坏的表。CHECKSUM TABLE 语句报告校验和。(仅限 MyISAM)
[DEFAULT] COLLATE
指定表的默认排序规则;
COMMENT
表的注释,最长 2048 个字符。您可以使用 table_option COMMENT 子句为表设置 InnoDB MERGE_THRESHOLD 值。参见“配置索引页面的合并阈值”:https://dev.mysql.com/doc/refman/5.7/en/index-page-merge-threshold.html
设置 NDB_TABLE 选项。在 MySQL NDB Cluster 7.5.2+中,CREATE TABLE 或 ALTER TABLE 语句中的表注释也可用于指定 1 到 4 个 NDB_TABLE 选项 NOLOGGING,READ_BACKUP,PARTITION_BALANCE 或 FULLY_REPLICATED 作为一组 name-value 对,如果需要,用逗号分隔,紧跟着字符串 NDB_TABLE=开始引用的注释文本。如下:
c2 VARCHAR(100),
c3 VARCHAR(100) )
COMMENT=”NDB_TABLE=READ_BACKUP=0,PARTITION_BALANCE=FOR_RP_BY_NODE”;
引用的字符串中不允许使用空格。字符串不区分大小写;
注释显示为 SHOW CREATE TABLE 的输出的一部分。注释的文本也可以作为 MySQL Information Schema TABLES 表的 TABLE_COMMENT 列;
NDB 表的 ALTER TABLE 语句也支持此注释语法。请记住,与 ALTER TABLE 一起使用的表注释替换表可能具有的任何现有注释;
DB 表不支持在表注释中设置 MERGE_THRESHOLD 选项(它会被忽略);
有关完整的语法信息和示例,参见“在表注释中设置 NDB_TABLE 选项”:https://dev.mysql.com/doc/refman/5.7/en/create-table-ndb-table-comment-options.html
COMPRESSION
用于 InnoDB 表的页面级压缩的压缩算法。支持的值:Zlib,LZ4,None。COMPRESSION 属性和透明页面压缩功能一起被引入。页面压缩仅支持驻留在独立表文件表空间中的 InnoDB 表,并且仅在支持稀疏文件和 hole punching 的 Linux 和 Windows 平台上可用。有关更多信息,参见“InnoDB 页面压缩”:https://dev.mysql.com/doc/refman/5.7/en/innodb-page-compression.html
CONNECTION
FEDERATED 表的连接字符串。注意:旧版本的 MySQL 对连接字符串使用 COMMENT 选项;
DATA DIRECTORY, INDEX DIRECTORY
对于 InnoDB,DATA DIRECTORY =’directory’选项允许在 MySQL 数据目录之外创建 InnoDB独立表文件表空间。在指定的目录中,MySQL 会创建一个对应于数据库名称的子目录,并在其中保存表的.ibd 文件。必须启用 innodb_file_per_table 配置选项才能使用 InnoDB 的 DATA DIRECTORY 选项。必须指定完整的目录路径。参见第“在数据目录之外创建文件每表表空间”:https://dev.mysql.com/doc/refman/5.7/en/tablespace-placing.html
创建 MyISAM 表时,可以使用 DATA DIRECTORY=’directory’子句,INDEX DIRECTORY =’directory’子句或两者都使用。他们分别指定放置 MyISAM 表的数据文件和索引文件的位置。与 InnoDB 表不同,当创建具有 DATA DIRECTORY 或 INDEX DIRECTORY 选项的 MyISAM 表时,MySQL 不会创建与数据库名称对应的子目录。会在指定的目录中创建文件;
从 MySQL 5.7.17 开始,您必须具有 FILE 权限才能使用 DATA DIRECTORY 或 INDEX DIRECTORY 表选项;
注意:对于分区表,表级 DATA DIRECTORY 和 INDEX DIRECTORY 选项将被忽略。(bug#32091)
只有当不使用–skip-symbolic-links 选项时,这些选项才可用。操作系统也必须有一个工作,线程安全的 realpath()调用。有关更完整的信息,参见“在 Unix 上使用 MyISAM 表的符号链接”:https://dev.mysql.com/doc/refman/5.7/en/symbolic-links-to-tables.html
如果创建一个没有 DATA DIRECTORY 选项的 MyISAM 表,则在数据库目录中创建.MYD 文件。默认情况下,如果 MyISAM 在这种情况下找到一个现有的.MYD 文件,它将覆盖它。同样适用于使用无 INDEX DIRECTORY 选项创建的表的.MYI 文件。要抑制此行为,请使用–keep_files_on_create 选项启动服务器,在这种情况下,MyISAM 将不会覆盖现有文件,并返回错误;
如果使用 DATA DIRECTORY 或 INDEX DIRECTORY 选项创建了 MyISAM 表,并且找到了现有的.MYD 或.MYI 文件,MyISAM 将始终返回错误。它不会覆盖指定目录中的文件;
注意:与 DATA DIRECTORY 或 INDEX DIRECTORY 一起,不能使用包含 MySQL 数据目录的路径名。这包括分区表和单独的表分区。(bug#32167)
DELAY_KEY_WRITE
如果要延迟表的 key 更新到表关闭,请将其设置为 1。参见“服务器系统变量”中的 delay_key_write 系统变量的描述:https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html%E3%80%82%EF%BC%88%E4%BB%85%E9%99%90 MyISAM)
ENCRYPTION
将 ENCRYPTION 选项设置为“Y”,以便对独立表文件表空间中创建的 InnoDB 表启用页面级数据加密。选项值不区分大小写。ENCRYPTION 选项伴随 InnoDB 表空间加密功能被引入;参见“InnoDB 表空间加密”:https://dev.mysql.com/doc/refman/5.7/en/innodb-tablespace-encryption.html%E3%80%82%E5%BF%85%E9%A1%BB%E5%8A%A0%E8%BD%BD keyring_file 插件以使用 ENCRYPTION 选项;
INSERT_METHOD
如果要将数据插入到 MERGE 表中,则必须使用 INSERT_METHOD 指定要插被入行的表。INSERT_METHOD 仅适用于 MERGE 表。使用 FIRST 或 LAST 的值将插入到第一个或最后一个表,或者使用值 NO 来防止插入。参见“MERGE 存储引擎”:https://dev.mysql.com/doc/refman/5.7/en/merge-storage-engine.html
KEY_BLOCK_SIZE
对于 MyISAM 表,KEY_BLOCK_SIZE 可选地指定要用于索引 key 块的大小(以字节为单位)。该值被视为提示;如果需要,可以使用不同的尺寸。为单个索引定义指定的 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。有关详细信息,参见第“InnoDB 表压缩”:https://dev.mysql.com/doc/refman/5.7/en/innodb-table-compression.html
当为 InnoDB 表指定 KEY_BLOCK_SIZE 时,Oracle 建议启用 innodb_strict_mode。当启用 innodb_strict_mode 时,指定无效的 KEY_BLOCK_SIZE 值将返回错误。如果 innodb_strict_mode 被禁用,则无效的 KEY_BLOCK_SIZE 值会导致警告,并且将忽略 KEY_BLOCK_SIZE 选项;
InnoDB 仅支持表级别的 KEY_BLOCK_SIZE;
32k 和 64k 的 innodb_page_size 值不支持 KEY_BLOCK_SIZE。InnoDB 表压缩不支持这些页面大小;
MAX_ROWS
计划存储在表中的最大行数。这不是硬限制,而是对存储引擎的一个暗示,表格必须能够存储至少这么多行;
NDB 存储引擎将此值视为最大值。如果您打算创建非常大的 NDB Cluster 表(包含数百万行),则应使用此选项来确保 NDB 通过设置MAX_ROWS=2*rows来,在用于存储表主键的哈希值的散列表中分配足够数量的索引插槽,其中 rows 是希望插入到表中的行数;
MAX_ROWS 的最大值为 4294967295;较大的值将被截断到此限制;
MIN_ROWS
计划存储在表中的最小行数。MEMORY 存储引擎使用此选项作为关于内存使用的提示;
PACK_KEYS
仅对 MyISAM 表有影响。如果要缩小索引,请将此选项设置为 1。这通常会使更新速度更慢,读取速度更快。将选项设置为 0 将禁用所有 key 的打包。将其设置为 DEFAULT 告诉存储引擎只打包长 CHAR,VARCHAR,BINARY 或 VARBINARY 列;
如果不使用 PACK_KEYS,默认是打包字符串,而不是数字。如果您使用 PACK_KEYS = 1,数字也会打包;
当打包二进制数字键时,MySQL 使用前缀压缩:1). 每个键需要一个额外的字节来指示上一个键的多少字节对于下一个键是相同的。2). 指向行的指针在 key 之后直接以高字节优先顺序存储,以提高压缩
这意味着如果在两个连续的行上有很多相同的键,则所有以下“相同”键通常只需要两个字节(包括指向该行的指针)。将这个与普通的情况(紧跟着的 key 是 storage_size_for_key + pointer_size(指针大小通常为 4))进行比较。相反,只有有很多数字相同,才能从前缀压缩中获得较大的益处。如果所有 key 完全不同,则如果键不是可以具有 NULL 值的键,则每个键将使用一个字节。(在这种情况下,打包 key 长度存储在用于标记 key 是否为 NULL的相同字节中。)
PASSWORD
此选项未使用。如果您需要争夺您的.frm 文件,并使其无法使用任何其他 MySQL 服务器,请联系我们的销售部门;
ROW_FORMAT
定义存储行的物理格式;
执行 CREATE TABLE 语句时,如果指定了存储引擎不支持的ROW_FORMAT,则使用存储引擎的默认行格式来创建该表。SHOW TABLE STATUS 报告的信息是实际使用的行格式。这可能与 Create_options 列中的值不同,因为在创建过程中保留原始的 CREATE TABLE 定义;
行格式选项因表使用的存储引擎而异:
对于 InnoDB 表:
1). 默认行格式由 innodb_default_row_format 定义,其默认设置为 DYNAMIC。当未定义 ROW_FORMAT 选项或使用 ROW_FORMAT = DEFAULT 时,将使用默认行格式。如果未定义 ROW_FORMAT 选项,或者如果使用 ROW_FORMAT=DEFAULT,那么重建表的操作也会将表的行格式默认地更改为由 innodb_default_row_format 定义的默认值。有关详细信息,参见“为表指定行格式”:https://dev.mysql.com/doc/refman/5.7/en/innodb-row-format-specification.html
2). 为了更有效的 InnoDB 存储数据类型,特别是 BLOB 类型,请使用 DYNAMIC。有关与 DYNAMIC 行格式相关的要求,参见”动态和压缩行格式”:https://dev.mysql.com/doc/refman/5.7/en/innodb-row-format-dynamic.html
3). 要启用 InnoDB 表的压缩,请指定 ROW_FORMAT = COMPRESSED。有关与 COMPRESSED 行格式相关的要求,参见“InnoDB 表和页面压缩”:https://dev.mysql.com/doc/refman/5.7/en/innodb-compression.html
4). 仍然可以通过指定 REDUNDANT 行格式来请求旧版本的 MySQL 中使用的行格式;
5). 指定非默认 ROW_FORMAT 子句时,请考虑启用 innodb_strict_mode 配置选项;
6). 不支持 ROW_FORMAT = FIXED。如果在禁用 innodb_strict_mode 时指定了 ROW_FORMAT = FIXED,InnoDB 将发出警告,并假定 ROW_FORMAT = DYNAMIC。如果在启用 innodb_strict_mode 时指定了 ROW_FORMAT = FIXED,则默认情况下,InnoDB 返回错误;
7). 有关 InnoDB 行格式的其他信息,参见“InnoDB 行存储和行格式”:https://dev.mysql.com/doc/refman/5.7/en/innodb-row-format.html
对于 MyISAM 表:
对于静态或可变长度的行格式,选项值可以是 FIXED 或 DYNAMIC。myisampack 将类型设置为 COMPRESSED。参见“MyISAM 表存储格式”:https://dev.mysql.com/doc/refman/5.7/en/myisam-table-formats.html
对于 NDB 表,MySQL NDB Cluster 7.5.1 及更高版本中的默认 ROW_FORMAT 为 DYNAMIC。(以前,它是固定的。)
STATS_AUTO_RECALC
指定是否自动重新计算 InnoDB 表的持久统计信息。值 DEFAULT 导致表的持久统计信息设置由 innodb_stats_auto_recalc 配置选项确定。当表中的 10%的数据已更改时,值 1 会导致统计信息重新计算。值 0 可防止对此表进行自动重新计算;使用此设置,发出 ANALYZE TABLE 语句以便在对表进行实质性更改后重新计算统计信息。有关持久性统计特性的更多信息,参见“配置持久优化器统计参数”:https://dev.mysql.com/doc/refman/5.7/en/innodb-persistent-stats.html
STATS_PERSISTENT
指定是否启用 InnoDB 表的持久统计信息。值 DEFAULT 导致表的持久统计信息设置由 innodb_stats_persistent 配置选项确定。值 1 启用表的持久统计,而值 0 关闭此功能。通过 CREATE TABLE 或 ALTER TABLE 语句启用持久性统计信息之后,在将代表性数据加载到表中之后,发出 ANALYZE TABLE 语句来计算统计信息。有关持久性统计特性的更多信息,参见“配置持久优化器统计参数”:https://dev.mysql.com/doc/refman/5.7/en/innodb-persistent-stats.html
STATS_SAMPLE_PAGES
估计索引列的基数和其他统计信息的索引页数,例如由 ANALYZE TABLE 计算的索引页数。有关详细信息,参见“配置持久优化器统计参数”:https://dev.mysql.com/doc/refman/5.7/en/innodb-persistent-stats.html
UNION
用于访问相同的 MyISAM 表的集合作为一个。这仅适用于 MERGE 表。参见“MERGE 存储引擎”:https://dev.mysql.com/doc/refman/5.7/en/merge-storage-engine.html
您必须对映射到 MERGE 表的表具有 SELECT,UPDATE 和 DELETE 权限;
注意:以前所有使用的表必须和 MERGE 表本身在同一数据库中。此限制不再适用;
TABLESPACE
TABLESPACE 选项用于在 InnoDB 一般表空间中创建一个表;
使用 TABLESPACE 选项之前,必须存在指定的一般表空间。有关一般表空间的信息,参见“InnoDB 常规表空间”:https://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html
tablespace_name 是区分大小写的标识符。它可能被引用或不引用。不允许使用正斜杠字符(“/”)。以“innodb_”开头的名称保留供特殊用途使用;
TABLESPACE 选项可用于将 InnoDB 表分区或子分区分配给一般表空间,单独的独立表文件表空间或系统表空间。MySQL 5.7 中支持表分区和子分区的 TABLESPACE 选项。所有分区必须具有相同存储引擎;
表级指定的表空间将成为新分区和子分区的默认表空间。可以通过在 CREATE TABLE 或 ALTER TABLE 语句中的分区或子分区级别指定表空间来覆盖默认表空间。以下示例显示了在表级别和分区级别定义的表空间:
-> ENGINE=InnoDB TABLESPACE ts1
-> PARTITION P2 VALUES LESS THAN (4) TABLESPACE ts2,
-> PARTITION P3 VALUES LESS THAN (6) TABLESPACE ts3);
有关 TABLESPACE 选项和分区的更多信息,参见“InnoDB 常规表空间”:https://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html
要在系统表空间中创建表,请指定 innodb_system 作为表空间名称:
使用 TABLESPACE [=] innodb_system 选项,无论 innodb_file_per_table 设置如何,都可以将系统表空间中的任何未压缩行格式的表放置。例如,您可以使用 TABLESPACE [=] innodb_system 选项将具有 ROW_FORMAT=DYNAMIC 的表添加到系统表空间;
要在每个表中的表空间中创建一个表,请指定 innodb_file_per_table 作为表空间名称:
注意:如果启用 innodb_file_per_table,则不需要指定 TABLESPACE = innodb_file_per_table 来创建一个 InnoDB 文件 / 表表空间。当启用 innodb_file_per_table 时,默认情况下,在每个文件表表空间中创建 InnoDB 表;
DATA DIRECTORY 子句允许使用 CREATE TABLE … TABLESPACE = innodb_file_per_table,但不支持与 TABLESPACE 选项结合使用;
ALTER TABLE 和 ALTER TABLE … REORGANIZE PARTITION 语句支持 TABLESPACE 选项,可用于将表和分区从一个表空间分别移动到另一个表空间。有关更多信息,参见“InnoDB 常规表空间”:https://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html
STORAGE 表选项仅用于 NDB 表。STORAGE 确定使用的存储器类型(磁盘或内存),并且可以是 DISK,MEMORY 或 DEFAULT 之一;
TABLESPACE … STORAGE DISK 将表分配给 NDB Cluster Disk Data 表空间。表空间必须已经使用 CREATE TABLESPACE 创建。有关详细信息,参见“NDB 群集磁盘数据表”:https://dev.mysql.com/doc/refman/5.7/en/mysql-cluster-disk-data.html
注意:无法在没有 TABLESPACE 子句的 CREATE TABLE 语句中使用 STORAGE 子句;
创建分区表
partition_options
可用于控制使用 CREATE TABLE 创建的表的分区;
并非在本节开头的 partition_options 语法中显示的所有选项都可用于所有分区类型。请参阅以下各种类型的列表,了解每种类型的特定信息,有关 MySQL 中分区的使用和使用的更完整信息,参见文档“分区”:https://dev.mysql.com/doc/refman/5.7/en/partitioning.html%EF%BC%8C%E4%BB%A5%E5%8F%8A%E6%9C%89%E5%85%B3%E8%A1%A8%E5%88%9B%E5%BB%BA%E5%92%8C%E5%85%B6%E4%BB%96%E7%9B%B8%E5%85%B3%E9%99%88%E8%BF%B0%E7%9A%84%E5%85%B6%E4%BB%96%E7%A4%BA%E4%BE%8B%E5%88%B0 MySQL 分区;
可以将分区修改,合并,添加到表中,并从表中删除。有关完成这些任务的 MySQL 语句的基本信息,参见“ALTER TABLE 语法”:https://dev.mysql.com/doc/refman/5.7/en/alter-table.html%E3%80%82%E6%9C%89%E5%85%B3%E6%9B%B4%E8%AF%A6%E7%BB%86%E7%9A%84%E8%AF%B4%E6%98%8E%E5%92%8C%E7%A4%BA%E4%BE%8B%EF%BC%8C%E5%8F%82%E8%A7%81%E2%80%9C%E5%88%86%E5%8C%BA%E7%AE%A1%E7%90%86%E2%80%9D%EF%BC%9Ahttps://dev.mysql.com/doc/refman/5.7/en/partitioning-management.html
PARTITION BY
如果使用,partition_options 子句以 PARTITION BY 开头。此子句包含用于确定分区的函数;该函数返回从 1 到 num 的整数值,其中 num 是分区数。(表中可能包含的用户定义分区的最大数量为 1024;此部分稍后讨论的子分区的数量包含在此最大值中。)
在 PARTITION BY 子句中使用的表达式(expr)不能引用正在创建的表中的任何列;这样的引用是特别不允许的,并导致语句失败并出现错误。(bug#29444)
HASH(expr)
哈希一列或多列以创建放置和定位行的键。expr 是使用一个或多个表列的表达式。这可以是产生单个整数值的任何有效的 MySQL 表达式(包括 MySQL 函数)。例如,这些都是使用 PARTITION BY HASH 的有效的 CREATE TABLE 语句:
您不得使用 PARTITION BY HASH 中的 VALUES LESS THAN 或 VALUES IN 子句;
PARTITION BY HASH 使用 expr 的余数除以分区数(即模数)。有关示例和其他信息,参见 HASH 分区”:https://dev.mysql.com/doc/refman/5.7/en/partitioning-hash.html
LINEAR 关键字需要一些不同的算法。在这种情况下,作为一个或多个逻辑 AND 运算的结果计算存储行的分区的编号。有关线性散列的讨论和示例,参见“线性哈希分区”:https://dev.mysql.com/doc/refman/5.7/en/partitioning-linear-hash.html
KEY(column_list)
这与 HASH 类似,除了 MySQL 提供散列函数,以保证均匀的数据分发。column_list 参数只是一个或多个表列的列表(最多 16 个)。此示例显示了一个由键分隔的简单表,具有 4 个分区:
PARTITIONS 4;
对于按键进行分区的表,可以使用 LINEAR 关键字进行线性分割。这与与 HASH 分区的表具有相同的效果。也就是说,使用&操作符而不是模数找到分区号,有关详细信息,参见“线性哈希分区”和“关键分区”:
https://dev.mysql.com/doc/refman/5.7/en/partitioning-linear-hash.html
https://dev.mysql.com/doc/refman/5.7/en/partitioning-key.html
此示例使用键的线性分区在 5 个分区之间分配数据:
PARTITIONS 5;
使用 MySQL 5.7.1 开始的
[SUB]PARTITION BY [LINEAR] KEY支持
ALGORITHM = {1|2}选项。ALGORITHM=1 导致服务器使用与 MySQL 5.1 相同的键哈希功能; ALGORITHM=2 意味着服务器使用 MySQL 5.5 及更高版本中新的 KEY 分区表默认实现和使用的密钥哈希功能。(使用 MySQL 5.5 及更高版本中使用的键哈希函数创建的分区表不能由 MySQL 5.1 服务器使用。)未指定该选项与使用 ALGORITHM = 2 具有相同的效果。此选项主要用于在 MySQL 5.1 和更高版本的 MySQL 版本之间升级或降级[LINEAR] KEY 分区表时使用,或者在 MySQL 5.5 或更高版本的服务器上创建可以在 MySQL 5.1 上使用的 KEY 或 LINEAR KEY 分区的表服务器。有关详细信息,请参见第 14.1.8.1 节“ALTER TABLE 分区操作”;
MySQL 5.7(及更高版本)中的 mysqldump 将此选项写入版本化注释中,如下所示:
/*!50100 PARTITION BY KEY */ /*!50611 ALGORITHM = 1 */ /*!50100 ()
这导致 MySQL 5.6.10 和更早版本的服务器忽略该选项,否则会导致这些版本中的语法错误。如果您打算加载在 MySQL 5.7 服务器上进行的转储,您将使用由 KEY 分区或分区的表转移到 5.6.11 之前的 MySQL 5.6 服务器中,请务必先查看影响升级到 MySQL 5.6 的更改,然后再继续。(如果您将从 MySQL 5.7 实际 5.6.11 或更高版本的服务器生成的 KEY 分区表或子分区表加载到 MySQL 5.5.30 或更早版本的服务器中,那么也会发现这些信息。)
同样在 MySQL 5.6.11 及更高版本中,在 SHOW CREATE TABLE 的输出中必要时显示 ALGORITHM = 1,使用与 mysqldump 相同的版本注释。即使在创建原始表时指定了此选项,SHOW CREATE TABLE 输出也总是忽略 ALGORITHM = 2;
不得使用具有 PARTITION BY KEY 的 VALUES LESS THAN 或 VALUES IN 子句;
RANGE(expr)
在这种情况下,expr 使用一组值不超过运算符来显示一系列值。使用范围分区时,必须使用 VALUES LESS THAN 至少定义一个分区。您不能使用 VALUES IN 进行范围分区;
注意:对于由 RANGE 分区的表,VALUES LESS THAN 必须与整数文字值或计算为单个整数值的表达式一起使用。在 MySQL 5.7 中,您可以在使用 PARTITION BY RANGE COLUMNS 定义的表中克服此限制,如本节后面所述;
假设您有一个表,您希望在包含年度值的列上分区,根据以下方案:
1 1991 to 1994
2 1995 to 1998
3 1999 to 2002
4 2003 to 2005
5 2006 and later
实现这种分区方案的表可以通过下面的 CREATE TABLE 语句来实现:
some_data INT
PARTITION BY RANGE (year_col) (
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 子句按类似于 switch … case 块的情况部分的顺序工作(如 C,Java 和 PHP 等许多编程语言中所发现的)。也就是说,这些条款必须以每个连续值不超过上限值的上限大于上一个值的方式进行排列,其中一个参考 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 子句中的值导致语句失败,并且在使用分区列列表时出现错误不一致。您不能对任何出现的值使用 NULL 价值不及。对于除第一个之外的给定列,可以多次使用 MAXVALUE,如此示例所示:
b INT NOT NULL
PARTITION BY RANGE COLUMNS(a,b) (
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’);
有关更多信息,请参见“范围分区”和“分区修剪”:
https://dev.mysql.com/doc/refman/5.7/en/partitioning-range.html
https://dev.mysql.com/doc/refman/5.7/en/partitioning-pruning.html
LIST(expr)
当基于具有限制的可能值集合的表列(如状态或国家 / 地区代码)分配分区时,这是非常有用的。在这种情况下,与特定状态或国家相关的所有行都可以分配给单个分区,也可以为特定状态集或国家保留分区。它类似于 RANGE,除了只有 VALUES IN 可用于指定每个分区的允许值;
VALUES IN 与要匹配的值列表一起使用。例如,您可以创建一个分区方案,如下所示:
name VARCHAR(35)
PARTITION BY LIST (id) (
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 至少定义一个分区。您不能按分类列表使用不超过值;
注意:对于由 LIST 分区的表,与 VALUES IN 一起使用的值列表只能由整数值组成。在 MySQL 5.7 中,您可以使用 LIST COLUMNS 分区来克服这个限制,这将在本节稍后介绍;
LIST COLUMNS(column_list)
LIST 上的此变体有助于使用多列比较条件(即,具有条件如 WHERE 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 一起使用。当与 PARTITION BY LIST COLUMNS 一起使用时,VALUES IN 子句中的每个元素必须是一组列值;每个集合中的值的数量必须与 COLUMNS 子句中使用的列数相同,并且这些值的数据类型必须与列的数据类型匹配(并以相同的顺序进行)。在最简单的情况下,该集合由单个列组成。在 column_list 和组成 value_list 的元素中可以使用的最大列数为 16;
由以下 CREATE TABLE 语句定义的表提供了使用 LIST COLUMNS 分区的表的示例:
b INT NULL
PARTITION BY LIST COLUMNS(a,b) (
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 子句声明的任何分区的总数;
注意:在创建由 RANGE 或 LIST 分区的表时是否使用 PARTITIONS 子句,您仍必须在表定义中至少包含一个 PARTITION VALUES 子句(见下文);
SUBPARTITION BY
分区可以可选地被划分成多个子分区。可以使用可选的 SUBPARTITION BY 子句来指示。子分区可以通过 HASH 或 KEY 来完成。这些都可以是 LINEAR。这些工作方式与前面对于等效分区类型的描述相同。(不可能通过 LIST 或 RANGE 进行子分区。)
可以使用 SUBPARTITIONS 关键字后跟一个整数值来指示子分区的数量;
对“PARTITIONS”或“SUBPARTITIONS”子句中使用的值进行严格检查,此值必须遵守以下规则:
- 该值必须为正,非零整数;
- 不允许使用前导零;
- 该值必须是一个整数文字,不能是一个表达式。例如,即使 0.2E + 01 评估为 2,也不允许使用分区 0.2E + 01(bug#15890)
partition_definition
每个分区可以使用 partition_definition 子句单独定义。组成本条的各部分如下:
PARTITION partition_name
指定分区的逻辑名称;
VALUES
对于范围分区,每个分区必须包含一个 VALUES LESS THAN 子句;对于列表分区,必须为每个分区指定 VALUES IN 子句。这用于确定在该分区中存储哪些行。有关语法示例,参阅“分区”中的“分区类型”的讨论:https://dev.mysql.com/doc/refman/5.7/en/partitioning.html
[STORAGE] ENGINE
分区处理程序接受 PARTITION 和 SUBPARTITION 的[STORAGE] ENGINE 选项。目前,可以使用的唯一方法是将所有分区或所有子分区设置为相同的存储引擎,并尝试为同一表中的分区或子分区设置不同的存储引擎将导致错误 ERROR 1469(HY000):此版本的 MySQL 不允许在分区中处理程序的混合。我们期望在未来的 MySQL 版本中解除对分区的限制;
可选的 COMMENT 子句可用于指定描述该分区的字符串。例:
分区注释的最大长度为 1024 个字符;
DATA DIRECTORY and INDEX DIRECTORY
DATA DIRECTORY 和 INDEX DIRECTORY 可用于指示将分别存储该分区的数据和索引的目录。data_dir 和 index_dir 都必须是绝对的系统路径名;
从 MySQL 5.7.17 开始,您必须具有 FILE 权限才能使用 DATA DIRECTORY 或 INDEX DIRECTORY 分区选项;
例如:
PARTITION BY LIST(YEAR(adate))
(
PARTITION p1999 VALUES IN (1995, 1999, 2003)
INDEX DIRECTORY = ‘/var/appdata/95/idx’,
INDEX DIRECTORY = ‘/var/appdata/96/idx’,
INDEX DIRECTORY = ‘/var/appdata/97/idx’,
INDEX DIRECTORY = ‘/var/appdata/98/idx’
DATA DIRECTORY 和 INDEX DIRECTORY 的行为方式与在 MyISAM 表中使用的 CREATE TABLE 语句的 table_option 子句相同;
可以为每个分区指定一个数据目录和一个索引目录。如果未指定,数据和索引将默认存储在表的数据库目录中;
在 Windows 上,MyISAM 表的各个分区或子分区不支持 DATA DIRECTORY 和 INDEX DIRECTORY 选项,INDo DIRECTORY 选项不适用于各个分区或 InnoDB 表的子部分。这些选项在 Windows 中被忽略,但生成警告除外。(bug#30459)
注意:如果 NO_DIR_IN_CREATE 有效,则创建分区表将忽略 DATA DIRECTORY 和 INDEX DIRECTORY 选项。(bug#24633)
MAX_ROWS and MIN_ROWS
可以分别指定要存储在分区中的最大和最小行数。max_number_of_rows 和 min_number_of_rows 的值必须为正整数。与具有相同名称的表级别选项一样,它们仅作为服务器的“建议”,并不是硬限制;
TABLESPACE
可用于将 InnoDB 表分区或子分区分配给一般表空间,单独的每表表空间或系统表空间。MySQL 5.7 中添加了表分区和子分区的 TABLESPACE 选项支持,参见“InnoDB 常规表空间”:https://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html%E3%80%82%E5%AE%83%E4%B9%9F%E5%BE%97%E5%88%B0 NDB 集群的支持。所有分区必须属于同一存储引擎;
subpartition_definition
分区定义可以可选地包含一个或多个子分区定义子句。它们中的每一个至少包含 SUBPARTITION 名称,其中 name 是子分区的标识符。除了使用 SUBPARTITION 替换 PARTITION 关键字,子分区定义的语法与分区定义的语法相同;
子分区必须由 HASH 或 KEY 完成,只能在 RANGE 或 LIST 分区上完成。参见第 21.2.6 节“分组”;
生成列分区
允许通过生成列进行分区。例如:
s1 INT,
s2 INT AS (EXP(s1)) STORED
)
PARTITION BY LIST (s2) (
PARTITION p1 VALUES IN (1)
);
分区将生成的列视为常规列,这对于不允许进行分区的功能的限制实现了解决方法(参见第 21.6.3 节“与功能分区限制”)。前面的例子演示了这种技术:EXP()不能直接在 PARTITION BY 子句中使用,但允许使用 EXP()定义的生成列;
清空表 and 截断表
https://blog.csdn.net/scheme2008/article/details/84654442
清空表:delete from users;
截断表:truncate table users;
重命名 | RENAME TABLE Syntax
文档:https://dev.mysql.com/doc/refman/5.7/en/rename-user.html
主题:MySQL 中的 RENAME 语法。
The RENAME USER statement renames existing MySQL accounts. An error occurs for old accounts that do not exist or new accounts that already exist.
To use RENAME USER, you must have the global CREATE USER privilege, or the UPDATE privilege for the mysql database. When the read_only system variable is enabled, RENAME USER additionally requires the SUPER privilege.
Each account name uses the format described in Section 7.2.3, “Specifying Account Names”. For example:
RENAME USER ‘jeffrey’@’localhost’ TO ‘jeff’@’127.0.0.1’;
The host name part of the account name, if omitted, defaults to ‘%’.
RENAME USER causes the privileges held by the old user to be those held by the new user. However, RENAME USER does not automatically drop or invalidate databases or objects within them that the old user created. This includes stored programs or views for which the DEFINER attribute names the old user. Attempts to access such objects may produce an error if they execute in definer security context. (For information about security context, see Section 22.6, “Access Control for Stored Programs and Views”.)
The privilege changes take effect as indicated in Section 7.2.6, “When Privilege Changes Take Effect”.