目录
ALTER DATABASE语句
ALTER EVENT语句
ALTER FUNCTION 语法
ALTER INSTANCE语句
ALTER LOGFILE GROUP 语法
ALTER PROCEDURE语句
ALTER SERVER 语法
ALTER TABLE 语法
ALTER TABLESPACE语句
ALTER VIEW 语法
CREATE DATABASE 语法
CREATE EVENT 语法
CREATE INDEX语句
字段前缀键部分
CREATE LOGFILE GROUP 语法
CREATE PROCEDURE 和 CREATE FUNCTION 语法
CREATE SERVER语句
CREATE TABLE 语法
CREATE TABLE语句保留
通过CREATE TABLE创建的文件
CREATE TEMPORARY TABLE 语法
CREATE TABLE ... LIKE 语法
CREATE TABLE ... SELECT 语法
使用 FOREIGN KEY 约束
二级索引和生成的列
设置NDB_TABLE选项
CREATE TABLESPACE语句
CREATE TRIGGER 语法
CREATE VIEW 语法
DROP DATABASE 语法
DROP EVENT语句
DROP FUNCTION 语法
DROP INDEX 语法
DROP LOGFILE GROUP 语法
DROP PROCEDURE 和 DROP FUNCTION 语法
DROP SERVER 语法
DROP TABLE 语法
DROP TABLESPACE 语法
DROP TRIGGER 语法
DROP VIEW 语法
RENAME TABLE 语法
TRUNCATE TABLE 语法
ALTER {DATABASE | SCHEMA} [db_name]
alter_specification ...
ALTER {DATABASE | SCHEMA} db_name
UPGRADE DATA DIRECTORY NAME
alter_specification:
[DEFAULT] CHARACTER SET [=] charset_name
| [DEFAULT] COLLATE [=] collation_name
ALTER DATABASE可以更改数据库的整体特征。这些特性存储在数据库目录的db.opt
文件中。要使用ALTER DATABASE
,您需要数据库的 ALTER
特权。 ALTER SCHEMA是ALTER DATABASE的同义词。
可以从第一种语法中省略数据库名称,在这种情况下,该语句适用于默认数据库。
国家语言特征
CHARACTER SET
子句更改默认数据库字符集。COLLATE
子句更改默认数据库排序规则。
您可以分别使用SHOW CHARACTER SET
和SHOW COLLATION
语句查看可用的字符集和排序规则。
如果更改数据库的默认字符集或排序规则,则必须删除并重新创建使用数据库默认值的存储例程,以便它们使用新的默认值。
(在存储的例程中,如果未明确指定字符集或排序规则,则具有字符数据类型的变量将使用数据库默认值。请参见第13.1.16节“ CREATE PROCEDURE和CREATE FUNCTION语句”。)
ALTER
[DEFINER = user]
EVENT event_name
[ON SCHEDULE schedule]
[ON COMPLETION [NOT] PRESERVE]
[RENAME TO new_event_name]
[ENABLE | DISABLE | DISABLE ON SLAVE]
[COMMENT 'string']
[DO event_body]
ALTER EVENT
语句可以更改现有事件的一个或多个特征,而无需删除并重新创建它。当使用 CREATE EVENT时,
此语法适用于每个 DEFINER
, ON SCHEDULE
, ON COMPLETION
, COMMENT
, ENABLE
/ DISABLE
, and DO的子句
任何用户都可以更改在该用户具有EVENT
特权的数据库上定义的 event。当用户成功执行ALTER EVENT
语句时,该用户将成为受影响事件的定义者。
ALTER EVENT
仅适用于现有事件:
mysql> ALTER EVENT no_such_event
> ON SCHEDULE
> EVERY '2:3' DAY_HOUR;
ERROR 1517 (HY000): Unknown event 'no_such_event'
在以下每个示例中,假设名为myevent
的 event 定义如下所示:
CREATE EVENT myevent
ON SCHEDULE
EVERY 6 HOUR
COMMENT 'A sample comment.'
DO
UPDATE myschema.mytable SET mycol = mycol + 1;
以下语句将myevent
的计划从立即开始后每六小时更改为每十二小时一次,从语句开始运行后四小时开始:
ALTER EVENT myevent
ON SCHEDULE
EVERY 12 HOUR
STARTS CURRENT_TIMESTAMP + INTERVAL 4 HOUR;
可以在单个语句中更改 event 的多个特征。本示例将myevent
执行的 SQL 语句更改为删除mytable
所有记录的 SQL 语句;它还会更改 event 的计划,使其在ALTER EVENT语句运行一天后执行。
ALTER EVENT myevent
ON SCHEDULE
AT CURRENT_TIMESTAMP + INTERVAL 1 DAY
DO
TRUNCATE TABLE myschema.mytable;
ALTER EVENT语句仅更改指定的特征,其他值将不做改变,这包括 CREATE EVENT
创建的任何默认值,比如 ENABLE。
要禁用myevent
,请使用此ALTER EVENT语句:
ALTER EVENT myevent
DISABLE;
ON SCHEDULE
子句可以使用涉及 MySQL built-in 函数和用户变量的表达式来获取它包含的任何timestamp
或interval
值。
您不能在此类表达式中使用存储的例程或 user-defined 函数,也不能使用任何 table references;但是,你可以使用SELECT FROM DUAL
。这对于ALTER EVENT和 CREATE EVENT
语句 都是如此。 在这种情况下,对存储例程,user-defined 函数和表的引用是特别不允许的,并且会因错误而失败(参见 Bug#22830)。
虽然在do子句中包含另一个ALTER EVENT语句似乎成功,但是当服务器尝试执行生成的调度 event 时,执行失败并显示错误。
要重命名 event,请使用ALTER EVENT语句的RENAME TO
子句。此语句将 event myevent
重命名为yourevent
:
ALTER EVENT myevent
RENAME TO yourevent;
您还可以使用ALTER EVENT ... RENAME TO ...
和
标记将事件移动到其他数据库 ,如下所示:db_name.event_name
ALTER EVENT olddb.myevent
RENAME TO newdb.myevent;
要执行前一个语句,执行它的用户必须对olddb
和newdb
数据库都具有EVENT
特权。
注意没有
RENAME EVENT语句
。
DISABLE ON SLAVE被用来复制从站而不是ENABLE
或DISABLE,
以指示在 master 上创建并复制到从站的 event,但不会在从站上执行。通常,DISABLE ON SLAVE
会根据需要自动设定;但是,在某些情况下,您可能需要或需要手动更改它。See Section 16.4.1.16, “Replication of Invoked Features”, for more information.
ALTER FUNCTION func_name [characteristic ...]
characteristic:
COMMENT 'string'
| LANGUAGE SQL
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
该语句可用于更改存储函数的特征。ALTER FUNCTION
语句中可以指定多个更改 。但是,您不能使用此语句更改参数或存储函数的主体。要进行此类更改,必须使用DROP FUNCTION
和CREATE FUNCTION
删除并重新创建该函数。
您必须具有ALTER ROUTINE
该功能的特权。(该特权会自动授予函数创建者。)如果启用了二进制日志记录,则该ALTER FUNCTION
语句可能也需要 SUPER
特权,如 第23.7节“存储的程序二进制日志记录”中所述。
ALTER INSTANCE ROTATE INNODB MASTER KEY
ALTER INSTANCE
MySQL 5.7.11中引入的定义了适用于MySQL服务器实例的操作。
该ALTER INSTANCE ROTATE INNODB MASTER KEY
语句可以轮换主加密密钥用于InnoDB
表空间加密 。必须安装并配置密钥环插件才能使用此语句。有关密钥环插件的信息,请参见第6.4.4节“ MySQL密钥环”。密钥轮换需要SUPER
特权。
ALTER INSTANCE ROTATE INNODB MASTER KEY
支持并发 DML。它不能与CREATE TABLE ... ENCRYPTION
或 并发ALTER TABLE ... ENCRYPTION
同时运行,并且会采取锁定来防止因并发执行这些语句而引起的冲突。如果其中一个冲突的语句是 running,则必须先完成,然后才能继续。
ALTER INSTANCE
操作将写入二进制 log,以便可以在复制的服务器上执行。
ALTER LOGFILE GROUP logfile_group
ADD UNDOFILE 'file_name'
[INITIAL_SIZE [=] size]
[WAIT]
ENGINE [=] engine_name
此语句将名为“file_name
”的UNDO
文件添加到现有 log 文件 group logfile_group
。 ALTER LOGFILE GROUP语句只有一个ADD UNDOFILE
子句。目前不支持DROP UNDOFILE
子句。
注意所有NDB群集磁盘数据对象共享相同的名称空间。这意味着每个磁盘数据对象必须唯一地命名(而不仅仅是给定类型的每个磁盘数据对象)。例如,您不能具有相同名称的表空间和撤消日志文件,或具有相同名称的撤消日志文件和数据文件。
可选的参数INITIAL_SIZE
设置UNDO
文件的初始大小(以字节为单位);如果未指定,则初始大小默认为 134217728(128 MB)。您可以选择后面size
跟一个字母缩写,代表一个数量级,类似于中使用的缩写my.cnf
。通常,这是字母M
(兆字节)或G
(千兆字节)之一。 (Bug#13116514,Bug#16104705,Bug#62858)
INITIAL_SIZE
的最小允许值为 1048576(1 MB)。 (Bug#29574)
注意
WAIT
被解析,但被忽略。此关键字当前无效,并且打算将来扩展。
ENGINE
参数(必需)确定此 log 文件 group 使用的存储引擎,engine_name
是存储引擎的 name。目前,engine_name
唯一可接受的值是 “ NDBCLUSTER
”和 “ NDB
”。这两个值是等价的。
示例,假定已使用创建 CREATE LOGFILE GROUP
日志文件组lg_3:
ALTER LOGFILE GROUP lg_3
ADD UNDOFILE 'undo_10.dat'
INITIAL_SIZE=32M
ENGINE=NDBCLUSTER;
当ALTER LOGFILE GROUP与ENGINE = NDBCLUSTER
(或者ENGINE = NDB
)一起使用时,会在每个 NDB Cluster 数据节点上创建UNDO
log 文件。您可以通过查询INFORMATIONSCHEMA.FILES table 验证是否已创建UNDO
files 并获取有关它们的信息。例如:
mysql> SELECT FILE_NAME, LOGFILE_GROUP_NUMBER, EXTRA
-> FROM INFORMATION_SCHEMA.FILES
-> WHERE LOGFILE_GROUP_NAME = 'lg_3';
+-------------+----------------------+----------------+
| FILE_NAME | LOGFILE_GROUP_NUMBER | EXTRA |
+-------------+----------------------+----------------+
| newdata.dat | 0 | CLUSTER_NODE=3 |
| newdata.dat | 0 | CLUSTER_NODE=4 |
| undo_10.dat | 11 | CLUSTER_NODE=3 |
| undo_10.dat | 11 | CLUSTER_NODE=4 |
+-------------+----------------------+----------------+
4 rows in set (0.01 sec)
用于UNDO_BUFFER_SIZE
的内存来自全局池,该全局池的大小由SharedGlobalMemory
数据节点配置参数的值确定 。这包括设置InitialLogFileGroup
数据节点配置参数对此选项隐含的任何默认值 。
ALTER PROCEDURE proc_name [characteristic ...]
characteristic:
COMMENT 'string'
| LANGUAGE SQL
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
此语句可用于更改存储过程的特征。可以在ALTER PROCEDURE
语句中指定多个更改。但是,您无法使用此语句更改存储过程的参数或主体;要进行此类更改,必须使用DROP PROCEDURE
和CREATE PROCEDURE
删除并重新创建该过程。
您必须具有该过程的ALTER ROUTINE
特权。默认情况下,该权限自动授予过程创建者。可以通过禁用automatic_sp_privileges系统变量来更改此行为。见第 23.2.2 节,“存储例程和 MySQL 权限”。
ALTER SERVER server_name
OPTIONS (option [, option] ...)
更改server_name
的服务器信息,调整CREATE SERVER
语句中允许的任何选项。mysql.servers
表中的相应字段将相应更新。此语句需要 SUPER
特权。
例如,更新USER
选项:
ALTER SERVER s OPTIONS (USER 'sally');
ALTER SERVER
导致隐式提交。请参见 第13.3.3节“导致隐式提交的声明”。
ALTER SERVER
不管使用哪种日志记录格式,都不会将其写入二进制日志。
ALTER TABLE tbl_name
[alter_specification [, alter_specification] ...]
[partition_options]
alter_specification:
table_options
| ADD [COLUMN] col_name column_definition
[FIRST | AFTER col_name]
| ADD [COLUMN] (col_name column_definition,...)
| ADD {INDEX|KEY} [index_name]
[index_type] (key_part,...) [index_option] ...
| ADD {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name]
(key_part,...) [index_option] ...
| ADD [CONSTRAINT [symbol]] PRIMARY KEY
[index_type] (key_part,...)
[index_option] ...
| ADD [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY]
[index_name] [index_type] (key_part,...)
[index_option] ...
| ADD [CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (col_name,...)
reference_definition
| ADD CHECK (expr)
| ALGORITHM [=] {DEFAULT|INPLACE|COPY}
| ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
| CHANGE [COLUMN] old_col_name new_col_name column_definition
[FIRST|AFTER col_name]
| [DEFAULT] CHARACTER SET [=] charset_name [COLLATE [=] collation_name]
| CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
| {DISABLE|ENABLE} KEYS
| {DISCARD|IMPORT} TABLESPACE
| DROP [COLUMN] col_name
| DROP {INDEX|KEY} index_name
| DROP PRIMARY KEY
| DROP FOREIGN KEY fk_symbol
| FORCE
| LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}
| MODIFY [COLUMN] col_name column_definition
[FIRST | AFTER col_name]
| ORDER BY col_name [, col_name] ...
| RENAME {INDEX|KEY} old_index_name TO new_index_name
| RENAME [TO|AS] new_tbl_name
| {WITHOUT|WITH} VALIDATION
partition_options:
partition_option [partition_option] ...
partition_option:
ADD PARTITION (partition_definition)
| DROP PARTITION partition_names
| DISCARD PARTITION {partition_names | ALL} TABLESPACE
| IMPORT PARTITION {partition_names | ALL} TABLESPACE
| TRUNCATE PARTITION {partition_names | ALL}
| COALESCE PARTITION number
| REORGANIZE PARTITION partition_names INTO (partition_definitions)
| EXCHANGE PARTITION partition_name WITH TABLE tbl_name [{WITH|WITHOUT} VALIDATION]
| ANALYZE PARTITION {partition_names | ALL}
| CHECK PARTITION {partition_names | ALL}
| OPTIMIZE PARTITION {partition_names | ALL}
| REBUILD PARTITION {partition_names | ALL}
| REPAIR PARTITION {partition_names | ALL}
| REMOVE PARTITIONING
| UPGRADE PARTITIONING
key_part:
col_name [(length)] [ASC | DESC]
index_type:
USING {BTREE | HASH}
index_option:
KEY_BLOCK_SIZE [=] value
| index_type
| WITH PARSER parser_name
| COMMENT 'string'
table_options:
table_option [[,] table_option] ...
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]...)
partition_options:
(see CREATE TABLE options)
太多,单独叙述。
ALTER TABLESPACE tablespace_name
{ADD|DROP} DATAFILE 'file_name'
[INITIAL_SIZE [=] size]
[WAIT]
ENGINE [=] engine_name
此语句用于添加新数据文件或从表空间中删除数据文件。
ADD DATAFILE
variant 允许您使用INITIAL_SIZE
子句指定初始大小,其中size
以字节为单位;默认 value 是 134217728(128 MB)。您可以选择使用带有 one-letter 缩写的size
作为_数量级,类似于my.cnf
中使用的那些。通常,这是字母M
(兆字节)或G
(千兆字节)之一。
注意所有NDB群集磁盘数据对象共享相同的名称空间。这意味着每个磁盘数据对象必须唯一地命名(而不仅仅是给定类型的每个磁盘数据对象)。例如,您不能具有相同名称的表空间和数据文件,或具有相同名称的撤消日志文件和表空间。
CREATE TABLESPACE,INITIAL_SIZE要
明确指出。
创建数据文件后,其大小无法更改;但是,您可以使用ALTER TABLESPACE ... ADD DATAFILE
语句向表空间添加更多数据 files。
将DROP DATAFILE
与ALTER TABLESPACE一起使用会从表空间中删除数据文件“file_name
”。您不能从正在使用表的表空间中删除数据文件;换句话说,数据文件必须为空(不使用扩展数据块)。见Section 21.5.13.1,“NDB Cluster Disk Data Objects”。此外,要删除的任何数据文件必须先前已使用 CREATE TABLESPACE
或ALTER TABLESPACE添加到表空间。
ALTER TABLESPACE ... ADD DATAFILE
和ALTER TABLESPACE ... DROP DATAFILE
都需要ENGINE
子句,该子句指定表空间使用的存储引擎。目前,engine_name
唯一可接受的值是 NDB
和NDBCLUSTER。
WAIT
被解析但被忽略,因此在 MySQL 5.7 中没有效果。它旨在用于未来的扩展。
当ALTER TABLESPACE ... ADD DATAFILE
与ENGINE = NDB
一起使用时,会在每个 Cluster 数据节点上创建一个数据文件。您可以通过查询INFORMATIONSCHEMA.FILES table 验证是否已创建数据 files 并获取有关它们的信息。例如,以下查询显示属于newts
的表空间的所有数据文件:
mysql> SELECT LOGFILE_GROUP_NAME, FILE_NAME, EXTRA
-> FROM INFORMATION_SCHEMA.FILES
-> WHERE TABLESPACE_NAME = 'newts' AND FILE_TYPE = 'DATAFILE';
+--------------------+--------------+----------------+
| LOGFILE_GROUP_NAME | FILE_NAME | EXTRA |
+--------------------+--------------+----------------+
| lg_3 | newdata.dat | CLUSTER_NODE=3 |
| lg_3 | newdata.dat | CLUSTER_NODE=4 |
| lg_3 | newdata2.dat | CLUSTER_NODE=3 |
| lg_3 | newdata2.dat | CLUSTER_NODE=4 |
+--------------------+--------------+----------------+
2 rows in set (0.03 sec)
见第 24.9 节,“INFORMATIONSCHEMA FILES Table”。
ALTER TABLESPACE仅对 NDB Cluster 的磁盘数据存储有用。见第 21.5.13 节,“NDB Cluster 磁盘数据表”。
ALTER
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = user]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
此语句更改必须存在的视图的定义。语法类似于用于CREATE VIEW。
该语句需要该视图的CREATE VIEW
和 DROP
特权,以及该SELECT
语句中引用的每个列的某些特权 。 ALTER VIEW
仅允许定义者或具有SUPER
特权的用户使用。
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
[create_specification] ...
create_specification:
[DEFAULT] CHARACTER SET [=] charset_name
| [DEFAULT] COLLATE [=] collation_name
CREATE DATABASE
创建具有给定名称的数据库。要使用此语句,您需要 CREATE
数据库特权。 CREATE SCHEMA
是的同义词CREATE DATABASE
。
如果数据库存在且您未指定IF NOT EXISTS
,则会发生错误。
在具有 active LOCK TABLES
语句的 session 中不允许CREATE DATABASE。
create_specification
选项指定数据库特征。数据库特征存储在数据库目录的db.opt
文件中。CHARACTER SET
子句指定默认数据库字符集。 COLLATE
子句指定默认的数据库排序规则。
MySQL中的数据库被实现为包含与数据库中的表相对应的文件的目录。因为最初创建数据库时数据库中没有表,所以该 CREATE DATABASE
语句仅在MySQL数据目录下创建一个数据库目录和db.opt
文件 。第9.2节“模式对象名称”中给出了允许的数据库名称的规则。如果数据库名称包含特殊字符,则数据库目录的名称包含这些字符的编码版本,如第9.2.4节“将标识符映射到文件名”中所述。
如果您在数据目录下手动创建目录(例如,使用mkdir),则服务器会将其视为数据库目录,并显示在SHOW DATABASES
的输出中 。
MySQL 对数据库的数量没有限制。底层文件系统可能对目录数量有限制。
您也可以使用mysqladmin程序创建数据库。
CREATE
[DEFINER = user]
EVENT
[IF NOT EXISTS]
event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE | DISABLE ON SLAVE]
[COMMENT 'string']
DO event_body;
schedule:
AT timestamp [+ INTERVAL interval] ...
| EVERY interval
[STARTS timestamp [+ INTERVAL interval] ...]
[ENDS timestamp [+ INTERVAL interval] ...]
interval:
quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |
WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |
DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND}
该语句创建并安排新事件。除非启用了事件计划程序,否则事件将不会运行。有关检查事件调度程序状态并在必要时启用它的信息,请参见第23.4.2节“事件调度程序配置”。
CREATE EVENT
需要EVENT
架构的特权在其中创建事件的。如果存在DEFINER
子句,则所需的权限取决于user
value
有效 CREATE EVENT
语句的最低要求如下:
CREATE EVENT
加上event name,它唯一地标识数据库 schema 中的 event。ON SCHEDULE
子句,它确定 event 执行的时间和频率。DO
子句,包含要由 event 执行的 SQL 语句。这是最小CREATE EVENT
语句的示例:
CREATE EVENT myevent
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
UPDATE myschema.mytable SET mycol = mycol + 1;
前一个语句创建一个名为myevent
的 event。此 event 在创建一小时后执行一次。一个 SQL 语句,该语句将myschema.mytable
table 的mycol
列的 value 递增 1。
event_name
必须是有效的 MySQL 标识符,最大长度为 64 个字符。Event 名称不区分大小写,因此您不能在同一个 schema 中有两个名为myevent
和MyEvent
的 events。通常,管理 event 名称的规则与存储例程的名称相同。
event 与 schema 相关联。如果没有 schema 被指示为event_name
的一部分,则假定默认(当前)schema。要在特定的 schema 中创建 event,请使用schema_name.event_name
语法来创建合格的事件名。
如果DEFINER
子句被省略,则默认的definer就是执行 CREATE EVENT
语句的用户,这和明确的指出 DEFINER = CURRENT_USER一样。
在 event 体内,CURRENT_USER function 返回用于在 event执行时检查权限的帐户. 该帐户是DEFINER
用户,有关 events 中用户审核的信息,请参阅第 6.2.18 节,“SQL-Based 账户活动审计”。
IF NOT EXISTS
与r CREATE EVENT
和 CREATE TABLE
具有相同的含义:如果 schema 中存在名为event_name
的 event,则不执行任何操作,也不会产生错误。 (但是,在这样的情况下会产生警告.)
ON SCHEDULE
子句决定了 event 的event_body
重复定义的时间,频率和方式。该子句采用以下两种形式之一:
AT timestamp
用于 one-time event。它指定 event 仅在timestamp
给出的 date 和 time 执行一次,它必须包含 date 和 time,或者必须是解析为 datetime value 的表达式。为此,您可以使用 DATETIME
或TIMESTAMP类型的值,如果 date 是过去的日期,则会发出警告,如下所示:
mysql> SELECT NOW();
+---------------------+
| NOW() |
+---------------------+
| 2006-02-10 23:59:01 |
+---------------------+
1 row in set (0.04 sec)
mysql> CREATE EVENT e_totals
-> ON SCHEDULE AT '2006-02-10 23:59:00'
-> DO INSERT INTO test.totals VALUES (NOW());
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
Level: Note
Code: 1588
Message: Event execution time is in the past and ON COMPLETION NOT
PRESERVE is set. The event was dropped immediately after
creation.
CREATE EVENT
语句本身无效 - 无论出于何种原因 - 失败并显示错误。
您可以使用CURRENTTIMESTAMP指定当前 date 和 time。在这种情况下,event 会在创建后立即执行。
要创建一个 event,它在将来的某个时刻发生,相对于当前的 date 和 time-如短语“从现在起三周”所表达的那样 - 你可以使用可选的子句+ INTERVAL interval
。 interval
部分由两部分组成,数量和 time 单位,并遵循Temporal Intervals中描述的语法规则,但在定义 event 时不能使用任何涉及微秒的单位关键字。对于某些间隔类型,可以使用复杂的 time 单位。例如,“两分十秒”可以表示为+ INTERVAL '2:10' MINUTE_SECOND
。
您还可以组合间隔。例如,AT CURRENT_TIMESTAMP + INTERVAL 3 WEEK + INTERVAL 2 DAY
相当于“从现在开始的三周加两天”。这样一个子句的每个部分必须以+ INTERVAL
开头。
EVERY
子句。 EVERY
关键字之后是interval
,如前面对AT
关键字的讨论中所述。 (+ INTERVAL
不与EVERY
一起使用 .)例如,EVERY 6 WEEK
表示“每六周一次”。虽然EVERY
子句中不允许使用+ INTERVAL
子句,但您可以使用允许的相同复杂时间单位在+ INTERVAL中。
EVERY
子句可以包含可选的STARTS
子句。 STARTS
之后是timestamp
value,指示动作应该何时开始重复,并且还可以使用+ INTERVAL interval
来指定 time“从现在起”的数量。例如,EVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEK
表示“每三个月,从现在开始一周”。同样,你可以表示“每两周,从现在开始的六小时十五分钟”作为EVERY 2 WEEK STARTS CURRENT_TIMESTAMP + INTERVAL '6:15' HOUR_MINUTE
。不指定STARTS
与使用STARTS CURRENT_TIMESTAMP
相同 - 也就是说,为 event 指定的操作在创建 event 后立即开始重复。
EVERY
子句可以包含可选的ENDS
子句。 ENDS
关键字之后是timestamp
value,它告诉 MySQL 何时 event 应该停止重复。你也可以使用+ INTERVAL interval
和ENDS
;例如,EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK
相当于“每十二小时,从现在开始后三十分钟开始重复,从现在开始四周后停止”。不使用ENDS
意味着 event 继续无限期执行。
ENDS
支持与STARTS
相同的复杂 time 单位语法。
您可以在EVERY
子句中使用STARTS
,ENDS
,两个都用或者两个都不用。
如果重复 event 未在其调度间隔内终止,则结果可能是 event 同时执行的多个实例。如果这是不合需要的,您应该建立一个机制来防止同时发生。比如,您可以使用GET_LOCK() function,或行或 table 锁定。
该ON SCHEDULE
子句可以使用涉及内置MySQL函数和用户变量的表达式来获取其包含的timestamp
或 interval
值。您不得在此类表达式中使用存储的函数或用户定义的函数,也不得使用任何表引用。但是,您可以使用SELECT FROM DUAL
。对于CREATE EVENT
和 ALTER EVENT
语句都是如此 。在这种情况下,明确不允许引用存储的函数,用户定义的函数和表,并且它们会因错误而失败(请参见Bug#22830)。
使用当前 session timezone value 解释ON SCHEDULE
子句中的时间。这成为 event time zone;也就是说,time zone 用于 event 调度,并且在 event 执行时生效。这些时间转换为 UTC 并与mysql.event
table 中的 event time zone 一起存储。这使 event 执行能够按照定义继续执行,而不管服务器 time zone 或夏令时 time 效果的任何后续更改。有关 event 次表示的其他信息,请参阅第 23.4.4 节,“事件元数据”。另见第 13.7.5.18 节,“SHOW EVENTS 语法”和第 24.8 节,“INFORMATIONSCHEMA EVENTS Table”。
通常,一旦 event 过期,它会立即被删除。您可以通过指定ON COMPLETION PRESERVE
来超控此行为。使用ON COMPLETION NOT PRESERVE
只会使默认的非持久行为显式化。
您可以使用DISABLE
关键字创建事件,阻止其处于活动状态 。或者,您可以 ENABLE
用来使默认活动状态显式。这与ALTER EVENT一起使用最为有用。
第三个值也可能代替ENABLE
或DISABLE
; DISABLE ON SLAVE
设置从站上 event 的状态,以指示 event 是在 master 上创建并复制到从站,但未在从站上执行。
您可以使用COMMENT
子句,comment
可以是任意 64 个字符,可以用来描述事件。comment 文本是一个 string 文字,必须用引号括起来。
DO
子句指定 event 携带的操作,由 SQL 语句组成。几乎任何可以在存储例程中使用的有效 MySQL 语句也可以用作调度 event 的操作语句。 例如,以下事件每小时将sessions
表中的所有行删除一次,其中 table 是site_activity
schema 的一部分:
CREATE EVENT e_hourly
ON SCHEDULE
EVERY 1 HOUR
COMMENT 'Clears out sessions table each hour.'
DO
DELETE FROM site_activity.sessions;
当事件创建或修改完成时,MySQL store sql_mode系统变量设置生效,并且始终使用此设置强制执行 event, 而与事件开始执行时当前的服务器SQL模式无关。
CREATE EVENT包含一个
ALTER EVENT
语句在 DO子句中看起来是成功的,
但是,当服务器尝试执行生成的计划事件时,执行失败并显示错误。
注意诸如
SELECT
或SHOW
仅返回结果集的语句在事件中使用时无效;它们的输出不会发送到MySQL Monitor,也不会存储在任何地方。但是,您可以使用诸如SELECT ... INTO
和INSERT INTO ... SELECT
存储结果的语句 。(有关后者的实例,请参阅本节中的下一个示例。)
事件所属的架构是该DO
子句中表引用的默认架构。对其他模式中的表的任何引用都必须使用正确的模式名称进行限定。
与存储例程一样,DO
可以通过使用BEGIN
and END
关键字在子句中的复合语句语法,如下所示:
delimiter |
CREATE EVENT e_daily
ON SCHEDULE
EVERY 1 DAY
COMMENT 'Saves total number of sessions then clears the table each day'
DO
BEGIN
INSERT INTO site_activity.totals (time, total)
SELECT CURRENT_TIMESTAMP, COUNT(*)
FROM site_activity.sessions;
DELETE FROM site_activity.sessions;
END |
delimiter ;
本示例使用delimiter
命令更改语句定界符。请参见 第23.1节“定义存储程序”。
事件中可能会出现更复杂的复合语句,例如存储例程中使用的复合语句。此示例使用局部变量,错误处理程序和流控制构造:
delimiter |
CREATE EVENT e
ON SCHEDULE
EVERY 5 SECOND
DO
BEGIN
DECLARE v INTEGER;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
SET v = 0;
WHILE v < 5 DO
INSERT INTO t1 VALUES (0);
UPDATE t2 SET s1 = s1 + 1;
SET v = v + 1;
END WHILE;
END |
delimiter ;
无法将参数直接传递给事件或从事件传递参数。但是,可以在事件中使用参数调用存储的例程:
CREATE EVENT e_call_myproc
ON SCHEDULE
AT CURRENT_TIMESTAMP + INTERVAL 1 DAY
DO CALL myproc(5, 27);
如果事件的定义者具有足以设置全局系统变量的特权(请参见 第5.1.8.1节“系统变量特权”),则事件可以读取和写入全局变量。由于授予此类特权可能会导致滥用行为,因此必须格外小心。
通常,在存储例程中任何有效的语句都可以用于事件执行的动作语句。有关存储例程中允许的语句的更多信息,请参见第23.2.1节“存储例程语法”。您可以将事件创建为存储例程的一部分,但是一个事件不能创建另一个事件。
CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX index_name
[index_type]
ON tbl_name (key_part,...)
[index_option]
[algorithm_option | lock_option] ...
key_part:
col_name [(length)] [ASC | DESC]
index_option:
KEY_BLOCK_SIZE [=] value
| index_type
| WITH PARSER parser_name
| COMMENT 'string'
index_type:
USING {BTREE | HASH}
algorithm_option:
ALGORITHM [=] {DEFAULT | INPLACE | COPY}
lock_option:
LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}
通常,在使用CREATE TABLE
创建表本身时,会在表上创建所有索引。该指南对于InnoDB
表尤为重要 ,在表中,主键确定数据文件中行的物理布局。 CREATE INDEX
使您可以向现有表添加索引。
CREATE INDEX
映射到一条 ALTER TABLE
语句以创建索引。 CREATE INDEX
不能用于创建一个PRIMARY KEY
; 使用 ALTER TABLE
代替。有关索引的更多信息,请参见第8.3.1节“ MySQL如何使用索引”。
InnoDB
支持虚拟列上的二级索引。有关更多信息,请参见 第13.1.18.9节“二级索引和生成的列”。
当innodb_stats_persistent设置完成时,在INnodb表创建索引之后运行 ANALYZE TABLE语句
(key_part1, key_part2, ...)
形式的索引规范创建了一个包含多个 key 部分的索引。索引键值是通过合并给定键部分的值而形成的。例如(col1, col2, col3)
指定 multiple-column 索引,其索引键由col1
,col2
和col3
的值组成。
key_part
规范可以以ASC
或DESC
结尾。这些关键字允许用于将来的扩展,以指定升序或降序索引 value 存储。目前,他们被解析但被忽略;索引值始终以升序 order 存储。
以下各节描述了该CREATE INDEX
语句的不同方面 :
对于字符串列,可以创建仅使用列值的前导部分的索引,使用col_name(length)
语法指定索引前缀长度:
BLOB
和 TEXT
关键零部件。此外, BLOB
和 TEXT
列可以只对索引InnoDB
, MyISAM
和BLACKHOLE
表。CREATE TABLE
,ALTER TABLE
和CREATE INDEX
statements 中索引规范的前缀长度被解释为非二进制 string 类型(CHAR,VARCHAR,文本)的字符数和二进制 string 类型(BINARY,VARBINARY,BLOB)的字节数。在为使用多字节字符集的非二进制 string 列指定前缀长度时,请考虑这一点。前缀支持和前缀长度(支持的位置)取决于存储引擎。例如,前缀最大可为767个字节对于 InnoDB
tables ,如果 innodb_large_prefix变量启用,
可有3072 bytes ;对于 MyISAM
tables,前缀长度限制为1000个字节, NDB存储引擎不支持前缀。
从 MySQL 5.7.17 开始,如果指定的索引前缀超过最大列数据类型大小, CREATE INDEX
将按如下方式处理索引:
此处显示的语句使用name
列的前 10 个字符创建索引(假设name
具有非二进制 string 类型):
CREATE INDEX part_of_name ON customer (name(10));
如果列名通常在前 10 个字符中不同,则使用此索引执行的查找不应比使用从整个name
列创建的索引慢得多。此外,使用索引的列前缀可以使索引文件更小,这可以节省大量磁盘空间,也可能加快 INSERT
操作。
唯一索引
UNIQUE
索引创建一个约束,使索引中的所有值必须是不同的。如果您尝试添加一个 key value 与现有行匹配的新行,则会发生错误。如果为UNIQUE
索引中的列指定前缀值 ,则列值在前缀长度内必须唯一。一个UNIQUE
索引,可以多次NULL
进行,可以包含列的NULL
值。
如果 table 具有PRIMARY KEY
或UNIQUE NOT NULL
索引,该索引由具有 integer 类型的单个列组成,则可以使用 _rowid
来引用SELECT
语句中的索引列,如下所示:
PRIMARY KEY
由单个 integer 列组成,_rowid
指的是PRIMARY KEY
列。如果有PRIMARY KEY
但它不包含单个 integer 列,则不能使用_rowid
。_rowid
引用第一个UNIQUE NOT NULL
索引中的列。如果第一个UNIQUE NOT NULL
索引不包含单个 integer 列,则不能使用_rowid
。Full-Text 索引
FULLTEXT
索引仅支持InnoDB和MyISAM 数据表,并且只能包含CHAR,VARCHAR和文本列。索引总是发生在整个列上;不支持列前缀索引,如果指定,则忽略任何前缀长度。有关操作的详细信息,请参阅第 12.9 节,“Full-Text 搜索功能”。
空间索引
MyISAM
, InnoDB
, NDB
, and ARCHIVE
存储引擎支持 POINT
and GEOMETRY
等空间列。但是,空间列索引的支持因引擎而异。空间列上的空间和非空间索引可根据以下规则使用。
空间列上的空间索引(使用SPATIAL INDEX
创建)具有以下特征:
仅适用于MyISAM 数据和InnoDB表。为其他存储引擎指定SPATIAL INDEX
会导致错误。
索引列必须为NOT NULL
。
列前缀长度是禁止的。每列的全宽是索引。
空间列上的非空间索引(使用INDEX
,UNIQUE
或PRIMARY KEY
创建)具有以下特征:
NULL
。SPATIAL
除POINT
列之外的非索引中的每个空间列,必须指定列前缀长度。(这与对索引BLOB
列的要求相同 。)前缀长度以字节为单位。SPATIAL
索引的索引类型取决于存储引擎。目前,使用 B-tree。InnoDB
, MyISAM
和 MEMORY
表可以有一个列NULL
。索引选项
在 key 部分列表之后,可以给出索引选项。index_option
value 可以是以下任何一种:
对于MyISAM 数据表,KEY_BLOCK_SIZE
可选地指定用于索引 key 块的大小(以字节为单位)。该值被视为提示,可以使用不同的尺寸。为单个索引定义指定的KEY_BLOCK_SIZE
value 会覆盖 table-level KEY_BLOCK_SIZE
value。
InnoDB表的索引 level 不支持KEY_BLOCK_SIZE
。
某些存储引擎允许您在创建索引时指定索引类型。例如:
CREATE TABLE lookup (id INT) ENGINE = MEMORY;
CREATE INDEX id_index ON lookup (id) USING BTREE;
Table 13.1, “Index Types Per Storage Engine” 显示不同存储引擎支持的允许索引类型值。如果列出了多个索引类型,则在没有给出索引类型说明符时,第一个是缺省值。未在 table 中列出的存储引擎不支持索引定义中的index_type
子句
每个存储引擎的索引类型
Storage Engine | Permissible Index Types |
---|---|
InnoDB |
BTREE |
MyISAM |
BTREE |
MEMORY /HEAP |
HASH , BTREE |
NDB |
HASH , BTREE (see note in text) |
index_type
子句不能用于FULLTEXT INDEX
或SPATIAL INDEX
规范。Full-text index implementation 依赖于存储引擎。空间索引实现为 R-tree 索引。BTREE
索引由 NDB
存储引擎实现为 T-tree 索引。
注意
对于NDB
表列上的索引,USING
只能为唯一索引或主键指定该选项。USING HASH
防止创建有序索引;否则,在NDB
表上创建唯一索引或主键会自动导致同时创建有序索引和哈希索引,每个索引都索引同一组列。对于包含
NDB
表的一个或多个NULL
列的唯一索引,哈希索引只能用于查找文字值,这意味着IS [NOT] NULL
条件需要对表进行全面扫描。一种解决方法是,确保NULL
始终使用这样的表来创建使用该表上一个或多个列的唯一索引:也就是说,在创建索引时避免使用USING HASH
。
如果指定的索引类型对于给定的存储引擎无效,但引擎可以使用另一种索引类型而不影响查询结果,则引擎将使用可用类型。解析器将RTREE
识别为类型名,但目前无法为任何存储引擎指定。
注意
不推荐在ON tbl_name
子句之前使用index_type
选项;在将来的 MySQL 版本中将删除对此位置中选项的使用的支持。如果在较早和较晚的位置都给出index_type
选项,则以最后一个选项为准。
TYPE type_name
被识别为USING type_name
的同义词。但是,USING
是首选形式。
下表显示了支持该index_type
选件的存储引擎的索引特征 。
InnoDB 存储引擎索引特征
Index Class | Index Type | Stores NULL VALUES | Permits Multiple NULL Values | IS NULL Scan Type | IS NOT NULL Scan Type |
---|---|---|---|---|---|
Primary key | BTREE |
No | No | N/A | N/A |
Unique | BTREE |
Yes | Yes | Index | Index |
Key | BTREE |
Yes | Yes | Index | Index |
FULLTEXT |
N/A | Yes | Yes | Table | Table |
SPATIAL |
N/A | No | No | N/A | N/A |
MyISAM 存储引擎索引特征
Index Class | Index Type | Stores NULL VALUES | Permits Multiple NULL Values | IS NULL Scan Type | IS NOT NULL Scan Type |
---|---|---|---|---|---|
Primary key | BTREE |
No | No | N/A | N/A |
Unique | BTREE |
Yes | Yes | Index | Index |
Key | BTREE |
Yes | Yes | Index | Index |
FULLTEXT |
N/A | Yes | Yes | Table | Table |
SPATIAL |
N/A | No | No | N/A | N/A |
MEMORY 存储引擎索引特征
Index Class | Index Type | Stores NULL VALUES | Permits Multiple NULL Values | IS NULL Scan Type | IS NOT NULL Scan Type |
---|---|---|---|---|---|
Primary key | BTREE |
No | No | N/A | N/A |
Unique | BTREE |
Yes | Yes | Index | Index |
Key | BTREE |
Yes | Yes | Index | Index |
Primary key | HASH |
No | No | N/A | N/A |
Unique | HASH |
Yes | Yes | Index | Index |
Key | HASH |
Yes | Yes | Index | Index |
NDB 存储引擎索引特征
Index Class | Index Type | Stores NULL VALUES | Permits Multiple NULL Values | IS NULL Scan Type | IS NOT NULL Scan Type |
---|---|---|---|---|---|
Primary key | BTREE |
No | No | Index | Index |
Unique | BTREE |
Yes | Yes | Index | Index |
Key | BTREE |
Yes | Yes | Index | Index |
Primary key | HASH |
No | No | Table (see note 1) | Table (see note 1) |
Unique | HASH |
Yes | Yes | Table (see note 1) | Table (see note 1) |
Key | HASH |
Yes | Yes | Table (see note 1) | Table (see note 1) |
Table note:
如果指定了USING HASH
,则会阻止创建隐式有序索引。
此选项仅可用于FULLTEXT
索引。如果 full-text 索引和搜索操作需要特殊处理,它会将解析器插件与索引相关联。 InnoDB和MyISAM 数据支持 full-text 解析器插件。
索引定义可以包含最多 1024 个字符内容。
可以使用 CREATE INDEX
语句的index_option
COMMENT
子句为各个索引配置索引页MERGE_THRESHOLD
CREATE TABLE t1 (id INT);
CREATE INDEX id_index ON t1 (id) COMMENT 'MERGE_THRESHOLD=40';
如果删除行或者更新操作缩短行时索引页的 page-full 百分比低于MERGE_THRESHOLD
value,则InnoDB会尝试将索引页与相邻索引页合并。默认MERGE_THRESHOLD
value 为 50,这是以前硬编码的 value。
MERGE_THRESHOLD
也可以使用CREATE TABLE
and ALTER TABLE
语句在索引级别和表级别定义 。
表复制和锁定选项
可以给出ALGORITHM
和LOCK
子句来影响 table 复制方法和 level 并发性,以便在修改索引时读取和写入 table。它们与ALTER TABLE语句具有相同的含义。有关更多信息,请参阅第 13.1.8 节,“ALTER TABLE 语法”
NDB Cluster 以前使用不再支持的替代语法支持在线CREATE INDEX
操作。 NDB Cluster 现在支持使用与标准 MySQL 服务器相同的ALGORITHM=INPLACE
语法进行在线操作。
CREATE LOGFILE GROUP logfile_group
ADD UNDOFILE 'undo_file'
[INITIAL_SIZE [=] initial_size]
[UNDO_BUFFER_SIZE [=] undo_buffer_size]
[REDO_BUFFER_SIZE [=] redo_buffer_size]
[NODEGROUP [=] nodegroup_id]
[WAIT]
[COMMENT [=] 'string']
ENGINE [=] engine_name
该语句创建一个名为logfile_group的新日志文件组,其中包含一个名为“undo_file
”的UNDO
文件, CREATE LOGFILE GROUP
语句只有一个ADD UNDOFILE
子句。有关 log 文件组命名的规则,请参阅第 9.2 节,“ Schema Object Names”。
注意所有NDB群集磁盘数据对象共享相同的名称空间。这意味着每个磁盘数据对象必须唯一地命名(而不仅仅是给定类型的每个磁盘数据对象)。例如,您不能具有相同名称的表空间和日志文件组,或具有相同名称的表空间和数据文件。
在任何给定时间,每个NDB群集实例只能有一个日志文件组。
INITIAL_SIZE
参数设置 UNDO
文件的初始大小。如果未指定,则默认为128M
(128兆字节)。可选的UNDO_BUFFER_SIZE
参数设置UNDO
缓冲区用于 log 文件 group 的大小; UNDO_BUFFER_SIZE
的默认 value 是8M
(8 兆字节);此 value 不能超过系统内存可用的数量。这两个参数都以字节为单位指定。您可以选择在其中一个或两个后面加上一个字母的缩写来表示数量级,通常,这是字母M
(兆字节)或G
(千兆字节)之一。
用于UNDO_BUFFER_SIZE
的 Memory 来自 global 池,其大小由SharedGlobalMemory数据节点 configuration 参数的 value 确定。
这包括通过设置InitialLogFileGroup数据节点 configuration 参数为此选项隐含的任何默认 value。
UNDO_BUFFER_SIZE
允许的最大值为 629145600(600 MB)。
在 32-bit 系统上,INITIAL_SIZE
支持的最大 value 为 4294967296(4 GB)。 (Bug#29186)
ENGINE
选项确定此 log 文件 group 要使用的存储引擎,engine_name
是存储引擎的 name。在 MySQL 5.7 中,这必须是 NDB
(or NDBCLUSTER
)。如果未设置ENGINE
,MySQL 将尝试使用default_storage_engine服务器系统变量(以前为storage_engine)指定的引擎。在任何情况下,如果引擎未指定为导航台或NDBCLUSTER,则CREATE LOGFILE GROUP
语句似乎成功但实际上无法创建 log 文件 group,如下所示:
mysql> CREATE LOGFILE GROUP lg1
-> ADD UNDOFILE 'undo.dat' INITIAL_SIZE = 10M;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+-------+------+------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+------------------------------------------------------------------------------------------------+
| Error | 1478 | Table storage engine 'InnoDB' does not support the create option 'TABLESPACE or LOGFILE GROUP' |
+-------+------+------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> DROP LOGFILE GROUP lg1 ENGINE = NDB;
ERROR 1529 (HY000): Failed to drop LOGFILE GROUP
mysql> CREATE LOGFILE GROUP lg1
-> ADD UNDOFILE 'undo.dat' INITIAL_SIZE = 10M
-> ENGINE = NDB;
Query OK, 0 rows affected (2.97 sec)
事实上CREATE LOGFILE GROUP
语句实际上并没有在非NDB
存储引擎被命名时发现错误,而是看似成功,这是一个已知的问题,我们希望在未来的 NDB Cluster 版本中解决这个问题。
REDO_BUFFER_SIZE
,NODEGROUP
,WAIT
和COMMENT
被解析但被忽略,因此在 MySQL 5.7 中没有效果。这些选项旨在用于将来的扩展。
与ENGINE [=] NDB
一起使用时,会在每个 Cluster 数据节点上创建 log 文件 group 和关联的UNDO
log 文件。您可以通过查询INFORMATIONSCHEMA.FILES table 验证是否已创建UNDO
files 并获取有关它们的信息。例如:
mysql> SELECT LOGFILE_GROUP_NAME, LOGFILE_GROUP_NUMBER, EXTRA
-> FROM INFORMATION_SCHEMA.FILES
-> WHERE FILE_NAME = 'undo_10.dat';
+--------------------+----------------------+----------------+
| LOGFILE_GROUP_NAME | LOGFILE_GROUP_NUMBER | EXTRA |
+--------------------+----------------------+----------------+
| lg_3 | 11 | CLUSTER_NODE=3 |
| lg_3 | 11 | CLUSTER_NODE=4 |
+--------------------+----------------------+----------------+
2 rows in set (0.06 sec)
CREATE LOGFILE GROUP
仅对 NDB Cluster 的磁盘数据存储有用。见第 21.5.13 节,“NDB Cluster 磁盘数据表”。
CREATE
[DEFINER = user]
PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
CREATE
[DEFINER = user]
FUNCTION sp_name ([func_parameter[,...]])
RETURNS type
[characteristic ...] routine_body
proc_parameter:
[ IN | OUT | INOUT ] param_name type
func_parameter:
param_name type
type:
Any valid MySQL data type
characteristic:
COMMENT 'string'
| LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
routine_body:
Valid SQL routine statement
这些 statements 创建存储的例程。默认情况下,例程与默认数据库关联。要将例程与给定数据库显式关联,请在创建时将 name 指定为db_name.sp_name
。
CREATE FUNCTION
语句也在 MySQL 中用于支持 UDF(user-defined 函数)。见第 28.4 节,“向 MySQL 添加新函数”。 UDF 可以被视为外部存储的函数。存储函数与 UDF 共享其命名空间。有关描述服务器如何将 references 解释为不同类型函数的规则,请参阅第 9.2.5 节,“函数名称解析和解析”。
要调用存储过程,请使用 CALL
语句(请参阅第 13.2.1 节,“CALL 语法”)。要调用存储的函数,请在表达式中引用它。该函数在表达式求值期间返回一个值。
CREATE PROCEDURE
和CREATE FUNCTION
要求 CREATE ROUTINE
特权。如果存在DEFINER
子句,则所需的权限取决于user
value,如第 23.6 节,“存储 Object 访问控制”中所述。如果启用了二进制日志记录,则CREATE FUNCTION
可能需要SUPER
特权,如第23.7节“存储的程序二进制日志记录”中所述。
默认情况下,MySQL 会自动向例程创建者授予ALTER ROUTINE
和 EXECUTE
特权。可以通过禁用automatic_sp_privileges系统变量来更改此行为。见第 23.2.2 节,“存储例程和 MySQL 权限”。
当在例程执行时检查访问权限, DEFINER
and SQL SECURITY
子句指定安全context (security context),如本节后面所述。
如果例程 name 与 built-in SQL function 的 name 相同,则会发生语法错误,除非在定义例程或稍后调用例程时在名字和后面括号之间使用空格。因此,请避免将现有 SQL 函数的名称用于您自己的存储例程。
IGNORE_SPACE SQL 模式适用于 built-in 函数,而不适用于存储的例程。无论是否启用了IGNORE_SPACE,在存储的例程 name 之后始终允许有空格。
括号内的参数列表必须始终存在。如果没有参数,则应使用()
的空参数列表。参数名称不区分大小写。
默认情况下,每个参数都是IN
参数。要为参数指定其他参数,请在参数 name 之前使用关键字OUT
或INOUT
。
注意
将参数指定为IN
,OUT
或INOUT
仅对PROCEDURE
有效。对于FUNCTION
,参数始终被视为IN
参数。
IN参数将值传递给过程,该过程可能会修改 value,但过程返回时调用者看不到修改。它的初始 value 在过程中是NULL
,当过程返回时,它的 value 对调用者是可见的。INOUT
参数由调用者初始化,可以由过程修改,并且过程返回时调用者可以看到过程所做的任何更改。
对于每个OUT
或INOUT
参数,在 CALL
语句中传递一个 user-defined 变量来调用该过程,以便在过程返回时获取其 value。如果从另一个存储过程或 function 中调用该过程,还可以将例程参数或本地例程变量作为OUT
或INOUT
参数传递。如果从触发器中调用过程,还可以将NEW.col_name
作为OUT
或INOUT
参数传递。
有关未处理条件对过程参数的影响的信息,请参阅第 13.6.7.8 节,“条件处理和 OUT 或 INOUT 参数”。
在例程中准备的语句中不能引用例程参数;见第 23.8 节,“存储程序的限制”。
以下示例显示了一个使用OUT
参数的简单存储过程:
mysql> delimiter //
mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
-> BEGIN
-> SELECT COUNT(*) INTO param1 FROM t;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> CALL simpleproc(@a);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @a;
+------+
| @a |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
在定义过程时,example 使用MySQL client delimiter
命令将语句分隔符从;
更改为//
。这使得过程体中使用的;
分隔符可以传递到服务器,而不是由MySQL本身解释。见第 23.1 节,“定义存储程序”。
RETURNS
子句只能为FUNCTION
指定,因为它是必需的。它表示 function 的 return 类型,function 体必须包含RETURN value
语句。如果 RETURN
语句返回不同类型的 value,则 value 将被强制转换为正确的类型。比如,如果 function 指定RETURNS
子句中的值为ENUM
or SET
,但 RETURN
语句返回 integer,则 function 返回的 value 是相应 ENUM
成员或 SET
成员。
下例,函数接受一个参数,使用 SQL function 执行操作,并返回结果。在这种情况下,不必使用delimiter
,因为 function 定义不包含内部;
语句分隔符:
mysql> CREATE FUNCTION hello (s CHAR(20))
mysql> RETURNS CHAR(50) DETERMINISTIC
-> RETURN CONCAT('Hello, ',s,'!');
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT hello('world');
+----------------+
| hello('world') |
+----------------+
| Hello, world! |
+----------------+
1 row in set (0.00 sec)
可以声明参数类型和 function return 类型以使用任何有效的数据类型。如果前面有CHARACTER SET
规范,则可以使用COLLATE
属性。
routine_body
由有效的 SQL 例程语句组成。这可以是一个简单的语句,如 SELECT
or INSERT
, 或使用BEGIN
和END
编写的复合语句。复合语句可以包含声明,循环和其他控制结构 statements。这些 statements 的语法在第 13.6 节,“Compound-Statement 语法”中描述。实际上,存储的函数倾向于使用复合语句,除非正文由单个 RETURN
语句组成。
MySQL 允许例程包含 DDL statements,例如CREATE
和DROP
。MySQL 还允许存储过程(但不是存储函数)包含 SQL transaction statements,例如 COMMIT.
存储的函数可能不包含执行显式或隐式的提交或回滚语句。 SQL 标准不要求支持这些语句,该标准规定每个 DBMS 供应商可以决定是否允许它们。
语句的返回值
可以在存储过程中使用,但不能在存储的 function 中使用。此禁止包括没有INTO var_list
子句的 SELECT
语句,和 SHOW
, EXPLAIN
, and CHECK TABLE语句
.对于可以在 function definition time 确定返回结果集的语句,会发生Not allowed to return a result set from a function
错误(ER_SP_NO_RETSET)。对于只能在语句运行时确定返回结果集的语句,会发生PROCEDURE %s can't return a result set in the given context
错误(ER_SP_BADSELECT)。
不允许在存储例程中使用USE
statements。调用例程时,将执行隐式USE db_name
(并在例程终止时撤消)。导致例程在执行时具有给定的默认数据库。对例程默认数据库以外的数据库中对象的引用应使用适当的数据库名称进行限定。
有关存储例程中不允许的 statements 的其他信息,请参阅第 23.8 节,“存储程序的限制”。
有关从具有 MySQL 接口的语言编写的程序中调用存储过程的信息,请参阅第 13.2.1 节,“CALL 语法”。
在创建或更改例程时,MySQL存储的sql_mode系统变量设置生效,并且始终使用此设置执行例程,而不管例程开始执行时当前服务器 SQL 模式如何。
从调用者的SQL模式切换到例程的SQL模式是在对参数进行评估并将结果值分配给例程参数之后发生的。如果在严格SQL模式下定义例程,但在非严格模式下调用例程,则在严格模式下不会将参数分配给例程参数。如果需要以严格的SQL模式分配传递给例程的表达式,则应引用具有有效的严格模式的例程。
COMMENT
特性是 MySQL 扩展,可用于描述存储的例程。此信息由 SHOW CREATE PROCEDURE
and SHOW CREATE FUNCTION
statements 显示。
LANGUAGE
特性表示编写例程的语言。服务器忽略了这个特性;仅支持 SQL 例程。
如果例程对于相同的输入参数总是产生相同的结果,则该例程被认为是“确定性的”,否则被认为是“不确定的”。如果例程定义中既未给出DETERMINISTIC
也未给出NOT DETERMINISTIC
,则默认为NOT DETERMINISTIC
。要声明 function 是确定性的,必须明确指定DETERMINISTIC
。
评估例程的性质是基于创建者的“诚实”:MySQL 不检查声明为DETERMINISTIC
的例程是否产生非确定性结果的语句。但是,错误地申明例程可能会影响结果或影响性能。将非确定性例程声明为DETERMINISTIC
可能会导致优化程序选择错误的执行计划,从而导致意外结果。将确定性例程声明为NONDETERMINISTIC
可能会导致不使用可用的优化,从而降低性能。
如果启用了二进制日志记录,则该DETERMINISTIC
特性会影响MySQL接受哪些例程定义。请参见第23.7节“存储的程序二进制日志记录”。
包含NOW()
函数(或其同义词)或 RAND()
不确定性的例程,但是它可能仍然是复制安全的。对于 NOW()
,二进制日志包含时间戳记并可以正确复制。 RAND()
只要在例程执行期间仅一次调用它,它也可以正确复制。(您可以将例程执行时间戳和随机数种子视为隐式输入,它们在主服务器和从属服务器上是相同的。)
几个特征提供了关于例程使用数据的性质的信息。在 MySQL 中,这些特征仅供参考。服务器不会使用它们来约束允许例程执行的 statements 类型。
CONTAINS SQL
指示例程不包含读取或写入数据的语句。如果未明确给出这些特征,则为默认设置。此类语句的示例为SET @x = 1
或DO RELEASE_LOCK('abc')
,它们执行但既不读取也不写入数据。NO SQL
表示该例程不包含 SQL statements。READS SQL DATA
表示例程包含读取数据的 statements(例如 SELECT
),但不包含写入数据的 statements。MODIFIES SQL DATA
表示例程包含可以写入数据的语句(例如 INSERT
或 DELETE
)。SQL SECURITY
特征可以是 DEFINER
或INVOKER
用于指定安全上下文;也就是说,是否执行例程所用的特权账户名来自例程DEFINER
子句中指定的帐户或调用它的用户。此帐户必须具有访问与例程关联的数据库的权限。默认的 value 是DEFINER
。调用例程的用户必须具有 EXECUTE
特权,如果例程在 definer security context 中执行,则必须具有DEFINER
帐户。
DEFINER
子句指定在例程执行时检查具有该SQL SECURITY DEFINER
特征的例程的访问权限时要使用的MySQL帐户。
如果存在DEFINER
子句,user
value 应该是指定为'user_name'@'host_name'
,,CURRENT_USER或CURRENT_USER()的 MySQL 帐户。允许的user
值取决于您拥有的权限,如第 23.6 节,“存储 Object 访问控制”中所述。有关存储的例程安全性的其他信息,另请参阅该部分。
如果省略DEFINER
子句,则默认定义者是执行 CREATE PROCEDURE
or CREATE FUNCTION
语句的用户。这与显式指定DEFINER = CURRENT_USER
相同。
在使用SQL SECURITY DEFINER
特性定义的存储例程的主体内,CURRENT_USER function 返回例程的DEFINER
value。有关存储例程中用户审核的信息,请参阅第 6.2.18 节,“SQL-Based 账户活动审计”。
请考虑以下过程,该过程显示mysql.user
system table 中列出的 MySQL 帐户数量的计数:
CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count()
BEGIN
SELECT 'Number of accounts:', COUNT(*) FROM mysql.user;
END;
无论哪个用户定义了该程序,都会为该程序分配一个DEFINER
帐户'admin'@'localhost'
。无论哪个用户调用它,它都以该帐户的权限执行(因为默认安全特性是DEFINER
)。该过程成功或失败取决于调用者是否具有 EXECUTE
特权,'admin'@'localhost'
具有mysql.user
table 的 SELECT
特权。
现在假设该过程是使用SQL SECURITY INVOKER
特性定义的:
CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count()
SQL SECURITY INVOKER
BEGIN
SELECT 'Number of accounts:', COUNT(*) FROM mysql.user;
END;
该过程仍然具有DEFINER
'admin'@'localhost'
,但在这种情况下,它以调用用户的权限执行。因此,该过程成功或失败取决于调用者是否具有 EXECUTE
特权以及mysql.user
table 的 SELECT
特权。
服务器处理例程参数的数据类型,使用DECLARE
或函数返回值创建的局部例程变量 ,如下所示:
SET x = (SELECT 1, 2)
无效。CHARACTER SET
,则使用指定的字符集及其默认排序规则。如果还存在COLLATE
属性,则使用该排序规则而不是默认排序规则。如果CHARACTER SET
和COLLATE
不存在,则使用在例程创建 time 时生效的数据库字符集和排序规则。为避免服务器使用数据库字符集和排序规则,请为字符数据参数提供显式CHARACTER SET
和COLLATE
属性。
如果更改数据库缺省字符集或排序规则,则必须删除并重新创建使用数据库缺省值的存储例程,以便它们使用新的缺省值。
数据库字符集和排序规则由character_set_database和collation_database系统变量的 value 给出。有关更多信息,请参阅第 10.3.3 节,“数据库字符集和整理”。
CREATE SERVER server_name
FOREIGN DATA WRAPPER wrapper_name
OPTIONS (option [, option] ...)
option:
{ HOST character-literal
| DATABASE character-literal
| USER character-literal
| PASSWORD character-literal
| SOCKET character-literal
| OWNER character-literal
| PORT numeric-literal }
此语句创建了使用FEDERATED
存储引擎的服务器的定义。 CREATE SERVER
语句在mysql
数据库的servers
table 中创建一个新行。此语句需要 SUPER
特权。
server_name
应该是服务器的唯一 reference。服务器定义在服务器范围内是全局的,无法将服务器定义限定为特定数据库。 server_name
的最大长度为 64 个字符(超过 64 个字符的名称将被静默截断),并且不区分大小写。您可以将 name 指定为带引号的 string。
wrapper_name
是标识符,可以用单引号引用。
对于每个选项
,您必须指定字符文字或数字文字。字符 literals 是 UTF-8,支持最大长度为 64 个字符,默认为空白(空)字符串。字符串文字被静默地截断为64个字符。数字文字必须是0到9999之间的数字,默认值为0。
注意该
OWNER
选项当前未应用,并且对创建的服务器连接的所有权或操作没有影响。
该CREATE SERVER
语句在mysql.servers
表中创建一个条目,以后可以在创建FEDERATED
table 时与CREATE TABLE
语句一起使用。
您指定的选项将用于填充mysql.servers
table 中的列。 table 列是Server_name
,Host
,Db
,Username
,Password
,Port
和Socket
。
例如:
CREATE SERVER s
FOREIGN DATA WRAPPER mysql
OPTIONS (USER 'Remote', HOST '198.51.100.106', DATABASE 'test');
请务必指定与服务器建立连接所需的所有选项。用户 name,host name 和 database name 是必需的。也可能需要其他选项,例如密码。
当 creating 与FEDERATED
table 的连接时,可以使用存储在 table 中的数据:
CREATE TABLE t (s1 INT) ENGINE=FEDERATED CONNECTION='s';
有关更多信息,请参阅第 15.8 节,“FEDERATED 存储引擎”。
CREATE SERVER
导致隐式提交。见第 13.3.3 节,“导致隐式提交的声明”。
CREATE SERVER
不管使用哪种日志记录格式,都不会将其写入二进制日志。
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 (expr)
column_definition:
data_type [NOT NULL | NULL] [DEFAULT default_value]
[AUTO_INCREMENT] [UNIQUE [KEY]] [[PRIMARY] KEY]
[COMMENT 'string']
[COLLATE collation_name]
[COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}]
[STORAGE {DISK|MEMORY}]
[reference_definition]
| data_type
[COLLATE collation_name]
[GENERATED ALWAYS] AS (expr)
[VIRTUAL | STORED] [NOT NULL | NULL]
[UNIQUE [KEY]] [[PRIMARY] KEY]
[COMMENT 'string']
[reference_definition]
data_type:
(see Chapter11, Data Types)
key_part:
col_name [(length)] [ASC | DESC]
index_type:
USING {BTREE | HASH}
index_option:
KEY_BLOCK_SIZE [=] value
| index_type
| WITH PARSER parser_name
| COMMENT 'string'
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:
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]...)
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]
query_expression:
SELECT ... (Some valid select or union statement)
CREATE TABLE
创建具有给定名称的表。您必须具有该表的CREATE
特权。
默认情况下,在默认的数据库中创建表,使用的 InnoDB
存储引擎。如果该表存在,没有默认数据库或该数据库不存在,都会发生错误。
MySQL 对表的数量没有限制。底层文件系统可能对表示表的 files 数量有限制。各个存储引擎可能会强加特定于引擎的约束。InnoDB
最多允许40亿张表。
CREATE TABLE
创建表时, 原始语句(包括所有规范和表选项)由MySQL存储。
CREATE TABLE
语句有多个方面,本节以下主题对此进行了描述:
表名
tbl_name
可以将表名指定为 db_name.tbl_name
在特定数据库中创建表。无论是否存在默认数据库(假定该数据库存在),此方法都有效。如果使用带引号的标识符,请分别为数据库和表名加上引号。例如,写 `mydb`.`mytbl`
而不是 `mydb.mytbl`
。
防止创建的表已存在的错误,但是没有去验证已存在的表的表结构是否与新创建的表的结构相同。
临时表
创建表可以时使用TEMPORARY
关键字。一个TEMPORARY
表仅在当前会话中可见,并且在关闭会话时会自动删除。
表克隆和复制
使用CREATE TABLE ... LIKE
根据另一个表的定义创建一个空表,包括原始表中定义的所有列属性和索引:
CREATE TABLE new_tbl LIKE orig_tbl;
从另一个表创建一个新表,请在 CREATE TABLE
语句的末尾添加 SELECT
语句:
CREATE TABLE new_tbl AS SELECT * FROM orig_tbl;
IGNORE
和REPLACE
选项指示在使用 SELECT
语句复制表时如何处理复制唯一键值的行。
列数据类型和属性
每个表有4096列的硬限制,但是对于给定的表,有效最大值可能会更少,并且取决于第8.4.7节“表的列数和行大小的限制”中讨论的因素。
data_type
data_type
表示列定义中的数据类型。
AUTO_INCREMENT
仅适用于整数和浮点类型。DEFAULT
并不适用于BLOB
, TEXT
, GEOMETRY
,和 JSON
类型。CHAR
, VARCHAR
,TEXT
类型, ENUM
, SET
,和任何同义词)可以包括CHARACTER SET
指定该列的字符集。CHARSET
是CHARACTER SET
的同义词。可以使用COLLATE
属性以及任何其他属性指定字符集的排序规则 。CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);
MySQL的5.7以字符的形式解释字符列定义中的长度规范。BINARY和VARBINARY的长度以字节为单位。
对于CHAR,VARCHAR,BINARY和VARBINARY列,可以创建仅使用列值的前导部分的索引,使用col_name(length)
语法指定索引前缀长度。. BLOB
and TEXT
columns也能创建索引,但是必须给定前缀长度,对于二进制字符串类型,前缀长度以字节形式给出。也就是说,索引条目包含了字段值类型为 CHAR
, VARCHAR
, and TEXT的
字段值的第一个length
(长度)的字符,还有字段值类型为 BINARY
, VARBINARY
, and BLOB的字段值的
第一个length
(长度)的字节,像这样索引只取字段值的前缀可以使索引文件小很多,有关索引前缀的更多信息,see Section 13.1.14, “CREATE INDEX Statement”.
只有InnoDB
和MyISAM
存储引擎支持 BLOB
and TEXT
列的索引。
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
从MySQL 5.7.17开始,如果指定的索引前缀超过了最大列数据类型的大小,则按 CREATE TABLE
以下方式处理索引:
JSON
列无法建立索引。您可以通过在生成的列上创建索引来解决此限制,该索引从列中提取标量值JSON
。如果既未指定NULL
也未指定NOT NULL
,则将列视为已指定NULL
。
在MySQL 5.7中,只有InnoDB
,MyISAM
和MEMORY
存储引擎支持可以具有NULL
值的列的索引。在其他情况下,您必须将索引列声明为NOT NULL,
否则将导致错误结果。
指定列的默认值。有关默认值处理的更多信息,包括列定义不包含显式DEFAULT
值的情况请参见第11.7节,“数据类型默认值”。
如果启用了NO_ZERO_DATE
或 NO_ZERO_IN_DATE
SQL模式,根据该模式使用的日期值默认值不正确,CREATE TABLE
则在未启用严格SQL模式的情况下产生警告,而在启用严格模式的情况下产生错误。例如, 启用NO_ZERO_IN_DATE
c1 DATE DEFAULT '2010-00-00'
将产生警告。
整数或浮点数列可以具有附加属性AUTO_INCREMENT
。当您将NULL
(推荐)或0
的值插入索引的AUTO_INCREMENT
列时,该列将设置为下一个序列值。通常为
,其中 value
+1value
是表中当前列的最大值。 AUTO_INCREMENT
序列以 1
开头。
要在插入行后检索自动增量值,请使用 LAST_INSERT_ID()
SQL函数或mysqlinsert_id() C API函数。
如果启用了NO_AUTO_VALUE_ON_ZERO
SQL模式下,可以存储0
在 AUTO_INCREMENT
列, 而不会产生一个新的序列值。
每个表只能有一个AUTO_INCREMENT列,必须对其进行索引,并且不能有 DEFAULT
值。仅当AUTO_INCREMENT
列仅包含正值时,它才能正常工作。插入负数被替换插入一个非常大的正数。这样做是为了避免数字从正到负“包裹”时的精度问题,并确保您不会意外地获得包含0
的AUTO_INCREMENT
列。
对于MyISAM
表,您可以在多列键中指定AUTO_INCREMENT
辅助列。
要使MySQL与某些ODBC应用程序兼容,您可以使用以下查询找到最后一个插入行的AUTO_INCREMENT
值:
SELECT * FROM tbl_name WHERE auto_col IS NULL
此方法要求sql_auto_is_null变量未设置为0。
有关InnoDB
和AUTO_INCREMENT
的信息,请参见第14.6.1.4节,“ AUTO_INCREMENT在InnoDB中处理”。有关AUTO_INCREMENT
和MySQL Replication的信息,请参见第16.4.1.1节,“复制和AUTO_INCREMENT”。
可以使用COMMENT
选项指定列的注释,最多1024个字符长。可以使用SHOW CREATE TABLE
and SHOW FULL COLUMNS
statements.来查看注释
在NDB群集中,还可以使用COLUMN_FORMAT
为 NDB
表的各列指定数据存储格式。允许的列格式为FIXED
,DYNAMIC
和DEFAULT
。FIXED
用于指定fixed-width存储,DYNAMIC
允许列为variable-width,DEFAULT
使列使用fixed-width或variable-width存储,由列的数据类型确定(可能由ROW_FORMAT
说明符覆盖)。
从MySQL NDB Cluster 7.5.4开始, COLUMN_FORMAT的默认值是固定的(在
MySQL NDB Cluster 7.5.1中, default 已经被换成DYNAMIC
,这种变化被恢复以保持与现有GA释放系列的向后兼容性。)
在NDB Cluster中,使用COLUMN_FORMAT=FIXED
定义的列的最大可能替换量为8188字节。
当前COLUMN_FORMAT对使用 NDB
以外的存储引擎的表列没有影响,COLUMN_FORMAT
在MySQL 5.7及更高版本中,被默默忽略。
对于 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
对使用 NDB
以外的存储引擎的表没有影响。 STORAGE
关键字仅在NDB Cluster随附的mysqld构建中受支持。在任何其他版本的MySQL中,该STORAGE
关键字均无法识别,尝试使用该关键字会导致语法错误。
用于指定生成的列表达式。
存储生成的列可以编入索引。 InnoDB
支持虚拟生成列上的二级索引。
索引和外键
有几个关键字适用于创建索引和外键。除了以下描述之外,对于一般背景,请参阅第 13.1.14 节,“CREATE INDEX 语法”和第 13.1.18.6 节,“使用 FOREIGN KEY 约束”。
CONSTRAINT symbol
子句可以赋予 name 约束。如果未给出该子句,或CONSTRAINT
关键字后面不包含symbol
,则 MySQL 会自动生成约束 name,并在下面指出表达式。如果使用symbol
value,则每个约束类型的 schema(数据库)必须是唯一的。重复symbol
会导致错误。
注意如果未在外键定义中提供该子句,或者在
CONSTRAINT
关键字后面没有包含symbol
,则NDB
使用外键索引 name。
SQL 标准指定所有类型的约束 (primary key, unique index, foreign key, check)属于同一名称空间。因此,每种类型约束的名称对于 schema 必须是唯一的。
一个唯一索引,其中所有 key 列必须定义为NOT NULL
。如果它们没有显式声明为NOT NULL
,那么 MySQL 会隐式声明它(并且默默地)。table 只能有一个PRIMARY KEY
。 PRIMARY KEY
的 name 始终为PRIMARY
,因此不能用作任何其他类型索引的 name。
如果你的表中没有PRIMARY KEY
和应用请求PRIMARY KEY,
MySQL 会返回没有NULL
列的第一个UNIQUE
索引作为PRIMARY KEY
。请保持PRIMARY KEY
简短,以最大程度减少二级索引的存储开销。每个二级索引条目都包含对应行的主键列的副本。
在创建的 table 中,PRIMARY KEY在第一位,然后放置所有UNIQUE
索引。这有助于 MySQL 优化器优先考虑使用哪个索引,并更快地检测重复的UNIQUE
密钥。
PRIMARY KEY
可以是 multiple-column 索引。但是,您无法使用明确规定字段中的PRIMARY KEY
key 属性创建 multiple-column 索引。这样做只会将单列标记为主列。您必须使用单独的PRIMARY KEY(key_part, ...)
子句。
如果 table 具有PRIMARY KEY
或UNIQUE NOT NULL
索引,该索引由具有 integer 类型的单个列组成,则可以使用_rowid
来引用SELECT
statements 中的索引列,如 Unique Indexes中所述。
在 MySQL 中,PRIMARY KEY
的 name 是PRIMARY
。对于其他索引,如果未指定 name,则为索引分配与第一个索引列相同的 name,并使用可选后缀 (_2
, _3
, ...
)使其唯一。您可以使用SHOW INDEX FROM tbl_name
查看 table 的索引名称。
KEY
通常是INDEX
的同义词。在列定义中,key属性PRIMARY KEY
也可以指定为KEY
。这是为了与其他数据库系统兼容而实现的。
UNIQUE
索引创建一个约束,使索引中的所有值必须是不同的。如果您尝试添加一个 key value 与现有行匹配的新行,则会发生错误。对于所有引擎,UNIQUE
索引允许包含可为NULL
列的多个NULL
值。如果为UNIQUE
索引中的列指定前缀 value,则列值必须在前缀长度内是唯一的。
如果 table 具有PRIMARY KEY
或UNIQUE NOT NULL
索引,该索引由具有 integer 类型的单个列组成,则可以使用_rowid
来引用SELECT
statements 中的索引列,如Unique Indexes.中所述。
FULLTEXT
索引是用于 full-text 搜索的特殊索引类型。只有InnoDB和MyISAM 数据存储引擎支持FULLTEXT
索引。它们只能从CHAR,VARCHAR和文本列创建。索引总是在整个列上进行;不支持列前缀索引,并且如果指定,则将忽略任何前缀长度。如果 full-text 索引和搜索操作需要特殊处理,则可以将WITH PARSER
子句指定为index_option
value 以将解析器插件与索引相关联。该子句仅对FULLTEXT
索引有效。 InnoDB和MyISAM 数据都支持 full-text 解析器插件。
您可以在空间数据类型上创建SPATIAL
索引。空间类型仅支持MyISAM
和InnoDB
表,索引列必须声明为NOT NULL
。
MySQL 支持外键,这些外键使您可以跨表交叉引用相关数据,外键约束可以帮助保持扩展数据的一致性。有关定义和选项的信息,请参见 reference_definition
和 reference_option
。
CHECK
子句被解析但被所有存储引擎忽略。
key_part
规范可以以ASC
或DESC
结尾。这些关键字允许将来用于指定升序或降序索引值存储的扩展。目前,它们已被解析但被忽略;索引值始终按升序存储。length
属性定义的前缀对于InnoDB
表最多可为 767 字节 (如果启用innodb_large_prefix选项,则为 3072 字节),对于MyISAM
表,前缀长度限制为 1000 个字节。前缀限制以字节为单位。但是CREATE TABLE
,ALTER TABLE
和CREATE INDEX
语句中索引规范的前缀长度被解释为非二进制 string 类型(CHAR,VARCHAR, TEXT
)的字符数和二进制 string 类型(BINARY,VARBINARY,BLOB)的字节数。在为使用多字节字符集的非二进制 string 列指定前缀长度时,请考虑这一点。
某些存储引擎允许您在创建索引时指定索引类型。 index_type
说明符的语法是USING type_name
。
CREATE TABLE lookup
(id INT, INDEX USING BTREE (id))
ENGINE = MEMORY;
首选位置USING
在索引列列表之后。可以在列列表之前给出它,但是不赞成在该位置使用该选项,并且在以后的MySQL版本中将删除该支持。
index_option
values 指定索引的其他选项。
对于MyISAM
表, KEY_BLOCK_SIZE
可以选择指定用于索引键块的字节大小。该值被视为提示;如有必要,可以使用其他大小。KEY_BLOCK_SIZE
为单个索引定义指定的值将覆盖表级KEY_BLOCK_SIZE
值。有关表级 KEY_BLOCK_SIZE
属性的信息,请 参见表选项。
WITH PARSER
选项只能与FULLTEXT
索引一起使用。如果 full-text 索引和搜索操作需要特殊处理,它会将解析器插件与索引相关联。
InnoDB和MyISAM 数据都支持 full-text 解析器插件。如果你有一个带有关联 full-text 解析器插件的MyISAM 数据 table,你可以使用ALTER TABLE
将 table 转换为InnoDB
。
在 MySQL 5.7 中,索引定义可以包含最多1024个字符的可选注释。
您可以使用index_option
COMMENT
子句为单个索引设置InnoDB
MERGE_THRESHOLD
value。
InnoDB
和 NDB
表支持检查外键约束。被引用表的列必须始终明确命名。支持外键上的ON DELETE
和ON UPDATE
操作。
对于其他存储引擎,MySQL Server 解析并忽略 CREATE TABLE语句
中的FOREIGN KEY
和REFERENCES
语法。
重要
对于熟悉 ANSI/ISO SQL 标准的用户,请注意,任何存储引擎(包括
InnoDB
)都不会识别或强制执行参照完整性约束定义中使用的MATCH
子句。使用显式MATCH
子句将不具有指定的效果,并且还会导致忽略ON DELETE
和ON UPDATE
子句。出于这些原因,应避免指定MATCH
。SQL 标准中的
MATCH
子句控制在与主 key 进行比较时如何处理复合(multiple-column)外键中的NULL
值。InnoDB
本质上实现了MATCH SIMPLE
定义的语义,它允许外部 key 全部或部分NULL
。在这种情况下,允许插入包含此类外键的(child table)行,并且该行与引用的(父)表中的任何行都不匹配。使用触发器可以实现其他语义。另外,MySQL要求对引用的列进行索引以提高性能。但是,
InnoDB
不强制要求将引用的列声明为UNIQUE
或NOT NULL
。对于诸如UPDATE或DELETE CASCADE之类的操作,对非唯一键或包含空值的键的外键引用的处理没有很好地定义。建议您使用只引用UNIQUE
(或PRIMARY
)和NOT NULL
的的外键。MySQL解析但忽略“ 内联
REFERENCES
规范 ”(如SQL标准所定义),其中引用被定义为列规范的一部分。 MySQL 仅在指定为单独的FOREIGN KEY
规范的一部分时才接受REFERENCES
子句。
reference_option
有关RESTRICT
,CASCADE
,SET NULL
,NO ACTION
和SET DEFAULT
选项的信息,请参阅第 13.1.18.6 节,“使用 FOREIGN KEY 约束”。
Table 选项
表选项用于优化表的行为。在大多数情况下,您不必指定任何一个。除非另有说明,否则这些选项适用于所有存储引擎。不适用于给定存储引擎的选项可以被接受并记住作为表定义的一部分。如果您以后使用ALTER TABLE转换 table 以使用其他存储引擎,则此类选项适用。
使用下表中显示的名称之一指定表的存储引擎。引擎名称可以不加引号或加引号。引号名称 'DEFAULT'
可以识别但可以忽略。
Storage Engine | Description |
---|---|
InnoDB |
Transaction-safe tables with row locking and foreign keys. The default storage engine for new tables. See Chapter 14, The InnoDB Storage Engine, and in particular Section 14.1, “Introduction to InnoDB” if you have MySQL experience but are new to InnoDB . |
MyISAM |
二进制便携式存储引擎,主要用于 read-only 或 read-mostly 工作负载。See Section 15.2, “The MyISAM Storage Engine”. |
MEMORY |
此存储引擎的数据仅存储在 memory 中, See Section 15.3, “The MEMORY Storage Engine”. |
CSV |
以 comma-separated 值格式存储行的表. See Section 15.4, “The CSV Storage Engine”. |
ARCHIVE |
归档存储引擎。 See Section 15.5, “The ARCHIVE Storage Engine”. |
EXAMPLE |
示例引擎. See Section 15.9, “The EXAMPLE Storage Engine”. |
FEDERATED |
访问远程表的存储引擎。. See Section 15.8, “The FEDERATED Storage Engine”. |
HEAP |
这是MEMORY 的同义词。 |
MERGE |
A collection of MyISAM tables used as one table. Also known as MRG_MyISAM . See Section 15.7, “The MERGE Storage Engine”. |
NDB |
群集的,基于内存的容错表,支持事务和外键。也称为 NDBCLUSTER 。 See Chapter 21, MySQL NDB Cluster 7.5 and NDB Cluster 7.6. |
默认情况下,如果指定了不可用的存储引擎,则该语句失败并显示错误。您可以通过从服务器 SQL 模式中删除NO_ENGINE_SUBSTITUTION来覆盖此行为 ,以便MySQL允许将指定的引擎替换为默认的存储引擎。通常在这种情况下,这是InnoDB
,这是default_storage_engine系统变量的默认值 value。禁用NO_ENGINE_SUBSTITUTION
时,如果不遵守存储引擎规范,则会发出警告。
AUTO_INCREMENT
table 的初始AUTO_INCREMENT
value。在 MySQL 5.7 中,这适用于MyISAM
,MEMORY
,InnoDB
和ARCHIVE
表。要为不支持该AUTO_INCREMENT
表选项的引擎设置第一个自动增量值,请在创建表后插入一个“ dummy ”行,其值比期望值小一,然后删除该虚拟行。
对于支持CREATE TABLE
statements 中的AUTO_INCREMENT
table 选项的引擎,您还可以使用ALTER TABLE tbl_name AUTO_INCREMENT = N
重置AUTO_INCREMENT
value。 value 不能设置为低于列中当前的最大 value。
表的平均行长的近似值。您仅需要为具有可变大小行的大型表设置此选项。
创建MyISAM
表时,MySQL使用MAX_ROWS
和 AVG_ROW_LENGTH
选项的乘积来确定结果表的大小。如果您未指定任何选项,则MyISAM
默认情况下,数据和索引文件的最大大小为256TB。(如果操作系统不支持那么大的文件,则表的大小受文件大小限制的约束。)如果要减小指针大小以使索引变小和变快,而且实际上并不需要大文件,则可以通过设置myisam_data_pointer_size
系统变量来减小默认指针大小 。
指定 table 的默认字符集。 CHARSET
是CHARACTER SET
的同义词。如果字符集 name 是DEFAULT
,则使用数据库字符集。
如果您希望MySQL维护所有行的实时校验和(即,当表更改时MySQL自动更新的校验和),请将其设置为1。这使表的更新速度稍慢,但也更容易找到损坏的表。
指定 table 的默认排序规则。
table 的 comment,最多 2048 个字符 long。
您可以使用table_option
COMMENT
子句为 table 设置InnoDB
MERGE_THRESHOLD
value。
Setting NDB_TABLE options.
在 MySQL NDB Cluster 7.5.2 及更高版本中,CREATE TABLE
或ALTER TABLE语句中的 table comment 也可用于指定一至四个NDB_TABLE
选项NOLOGGING
,READ_BACKUP
,PARTITION_BALANCE
或FULLY_REPLICATED作为
name-value 对,如果需要则用逗号分隔紧跟在开始引用的 comment 文本的字符串 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 Information Schema TABLES
表的TABLE_COMMENT列使用 。
对于NDB
表,ALTER TABLE statements 也支持此 comment 语法。请记住,与ALTER TABLE
一起使用的 table comment 将替换 table 可能具有的任何现有的 comment。
NDB
表不支持在 table comments 中设置MERGE_THRESHOLD
选项(忽略它)。
用于InnoDB
表的页面 level 压缩的压缩算法。支持的值包括Zlib
,LZ4
和None
。COMPRESSION
属性是通过透明页面压缩功能引入的
页面压缩仅受驻留在file-per-table表空间中的InnoDB
表的支持,并且仅在支持稀疏文件和打孔的Linux和Windows平台上可用。
FEDERATED
表 的连接字符串。
注意较早版本的MySQL使用
COMMENT
连接字符串选项。
DATA DIRECTORY
, INDEX DIRECTORY
对于InnoDB
,DATA DIRECTORY='directory'
子句允许在数据目录之外创建 file-per-table 表空间。表空间数据文件在指定目录中创建,该目录位于与 schema 具有相同 name 的子目录中。必须启用innodb_file_pertable变量才能使用DATA DIRECTORY
子句。必须指定完整目录路径。
在创建MyISAM
表时,可以使用DATA DIRECTORY='directory'
子句,INDEX DIRECTORY='directory'
子句或两者。它们分别指定放置MyISAM
table 的数据文件和索引文件的位置。与InnoDB
表不同,当_用DATA DIRECTORY
或INDEX DIRECTORY
选项创建MyISAM
table 时,MySQL 不会创建与数据库 name 对应的子目录。 Files 在指定的目录中创建。
从 MySQL 5.7.17 开始,您必须具有FILE
特权才能使用DATA DIRECTORY
或INDEX DIRECTORY
table 选项。
重要
对于分区表,将忽略Table-level 的
DATA DIRECTORY
和INDEX DIRECTORY
选项。错误32091)
这些选项仅在您不使用--skip-symbolic-links选项时有效。您的操作系统还必须有一个有效的 thread-safe realpath()
呼叫。
如果在没有DATA DIRECTORY
选项的情况下创建MyISAM
table,则会在数据库目录中创建.MYD
文件。
默认情况下,如果MyISAM
在这种情况下找到现有的.MYD
文件,则会覆盖它。对于没有INDEX DIRECTORY
选项创建的表,这同样适用于.MYI
files。若要禁止此行为,请使用--keepfiles_on_create选项启动服务器,在这种情况下MyISAM
将不会覆盖现有的 files 并返回错误。
如果使用DATA DIRECTORY
或INDEX DIRECTORY
选项创建MyISAM
table 并且找到现有的.MYD
或.MYI
文件,则 MyISAM 始终返回错误。它不会覆盖指定目录中的文件。
重要
您不能将包含 MySQL 数据目录的路径名用于DATA DIRECTORY
或INDEX DIRECTORY
。这包括分区表和单个 table 分区。 (见 Bug#32167.)
如果要延迟 table 的 key 更新,直到 table 关闭,请将此值设置为 1
将ENCRYPTION
选项设置为'Y'
,以便为file-per-table表空间中创建的InnoDB
table 启用 page-level 数据加密。选项值不是 case-sensitive。 ENCRYPTION
选项是在InnoDB
tablespace encryption feature 中引入的;
如果要将数据插入MERGE
table,则必须使用INSERT_METHOD
指定要插入行的 table。 INSERT_METHOD
是仅对MERGE
表有用的选项。使用FIRST
或LAST
的值将插入转到第一个或最后一个 table,或使用 value NO
来防止插入。
对于MyISAM 数据表,KEY_BLOCK_SIZE
可选地指定用于索引 key 块的大小(以字节为单位)。 value 被视为提示;如有必要,可以使用不同的尺寸。为单个索引定义指定的KEY_BLOCK_SIZE
value 会覆盖 table-level KEY_BLOCK_SIZE
value。
太多了,暂略,待补充。
CREATE TABLE
创建表时, 原始语句(包括所有规范和表选项)由MySQL存储。该信息将保留,以便在您使用ALTER TABLE
语句更改存储引擎,排序规则或其他设置时,保留指定的原始表选项。即使两个引擎支持的行格式不同,这也使您可以在InnoDB
和 MyISAM
表类型之间进行切换 。
因为保留了原始语句的文本,但是由于某些值和选项可能以静默方式重新配置(例如ROW_FORMAT
),因此,活动表定义(可通过DESCRIBE
或通过 SHOW TABLE STATUS
进行访问)和表创建字符串(可通过进行SHOW CREATE TABLE
访问)将报告不同的值。
MySQL 通过数据库目录中的.frm表格式文件
表示每个表。表的存储引擎可能还会创建其他文件。
对于在 file-per-table 表空间或通用表空间中创建的InnoDB
table,table 数据和关联索引存储在数据库目录的.ibd 文件中。在系统表空间中创建InnoDB
table 时,table 数据和索引存储在表示系统表空间的ibdata * files中。默认情况下 innodb_file_pertable选项控制是否在 file-per-table 表空间或系统表空间中创建表。TABLESPACE
选项可在 file-per-table 表空间,通用表空间或系统表空间中创建表,而不管innodb_file_pertable设置如何。
对于MyISAM
表,存储引擎会创建数据和索引 files。因此,对于每个MyISAM
table tbl_name
,有三个磁盘 files。
文件 | 目的 |
---|---|
tbl_name.frm |
Table 格式(定义)文件 |
tbl_name.MYD |
数据文件 |
tbl_name.MYI |
索引文件 |
由.frm 文件结构强加的限制
如前所述,每个 table 都有一个包含 table 定义的.frm
文件。服务器使用以下表达式检查存储在文件中的某些 table 信息,上限为 64KB
if (info_length+(ulong) create_fields.elements*FCOMP+288+
n_length+int_length+com_length > 65535L || int_count > 255)
存储在.frm
文件中的针对表达式检查的信息部分不能超过 64KB 限制,因此如果 table 定义达到此大小,则不能再添加列。
表达中的相关因素是:
info_length
是“屏幕”所需的空间。”这与MySQL的Unireg传统有关。create_fields.elements
是列数。FCOMP
是17。n_length
是所有列名的总长度,包括每个名字以 一个字节作为分隔符。int_length
与ENUM和 SET
列的值列表相关。在这个 context 中,“ int”并不意味着“integer”。它表示“间隔”,一个统称为ENUM和 SET
列的术语。int_count
是唯一ENUM和 SET
定义的数量。com_length
是列 comments 的总长度。刚才描述的表达式对允许的 table 定义有几个含义
SET
列,或使用列 comments。e1 ENUM('a','b','c')
e2 ENUM('a','b','c')
唯一ENUM和 SET
定义中元素名称长度的总和计入 64KB 限制,因此尽管给定ENUM列中元素数量的理论限制为 65,535,但实际限制小于 3000。
创建 table 时可以使用TEMPORARY
关键字。 TEMPORARY
table 仅在当前 session 中可见,并在 session 关闭时自动删除。这意味着两个不同的会话可以使用相同的临时 table name,而不会相互冲突;或者已经存在的非 TEMPORARY
具有相同的名字(在删除临时表之前,现有表一直处于隐藏状态。)。
CREATE TABLE
导致隐式提交,除非与TEMPORARY
关键字一起使用。
TEMPORARY
表与数据库(方案)的关系非常松散。删除数据库不会自动删除该数据库中创建的任何TEMPORARY
表。
此外,如果使用CREATE TABLE
语句中的数据库 name 限定 table name,则可以在不存在的数据库中创建TEMPORARY
table。在这种情况下,table 的所有后续 reference 必须使用数据库 name 限定。
要创建临时 table,您必须具有 CREATE TEMPORARY TABLES
特权。在 session 创建临时 table 之后,服务器不会对 table 执行进一步的权限检查。 creating session 可以对 table 执行任何操作,例如DROP TABLE, INSERT
,UPDATE
,或 SELECT
。
这种行为的一个暗示是,即使当前用户没有创建临时表的权限,会话也可以操纵其临时表。假设当前用户没有CREATE TEMPORARY TABLES
特权,但是能够执行定义者上下文存储过程,该存储过程以拥有CREATE TEMPORARY TABLES
并创建临时表的用户的特权执行。在执行过程时,会话将使用定义用户的特权。该过程返回后,有效特权将恢复为当前用户的特权,该用户仍可以看到临时表并对其执行任何操作。
注意
自MySQL 5.7.24起,
CREATE TEMPORARY TABLE
不再支持TABLESPACE = innodb_file_per_table
andTABLESPACE = innodb_temporary
子句,会在将来的MySQL版本中移除。
使用CREATE TABLE ... LIKE
根据另一个 table 的定义创建一个空 table,包括原始 table 中定义的所有列属性和索引:
CREATE TABLE new_tbl LIKE orig_tbl;
使用与原始表相同的表存储格式版本创建副本。原始 table 需要SELECT
特权。
LIKE
仅适用于基表,不适用于视图。
重要
当锁表语句生效时,您无法执行CREATE TABLE
或CREATE TABLE ... LIKE
。
CREATE TABLE ... LIKE
与CREATE TABLE
进行相同的检查,并不只是复制.frm
文件。这意味着如果当前 SQL 模式与创建原始 table 时生效的模式不同,则对于新模式,table 定义可能被视为无效,并且语句将失败。
对于CREATE TABLE ... LIKE
,目标 table 保留原始 table 中生成的列信息。
CREATE TABLE ... LIKE
不保留为原始表指定的任何 DATA DIRECTORY
或INDEX DIRECTORY
表选项,或任何外键定义。
如果原始 table 是TEMPORARY
table,则CREATE TABLE ... LIKE
不会保留TEMPORARY
。要创建TEMPORARY
目标 table,请使用CREATE TEMPORARY TABLE ... LIKE
。
您可以通过在 CREATE TABLE
语句末尾添加一条SELECT
语句来从另一个表创建一个表:
CREATE TABLE new_tbl [AS] SELECT * FROM orig_tbl;
MySQL 为 SELECT
中的所有元素创建新列。例如:
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (a), KEY(b))
-> ENGINE=MyISAM SELECT b,c FROM test2;
这将创建一个MyISAM
表有三列,a
,b
,和 c
。该ENGINE
选项是CREATE TABLE
语句的一部分,不应在SELECT
; 之后使用 。这将导致语法错误。其他CREATE TABLE
选项(例如CHARSET
) 也是如此 。
注意,SELECT
语句中的列 被追加到表的右侧,而不是重叠在表的右侧。请看以下示例:
mysql> SELECT * FROM foo;
+---+
| n |
+---+
| 1 |
+---+
mysql> CREATE TABLE bar (m INT) SELECT n FROM foo;
Query OK, 1 row affected (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM bar;
+------+---+
| m | n |
+------+---+
| NULL | 1 |
+------+---+
1 row in set (0.00 sec)
对于 table foo
中的每一行,在bar
中插入一行,其中包含foo
的值和新列的默认值。
由 CREATE TABLE ... SELECT
生成的表中,仅在CREATE TABLE
部分中命名的列位于第一位。在这两个部分中或只有一部分中以SELECT
命名的列会在之后出现。还可以通过指定 CREATE TABLE
部分中的列来覆盖 SELECT
列的数据类型。
如果在将数据复制到 table 时发生任何错误,则会自动删除并且不会创建。
您可以在SELECT
之前加IGNORE
或REPLACE
来指示如何处理重复的唯一键值的行。使用IGNORE
,将删除在唯一键值上重复存在的行,使用REPLACE
时,新行将替换相同唯一索引键的值。如果既未指定IGNORE
也未指定REPLACE
,则重复的唯一 key 值将导致错误。
SELECT语句表下面的行顺序始终无法确认,
因此CREATE TABLE ... IGNORE SELECT
和CREATE TABLE ... REPLACE SELECT
statements 被标记为 statement-based 复制不安全。当使用 statement-based 模式时,此类 statements 在错误 log 中产生警告,并在使用MIXED
模式时使用 row-based 格式写入二进制 log。另见第 16.2.1.1 节,“Statement-Based 和 Row-Based 复制的优点和缺点”。CREATE TABLE ... SELECT
不会自动为您创建任何索引。这样做是为了使声明尽可能灵活。如果要在创建的 table 中包含索引,则应在SELECT
语句之前指定这些索引:
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
对于CREATE TABLE ... SELECT
,目标表不会保留有关selected-from表中的列是否是生成的列的信息。语句的SELECT
部分不能为目标表中的生成列分配值。
可能会发生某些数据类型转换。例如,不保留AUTO_INCREMENT
属性,VARCHAR列变成为CHAR列。重新编排的属性是NULL
(或NOT NULL
),对于那些具有它们的列,CHARACTER SET
, COLLATION
, COMMENT
, and the DEFAULT
clause.
使用 CREATE TABLE ... SELECT
创建 table 时,请确认在查询中任何 function calls 或表达式设置的别名。如果不这样做,CREATE
语句可能会失败或导致不合需要的列名。
CREATE TABLE artists_and_works
SELECT artist.name, COUNT(work.artist_id) AS number_of_works
FROM artist LEFT JOIN work ON artist.id = work.artist_id
GROUP BY artist.id;
您还可以在创建的 table 中显式指定列的数据类型:
CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;
对于 CREATE TABLE ... SELECT
,如果给出IF NOT EXISTS
且目标 table 存在,则不会在目标 table 中插入任何内容,并且不记录该语句。
为确保二进制 log 可用于 re-create 原始表,MySQL 在 CREATE TABLE ... SELECT
.期间不允许并发插入。
您不能在 CREATE TABLE
.等语句中将new_table
SELECT ... FROM old_table
...FOR UPDATE
用作SELECT
的一部分。如果您尝试这样做,则该语句失败。
MySQL 支持外键,允许跨表交叉引用相关数据,这有助于保持这个 spread-out 数据的一致性
CREATE TABLE
or ALTER TABLE
语句中的外部 key 约束定义的基本语法如下所示:
[CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (col_name, ...)
REFERENCES tbl_name (col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
身份标识
外键约束命名受以下规则支配:
CONSTRAINT
symbol
value。CONSTRAINT
symbol
未定义该子句,或者在CONSTRAINT
关键字之后未包含符号 :InnoDB
表,将自动生成约束名称。NDB
表,使用该 FOREIGN KEY
index_name
值(如果已定义)。否则,将自动生成约束名称。CONSTRAINT
symbol
值(如果已定义)在数据库中必须唯一。重复symbol
会导致类似以下错误:错误1005(HY000):无法创建表'test.fk1'(errno:121)。 条件和限制
外键约束受以下条件和限制的约束:
REFERENCES
特权。index_name
如果给定,则如前所述使用。InnoDB
允许外键引用任何索引列或列组。但是,在引用表中,必须有一个索引,其中引用列是 相同顺序的第一列。InnoDB
还考虑了添加到索引的隐藏列 NDB
在引用为外键的任何列上都需要一个显式唯一键(或主键)。 InnoDB
不需要,这是标准SQL的扩展。
BLOB
和 TEXT
列不能包含在外键中,因为这些列上的索引必须始终包含前缀长度。InnoDB
当前不支持具有用户定义分区的表的外键。这包括父表和子表。此限制不适用于由KEY
或LINEAR KEY
(NDB
存储引擎支持的唯一用户分区类型)分区的NDB
表;它们可能具有外键引用,也可能是此类引用的目标。
Referential Actions(参照动作)
当“ UPDATE
或” DELETE
操作影响子表中具有匹配行的父表中的键值时,结果取决于使用FOREIGN KEY
子句的ON UPDATE
和ON DELETE
子句指定的引用操作。 MySQL 支持关于要采取的操作的五个选项,如下所示:
CASCADE
:删除或更新 parent table 中的行,并自动删除或更新 child table 中的匹配行。支持ON DELETE CASCADE
和ON UPDATE CASCADE
。在两个表之间,不要定义几个ON UPDATE CASCADE
子句作用于 parent table 或 child table 中的同一列。如果在外键关系中的两个表上定义FOREIGN KEY
子句,使两个表成为 parent 和 child,则必须在 order 中为另一个FOREIGN KEY
子句定义ON UPDATE CASCADE
或ON DELETE CASCADE
子句,以便成功进行级联操作。如果仅为一个FOREIGN KEY
子句定义了ON UPDATE CASCADE
或ON DELETE CASCADE
子句,则级联操作将失败并显示错误。
注意级联的外键操作不会激活触发器。
SET NULL
:删除或更新 parent table 中的行,并将 child table 中的外键列设置为NULL
。支持ON DELETE SET NULL
和ON UPDATE SET NULL
子句。如果指定SET NULL
操作,请确保未将 child table 中的列声明为NOT NULL
。RESTRICT
:拒绝 parent table 的删除或更新操作。指定RESTRICT
(或NO ACTION
)与省略ON DELETE
或ON UPDATE
子句相同。NO ACTION
:标准SQL中的关键字。在MySQL中,等效于RESTRICT
。如果引用表中有相关的外键值,则MySQL服务器会拒绝父表的删除或更新操作。某些数据库系统具有延迟检查,并且NO ACTION
是延迟检查。在MySQL中,外键约束会立即检查,因此NO ACTION
与相同RESTRICT
。SET DEFAULT
:MySQL 解析器识别此操作,但InnoDB和导航台拒绝包含ON DELETE SET DEFAULT
或ON UPDATE SET DEFAULT
子句的 table 定义。对于未指定的ON DELETE
或ON UPDATE
,默认操作始终为RESTRICT
。
对于支持外键的存储引擎,MySQL将拒绝任何INSERT
或 UPDATE
操作,如果有父表中没有匹配的候选键值试图创建一个子表的外键的值。
对于未指定的ON DELETE
或ON UPDATE
,默认操作始终为RESTRICT
。
对于NDB
表,ON UPDATE CASCADE
在引用到父表的主键的情况下不支持。
外键约束示例
这个简单的示例通过单列外键关联parent
和 child
表:
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (
id INT,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id)
REFERENCES parent(id)
ON DELETE CASCADE
) ENGINE=INNODB;
一个更复杂的 example,其中product_order
table 具有两个其他表的外键。一个外部 key 在product
table 中引用 two-column 索引。另一个_re 参见customer
table 中的 single-column 索引:
CREATE TABLE product (
category INT NOT NULL, id INT NOT NULL,
price DECIMAL,
PRIMARY KEY(category, id)
) ENGINE=INNODB;
CREATE TABLE customer (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE product_order (
no INT NOT NULL AUTO_INCREMENT,
product_category INT NOT NULL,
product_id INT NOT NULL,
customer_id INT NOT NULL,
PRIMARY KEY(no),
INDEX (product_category, product_id),
INDEX (customer_id),
FOREIGN KEY (product_category, product_id)
REFERENCES product(category, id)
ON UPDATE CASCADE ON DELETE RESTRICT,
FOREIGN KEY (customer_id)
REFERENCES customer(id)
) ENGINE=INNODB;
添加外键
您可以使用ALTER TABLE向现有 table 添加新的外键约束。此语句显示与此语句的外键相关的语法:
ALTER TABLE tbl_name
ADD [CONSTRAINT [symbol]] FOREIGN KEY
[index_name] (col_name, ...)
REFERENCES tbl_name (col_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
外部 key 可以是自引用的(指的是相同的 table)。使用ALTER TABLE向 table 添加外部 key 约束时,请记住首先创建所需的索引。
删除外键
您还可以使用ALTER TABLE删除外键,使用此处显示的语法:
ALTER TABLE tbl_name DROP FOREIGN KEY fk_symbol;
CREATE TABLESPACE tablespace_name
InnoDB and NDB:
ADD DATAFILE 'file_name'
InnoDB only:
[FILE_BLOCK_SIZE = value]
NDB only:
USE LOGFILE GROUP logfile_group
[EXTENT_SIZE [=] extent_size]
[INITIAL_SIZE [=] initial_size]
[AUTOEXTEND_SIZE [=] autoextend_size]
[MAX_SIZE [=] max_size]
[NODEGROUP [=] nodegroup_id]
[WAIT]
[COMMENT [=] 'string']
InnoDB and NDB:
[ENGINE [=] engine_name]
该语句用于创建表空间。精确的语法和语义取决于所使用的存储引擎。在标准的 MySQL 5.7 版本中,这始终是InnoDB表空间。 MySQL NDB Cluster 7.5 除了使用InnoDB
之外,还支持使用NDB
存储引擎的表空间。
InnoDB 的注意事项
CREATE TABLESPACE
语法用于创建常规表空间。常规表空间是共享表空间。它可以容纳多个表,并支持所有表行格式。可以在相对于或独立于数据目录的位置中创建常规表空间。
创建InnoDB
常规表空间后,可以使用CREATE TABLE tblname ... TABLESPACE [=] tablespacename或ALTER TABLE tblname TABLESPACE [=] tablespacename将表添加到表空间。
NDB Cluster 的注意事项
此语句用于创建表空间,该表空间可以包含一个或多个数据文件,为 NDB Cluster 磁盘数据表提供存储空间
用此语句创建一个数据文件并将其添加到表空间。可以使用ALTER TABLESPACE语句将其他数据 files 添加到表空间
注意所有NDB群集磁盘数据对象共享相同的名称空间。这意味着每个磁盘数据对象必须唯一地命名(而不仅仅是给定类型的每个磁盘数据对象)。例如,您不能具有相同名称的表空间和日志文件组,或具有相同名称的表空间和数据文件。
必须将一个或多个UNDO
log files 的 log 文件 group 分配给要使用USE LOGFILE GROUP
子句创建的表空间。 logfile_group
必须是使用CREATE LOGFILE GROUP
创建的现有 log 文件 group
设置EXTENT_SIZE
或INITIAL_SIZE
时,您可以选择使用带有 one-letter 缩写的数字作为数量级,类似于my.cnf
中使用的数字。通常,这是字母M
(兆字节)或G
(千兆字节)之一。
INITIAL_SIZE
和EXTENT_SIZE
需要四舍五入如下:
EXTENT_SIZE
向上舍入到最近的 32K 的整数倍。INITIAL_SIZE
向下舍入到最近的 32K 的整数倍;此结果向上舍入到EXTENT_SIZE
(在四舍五入后)最接近的整数倍。刚才描述的舍入是明确完成的,当执行任何这样的舍入时,MySQL 服务器会发出警告。 NDB 内核还使用舍入值来计算INFORMATIONSCHEMA.FILES列值和其他用途。但是,为避免出现意外结果,我们建议您在指定这些选项时始终使用 32K 的整数倍。
当CREATE TABLESPACE
与ENGINE [=] NDB
一起使用时,会在每个 Cluster 数据节点上创建表空间和关联的数据文件。您可以通过查询INFORMATIONSCHEMA.FILES table 验证是否已创建数据 files 并获取有关它们的信息。
选项
ADD DATAFILE
:定义表空间数据文件的名称;始终需要此选项。 InnoDB
表空间仅支持单个数据文件,其 name 必须包含.ibd
扩展名。 NDB Cluster 表空间支持多个数据文件,这些文件可以包含任何合法的文件名;通过使用ALTER TABLESPACE语句创建 NDB Cluster 表空间后,可以将更多数据 files 添加到 NDB Cluster 表空间。
注意
InnoDB
不支持ALTER TABLESPACE
。
要将数据文件放置在数据目录(datadir
)之外的位置,请包括绝对目录路径或相对于数据目录的路径。如果未指定路径,则会在数据目录中创建表空间。在数据目录之外创建InnoDB
表空间时,将在数据目录中创建ISL文件。
为避免与隐式创建的 file-per-table 表空间冲突,不支持在数据目录下的子目录中创建通用表空间。当在数据目录之外创建一般表空间时,该目录必须在创建表空间之前存在。
file_name
(包括任何指定的路径)必须使用单引号或 double 引号引用。文件名(不包括文件扩展名)和目录名的长度必须至少为一个字节。不支持零长度文件名和目录名。
FILE_BLOCK_SIZE
:此选项 - 特定于InnoDB
,并被NDB
忽略 - 定义表空间数据文件的块大小。如果FILE_BLOCK_SIZE
等于innodb_page_size value,则表空间只能包含具有未压缩行格式(COMPACT
,REDUNDANT
和DYNAMIC
)的表。具有COMPRESSED
行格式的表具有与未压缩表不同的物理页大小。因此,压缩表不能与未压缩表共存于同一表空间中。
对于包含压缩表的常规表空间,必须指定FILE_BLOCK_SIZE
,并且FILE_BLOCK_SIZE
value 必须是与innodb_page_size value 相关的有效压缩页大小。此外,压缩 table(KEY_BLOCK_SIZE
)的物理页面大小必须等于FILE_BLOCK_SIZE/1024
略
CREATE
[DEFINER = user]
TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
[trigger_order]
trigger_body
trigger_time: { BEFORE | AFTER }
trigger_event: { INSERT | UPDATE | DELETE }
trigger_order: { FOLLOWS | PRECEDES } other_trigger_name
此语句创建一个新触发器。触发器是与 table 关联的命名数据库 object,并在 table 发生特定 event 时激活。触发器与名为tbl_name
的 table 相关联,该表必须引用永久 table。您无法将触发器与TEMPORARY
table 或视图相关联。
schema 命名空间中存在触发器名称,这意味着所有触发器在 schema 中必须具有唯一的名称。不同模式中的触发器可以具有相同的 name。
创造触发器需要与触发器关联的 table 的触发特权。如果存在DEFINER
子句,则所需的权限取决于user
value,如果启用了 binary logging,则创造触发器可能需要超特权
DEFINER
子句确定在触发器激活 time 时检查访问权限时要使用的安全性 context,如本节后面所述。
trigger_time
是触发器动作 time。它可以是BEFORE
或AFTER
,表示触发器在每行要修改之前或之后激活。
基本列 value 检查在触发器激活之前发生,因此您不能使用BEFORE
触发器将不适合列类型的值转换为有效值。
trigger_event
表示激活触发器的操作类型。允许使用这些trigger_event
值:
INSERT
:每当在表中插入新行时(例如,通过INSERT
, LOAD
和DATA
REPLACE
语句), 触发器就会激活。UPDATE
语句)。DELETE
:每当从表中删除一行时(例如,通过DELETE
和 REPLACE
语句),触发器就会激活 。 DROP TABLE
和 TRUNCATE TABLE
表上的语句不会激活此触发器,因为它们未使用DELETE
。删除分区也不会激活 DELETE
触发器。trigger_event
不代表文本类型激活触发器的语句,因为它代表了一种类型的表操作的SQL语句。例如, INSERT
触发器不仅会激活INSERT
语句,还会 激活LOAD DATA
语句,因为这两个语句都会在表中插入行。
一个可能令人困惑的示例是INSERT INTO ... ON DUPLICATE KEY UPDATE ...
语法:BEFORE INSERT
触发器为每一行激活,后跟AFTER INSERT
触发器或BEFORE UPDATE
和AFTER UPDATE
触发器,具体取决于该行是否有重复的 key。
CREATE
[OR REPLACE]
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = user]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
创建视图语句创建新视图,或者在给定OR REPLACE
子句时替换现有视图。如果视图不存在,则创建或替换视图与创建视图相同。如果视图确实存在,创建或替换视图将替换它。
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name
DROP DATABASE删除数据库中的所有表并删除数据库。对此声明要非常小心!要使用DROP DATABASE,您需要数据库的DROP
特权。 DROP SCHEMA是DROP DATABASE的同义词。
DROP EVENT [IF EXISTS] event_name
此语句删除名为event_name
的 event。 event 立即停止 active,并从服务器中完全删除。
如果 event 不存在,则会出现错误 ERROR 1517(HY000):未知 event'event_name
'。您可以覆盖它并使该语句为不存在的 events 生成警告,来替代使用IF EXISTS
。
此语句需要 schema 的事件特权才能删除 event 所属的 schema。
DROP FUNCTION语句用于删除存储的函数和 user-defined 函数(UDF):
有关删除存储函数的信息,请参阅第 13.1.27 节,“DROP PROCEDURE 和 DROP FUNCTION 语法”。
有关删除 user-defined 函数的信息,请参阅第 13.7.3.2 节,“DROP FUNCTION 语法”。
DROP INDEX index_name ON tbl_name
[algorithm_option | lock_option] ...
algorithm_option:
ALGORITHM [=] {DEFAULT|INPLACE|COPY}
lock_option:
LOCK [=] {DEFAULT|NONE|SHARED|EXCLUSIVE}
DROP INDEX从 table tbl_name
中删除名为index_name
的索引。此语句映射到ALTER TABLE语句以删除索引。
要删除主 key,索引 name 始终为PRIMARY
,必须将其指定为带引号的标识符,因为PRIMARY
是保留字:
DROP INDEX `PRIMARY` ON t;
DROP LOGFILE GROUP logfile_group
ENGINE [=] engine_name
此语句删除名为logfile_group
的 log 文件 group。 log 文件 group 必须已存在或导致错误。
重要
在删除 log 文件 group 之前,必须删除使用该 log 文件 group 进行UNDO
logging 的所有表空间。
required ENGINE
子句提供了要删除的日志文件组所使用的存储引擎的名称。目前,唯一允许值 engine_name
是 NDB
和 NDBCLUSTER
。
DROP LOGFILE GROUP
仅对NDB群集的磁盘数据存储有用。请参见 第21.5.13节“ NDB群集磁盘数据表”。
DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name
此语句用于删除存储过程或 function。也就是说,从服务器中删除指定的例程。您必须具有该例程的ALTER ROUTINE
特权。
(如果启用了automatic_sp_privileges
系统变量,则在创建例程时会自动将该特权和EXECUTE
授予例程创建者,并在例程被删除时从创建者中删除。请参阅第 23.2.2 节,“存储例程和 MySQL 权限” .)
IF EXISTS
子句是 MySQL 扩展。如果过程或 function 不存在,它可以防止发生错误。生成一个可以使用 SHOW WARNINGS
查看的警告。
DROP FUNCTION也用于删除 user-defined 函数
DROP SERVER [ IF EXISTS ] server_name
删除名为server_name
的服务器的服务器定义。 mysql.servers
table 中的相应行将被删除。此语句需要 SUPER
特权。
删除 table 的服务器不会影响在创建它们时使用此连接信息的任何FEDERATED
表。
DROP SERVER
导致隐式提交。
无论正在使用的 logging 格式如何,DROP SERVER
都不会写入二进制 log。
DROP [TEMPORARY] TABLE [IF EXISTS]
tbl_name [, tbl_name] ...
[RESTRICT | CASCADE]
DROP TABLE删除一个或多个表。您必须拥有每个 table 的DROP
特权。
请谨慎使用此语句!对于每个表,它将删除表定义和所有表数据。如果表已分区,则该语句将删除表定义,其所有分区,存储在这些分区中的所有数据以及与删除的表关联的所有分区定义。
删除表也会删除该表的所有触发器。
DROP TABLE
导致隐式提交,除非与TEMPORARY
关键字一起使用。
重要删除表时,不会自动删除专门为该表授予的特权。必须手动删除它们。
如果参数列表中命名的任何表都不存在,则 DROP TABLE
行为取决于是否提供了该IF EXISTS
子句:
IF EXISTS
,则该语句将删除所有确实存在的命名表,并返回错误,指出无法删除哪些不存在的表。IF EXISTS
,对于不存在的表不会发生错误。该语句删除所有确实存在的命名表,并为每个不存在的表生成NOTE
诊断。这些注释可以用SHOW WARNINGS
显示 IF EXISTS
在有.frm
文件但没有由存储引擎管理的表异常情况下,删除表也很有用 。(例如,如果在从存储引擎中删除表之后但在.frm
文件删除之前发生了异常的服务器退出 。)
TEMPORARY
关键字具有以下效果:
该语句仅删除TEMPORARY
表。
该语句不会导致隐式提交。
没有检查访问权限。只有创建它的 session 才能看到TEMPORARY
table,因此不需要进行检查。
包含TEMPORARY
关键字是防止意外删除非TEMPORARY
表的好方法。
RESTRICT
和CASCADE
关键字不执行任何操作。允许它们从其他数据库系统中轻松移植。
所有innodb_force_recovery设置均不支持DROP TABLE。
DROP TABLESPACE tablespace_name
[ENGINE [=] engine_name]
此语句删除以前使用 CREATE TABLESPACE
创建的表空间。它支持所有 MySQL NDB Cluster 7.5 版本,以及标准 MySQL 服务器中的InnoDB
。
ENGINE使用表空间放置存储引擎,其中engine_name
是存储引擎的 name。目前,支持值InnoDB
和NDB
。如果未设置,则使用 default_storage_engine
的 value。如果它与用于创建表空间的存储引擎不同,则DROP TABLESPACE
语句将失败。
对于InnoDB
表空间,必须在DROP TABLESPACE
操作之前从表空间中删除所有表。如果表空间不为空,DROP TABLESPACE
将返回错误。
与InnoDB
系统表空间一样,截断或删除存储在通用表空间中的InnoDB
表会在表空间.ibd 数据文件中创建可用空间,该空间只能用于新的InnoDB
数据。空间不会通过 file-per-table 表空间的操作释放回操作系统。
要删除的NDB
表空间不得包含任何数据 files;换句话说,在删除NDB
表空间之前,必须先使用ALTER TABLESPACE ... DROP DATAFILE删除每个数据 files。
笔记
DROP TABLESPACE
删除表空间。DROP DATABASE
即使该操作删除了属于该表空间的所有表,在这方面也没有影响DROP DATABASE
操作可以删除属于常规表空间的表,但是即使该操作删除了属于该表空间的所有表,也不能删除该表空间。必须使用显式DROP TABLESPACE tablespace_name
删除表空间。InnoDB
数据。空间不会像 file-per-table 表空间一样释放回操作系统。InnoDB Example
本示例演示如何删除InnoDB
常规表空间。常规表空间ts1
是用单个表创建的。在删除表空间之前,必须删除表。
mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB;
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts10 Engine=InnoDB;
mysql> DROP TABLE t1;
mysql> DROP TABLESPACE ts1;
NDB Example
这个例子显示如何在首次创建表空间后删除具有名为mydata-1.dat
的数据文件的NDB
表空间myts
,并假定存在名为mylg
的 log 文件 group
mysql> CREATE TABLESPACE myts
-> ADD DATAFILE 'mydata-1.dat'
-> USE LOGFILE GROUP mylg
-> ENGINE=NDB;
您必须使用ALTER TABLESPACE从表空间中删除所有数据 files,如此处所示,然后才能删除它:
mysql> ALTER TABLESPACE myts
-> DROP DATAFILE 'mydata-1.dat'
-> ENGINE=NDB;
mysql> DROP TABLESPACE myts;
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name
此语句删除触发器。 schema(数据库)name 是可选的。如果省略 schema,则从默认的 schema 中删除触发器。 DROP TRIGGER需要与触发器关联的 table 的TRIGGER
特权。
使用IF EXISTS
可以防止不存在的触发器发生错误。使用IF EXISTS
时,会为不存在的触发器生成NOTE
如果删除 table,也会删除 table 的触发器。
DROP VIEW [IF EXISTS]
view_name [, view_name] ...
[RESTRICT | CASCADE]
DROP VIEW删除一个或多个视图。您必须拥有每个视图的DROP
权限。
如果参数列表中指定的任何视图不存在,则该语句将返回一个错误,按名称指示无法删除哪些不存在的视图,但还会删除列表中存在的所有视图。
注意在MySQL 8.0中,
DROP VIEW
如果参数列表中命名的任何视图都不存在,则失败。由于行为上的变化,DROP VIEW
当复制到MySQL 8.0从属服务器时,在MySQL 5.7主服务器上的部分完成的 操作将失败。为避免这种失败情况,请在DROP VIEW
语句中使用IF EXISTS
语法以防止不存在的视图发生错误。有关更多信息,请参见 Atomic Data Definition Statement Support。
IF EXISTS
子句可防止不存在的视图发生错误。给定此子句后,将为每个不存在的视图生成一个 NOTE
。
RESTRICT
和CASCADE
(如果提供)将被解析并忽略。
RENAME TABLE
tbl_name TO new_tbl_name
[, tbl_name2 TO new_tbl_name2] ...
RENAME TABLE
重命名一个或多个表。您必须具有ALTER
与 DROP
原始表的权限,以及CREATE
与 INSERT
新表的权限。
例如,要将名为old_table
的 table 重命名为new_table
,用这个语句:
RENAME TABLE old_table TO new_table;
该语句等同于以下ALTER TABLE语句:
ALTER TABLE old_table RENAME new_table;
与ALTER TABLE不同,RENAME TABLE
可以在一个语句中重命名多个表:
RENAME TABLE old_table1 TO new_table1,
old_table2 TO new_table2,
old_table3 TO new_table3;
重命名操作从左到右执行。因此,要交换两个 table 名称,请执行此操作(假设中间 name tmp_table
的 table 尚不存在):
RENAME TABLE old_table TO tmp_table,
new_table TO old_table,
tmp_table TO new_table;
表上的元数据锁是按名称顺序获取的,在某些情况下,当多个事务同时执行时,操作结果可能会有所不同。
要执行RENAME TABLE
,必须没有活动的事务或用LOCK TABLES
锁定的表。满足事务表锁定条件后,重命名操作将自动完成;重命名过程中,没有其他会话可以访问任何表。
如果在RENAME TABLE
期间发生任何错误,则语句将失败并且不会进行任何更改。
您可以使用RENAME TABLE
将 table 从一个数据库移动到另一个数据库:
RENAME TABLE current_db.tbl_name TO other_db.tbl_name;
使用此方法实际上将所有表从一个数据库移动到另一个数据库,这实际上重命名了该数据库(MySQL没有单一语句去执行这种操作),只是原始数据库继续存在(尽管没有表)。
像一样RENAME TABLE
,ALTER TABLE ... RENAME
也可以用于将表移动到其他数据库。无论使用哪种语句,如果重命名操作会将表移动到位于不同文件系统上的数据库,则结果的成功是特定于平台的,并且取决于用于移动表文件的基础操作系统调用。
如果表具有触发器,则尝试将表重命名为其他数据库失败,并会出现“模式错误 (ER_TRG_IN_WRONG_SCHEMA
)触发”错误。
要重命名TEMPORARY
表,RENAME TABLE
将不起作用。使用ALTER TABLE
代替。
RENAME TABLE
适用于视图,但不能将视图重命名为其他数据库中。
专门为重命名的表或视图授予的任何特权都不会迁移到新名称。必须手动更改它们。
RENAME TABLE
改变了以字符串内部生成的外键约束名称和用户定义的外键约束的名字 “ tbl_name
TO new_tbl_name
tbl_name
_ibfk_ ”,以反映新表名。InnoDB
将以字符串“ tbl_name
_ibfk_ ”开头的外键约束名称解释 为内部生成的名称。
除非存在冲突,否则指向重命名表的外键约束名称将自动更新,在这种情况下,语句将失败并显示错误。
如果重命名的约束名称已经存在,则会发生冲突。在这种情况下,必须删除并重新创建外键才能使其正常运行。
TRUNCATE [TABLE] tbl_name
TRUNCATE TABLE
完全清空一张表。它需要DROP
特权。
从逻辑上讲,TRUNCATE TABLE
它类似于DELETE
删除所有行的语句或DROP TABLE
and CREATE TABLE
语句的序列。为了获得高性能,它绕过了删除数据的DML方法。因此,它不能回滚,它不会导致ON DELETE
触发器触发,也不能对InnoDB
具有父子外键关系的表执行。
虽然TRUNCATE TABLE类似于DELETE
,但它被归类为 DDL 语句而不是 DML 语句。它在以下方面与 DELETE
不同:
InnoDB
table和 NDB
table,如果有任何其他表的外键约束来引用此表,则TRUNCATE TABLE
会失败,允许使用相同 table 的列之间的外键约束。tbl_name
.frm
有效,就可以使用TRUNCATE TABLE
将该表重新创建为空表 ,即使数据或索引文件已损坏。AUTO_INCREMENT
值都将重置为其初始值。即使对于MyISAM
和InnoDB
,也是如此,它们通常不重用序列值。TRUNCATE TABLE
保留分区;也就是说,数据和索引文件已删除并重新创建,而分区定义(.par
)文件不受影响。TRUNCATE TABLE
语句不调用ON DELETE
触发器。对于表的TRUNCATE TABLE,会关闭所有用
HANDLER OPEN
.打开的表的操作,
TRUNCATE TABLE的先删除
DROP TABLE后创建
CREATE TABLE
对于二进制日志记录和复制是有价值的,即 DDL 而不是 DML。这是由于以下事实:在使用 InnoDB或
其他事务存储引擎时,事务隔离级别不允许基于语句的日志记录(READ COMMITTED
或READ UNCOMMITTED
),在使用STATEMENT
或 MIXED
日志记录模式时未记录和复制该语句。(缺陷号36763)但是,它仍然以前面描述的方式应用于使用InnoDB的复制从机。
在具有大InnoDB
缓冲池并已 innodb_adaptive_hash_index
启用的系统上,由于当删除InnoDB表的自适应hash索引项会发生LRU扫描,TRUNCATE TABLE操作可能会使系统性能暂时下降
。该问题对于 DROP TABLE
在MySQL 5.5.23中已解决(错误#13704145,错误#64284),但仍然是TRUNCATE TABLE
(错误#68184)的已知问题 。
TRUNCATE TABLE可以与 Performance Schema 汇总表一起使用,但效果是将汇总列重置为 0 或NULL
,而不是删除行。