“MySQL 语句:数据定义语句(DDL)”的版本间差异
第230行: | 第230行: | ||
=== CREATE EVENT 语句 === | === CREATE EVENT 语句 === | ||
<syntaxhighlight lang="xml"> | <syntaxhighlight lang="xml"> | ||
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} | |||
</syntaxhighlight> | |||
该语句创建并安排新事件。 | |||
* 除非启用了事件计划程序,否则事件将不会运行。 | |||
* 要求具有在其中创建事件的架构的“EVENT”权限。 | |||
*: 如果存在“DEFINER”子句,则所需的权限取决于“user”值。 | |||
有效的“CREATE EVENT”语句的最低要求如下: | |||
# 关键字“CREATE EVENT”加上'''事件名称''',该名称在数据库架构中唯一标识事件。 | |||
# “ON SCHEDULE”子句,用于确定事件的'''执行时间和频率'''。 | |||
# “DO”子句,其中包含要由'''事件执行'''的 SQL 语句。 | |||
示例: | |||
<syntaxhighlight lang="xml"> | |||
CREATE EVENT myevent | |||
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR | |||
DO | |||
UPDATE myschema.mytable SET mycol = mycol + 1; | |||
</syntaxhighlight> | |||
“'''event_name'''”:事件名称必须是有效的 MySQL 标识符,最大长度为 64 个字符,'''不区分大小写'''。通常,控制事件名称的规则与存储例程名称的规则相同。 | |||
* '''事件与模式(数据库)关联'''。如果没有模式指示为“event_name”的一部分,则假定为默认(当前)模式。 | |||
*: 要在特定架构中创建事件,请使用“schema_name.event_name”语法用架构限定事件名称。 | |||
“'''DEFINER'''”子句:指定在事件执行时检查访问权限时要使用的 MySQL 帐户。 | |||
# 如果存在“DEFINER”子句,则“user”值应为指定为:“'user_name'@'host_name'”、“CURRENT_USER”或“CURRENT_USER()”的 MySQL 帐户。 | |||
# 如果省略“DEFINER”子句,则默认定义器是执行“CREATE EVENT”语句的用户。这与显式指定“DEFINER = CURRENT_USER”相同。 | |||
* 在事件主体内,“CURRENT_USER”函数返回用于在事件执行时检查权限的帐户,该帐户是“DEFINER”用户。 | |||
“'''ON SCHEDULE'''”子句:确定为事件定义的“event_body”重复的时间,频率和持续时间。此子句采用以下两种形式之一: | |||
# “'''AT timestamp'''”用于'''一次性事件'''。它指定事件仅在“timestamp”给定的日期和时间执行一次,该时间必须同时包括日期和时间,或者必须是可解析为“datetime”值的表达式。为此,您可以使用“DATETIME”或“TIMESTAMP”类型的值。 | |||
#*: 如果日期是过去的日期,则会发生警告,如下所示: | |||
#*: <syntaxhighlight lang="xml"> | |||
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. | |||
</syntaxhighlight> | </syntaxhighlight> | ||
#* 可以使用“CURRENT_TIMESTAMP”指定当前日期和时间。在这种情况下,事件在创建后立即起作用。 | |||
#* 要创建相对于当前日期和时间在将来某个时间发生的事件,可以使用可选的子句“+ INTERVAL interval”。(也可以使用多个间隔表示,或合并间隔) | |||
#*: 例如,“AT CURRENT_TIMESTAMP + INTERVAL 3 WEEK + INTERVAL 2 DAY”等效于“从现在起三周零两天”。该子句的每个部分都必须以+ INTERVAL开头。 | |||
# “'''EVERY interval'''”子句用于'''定期重复执行操作'''。“EVERY”关键字后跟“interval”。(“+ INTERVAL”不能与“EVERY”一起使用) | |||
#: 例如,“EVERY 6 WEEK”表示“每六个星期”。 | |||
## “EVERY”子句包含可选的“'''STARTS'''”子句,后跟一个“timestamp”值,该值指示何时应开始重复该操作,并且还可以使用“+ INTERVAL interval”指定“从现在开始”的时间。 | |||
##: 例如,“EVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEK”表示“每三个月,从现在开始的一个星期开始”。 | |||
##* 未指定“STARTS”与使用“STARTS CURRENT_TIMESTAMP”相同。也就是说,为事件指定的操作在创建事件后立即开始重复。 | |||
## “EVERY”子句包含可选的“'''ENDS'''”子句。后跟一个“timestamp”值,该值指示何时应停止重复事件,并且还可以将“+ INTERVAL interval”与“ENDS”结合使用。 | |||
##: 例如“EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK”等价于“每 12 个小时,从 30 分钟后开始,到 4 周后结束”。 | |||
##* 不使用“ENDS”意味着事件将无限期 continue 执行。 | |||
* 如果重复事件未在其调度间隔内终止,则结果可能是事件的多个实例同时执行。如果这是不希望的,则应构建一种机制来防止同时发生实例。例如,您可以使用“GET_LOCK()”函数、行或表锁定。 | |||
* “ON SCHEDULE”子句可以使用涉及内置 MySQL 函数和用户变量的表达式来获取其中包含的“timestamp”或“interval”值中的任何一个。您不得在此类表达式中使用存储的函数或用户定义的函数,也不得使用任何表引用。但是,您可以使用“SELECT FROM DUAL”。【???】 | |||
* “ON SCHEDULE”子句中的时间使用当前会话“time_zone”值进行解释。这成为事件时区;也就是说,用于事件调度的时区,在事件执行时有效。这些时间将转换为 UTC,并与事件时区一起存储在“mysql.event”表中。这使得事件执行可以按定义进行,而不管服务器时区的任何后续更改或夏令时影响如何。【与时区无关】 | |||
“'''ON COMPLETION [NOT] PRESERVE'''”子句:通常,一旦事件过期,它将立即被丢弃。您可以通过指定“ON COMPLETION PRESERVE”来覆盖此行为。使用“ON COMPLETION NOT PRESERVE”只会使默认的非持久行为明确。 | |||
“'''ENABLE | DISABLE | DISABLE ON SLAVE'''”子句:指示实现状态“启用”、“停用”、“从属服务器上的事件状态:启用|停用” | |||
“'''DO'''”子句指定事件所执行的操作,并包含一个 SQL 语句。(几乎可以在存储例程中使用的任何有效 MySQL 语句也可以用作计划事件的操作语句) | |||
* 创建或更改事件时,MySQL 存储有效的“sql_mode”系统变量设置,并始终在有效的情况下执行该事件,而与事件开始执行时当前的服务器 SQL 模式无关。【???】 | |||
* “DO”子句中包含“ALTER EVENT”语句的“CREATE EVENT”语句似乎成功;但是,当服务器尝试执行生成的计划事件时,执行失败并显示错误。 | |||
# 与存储例程一样,可以通过使用“'''BEGIN'''”和“'''END'''”关键字在“DO”子句中使用'''复合语句语法''',如下所示: | |||
#: <syntaxhighlight lang="xml"> | |||
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 ; | |||
</syntaxhighlight> | |||
#: 本示例使用“delimiter”命令更改语句定界符。【????????????????】 | |||
# 事件中可能会出现更复杂的复合语句,例如存储例程中使用的复合语句。此示例使用'''局部变量,错误处理程序和流控制构造''': | |||
#: <syntaxhighlight lang="xml"> | |||
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 ; | |||
</syntaxhighlight> | |||
# 无法将参数直接传递给事件或从事件传递参数。但是,可以在事件中使用参数调用存储的例程: | |||
#: <syntaxhighlight lang="xml"> | |||
CREATE EVENT e_call_myproc | |||
ON SCHEDULE | |||
AT CURRENT_TIMESTAMP + INTERVAL 1 DAY | |||
DO CALL myproc(5, 27); | |||
</syntaxhighlight> | |||
* 如果事件的定义者具有足以设置全局系统变量的权限,则该事件可以读取和写入全局变量。由于授予此类特权可能会导致滥用行为,因此必须格外小心。 | |||
* 通常,在存储的例程中有效的任何语句都可以用于事件执行的动作语句。。您可以将事件创建为存储例程的一部分,但是另一个事件不能创建一个事件。 | |||
=== CREATE FUNCTION 语句 === | === CREATE FUNCTION 语句 === |
2021年4月6日 (二) 03:52的版本
ALTER 语句
ALTER DATABASE 语句
ALTER {DATABASE | SCHEMA} [db_name]
alter_option ...
ALTER {DATABASE | SCHEMA} db_name
UPGRADE DATA DIRECTORY NAME
alter_option: {
[DEFAULT] CHARACTER SET [=] charset_name
| [DEFAULT] COLLATE [=] collation_name
}
“ALTER DATABASE”可以更改数据库的总体 Feature。这些 Feature 存储在数据库目录的“db.opt”文件中。
- 该语句要求对数据库具有“ALTER”权限。
- “ALTER SCHEMA”是“ALTER DATABASE”的同义词。
从 MySQL 5.1 之前的版本升级
包含“UPGRADE DATA DIRECTORY NAME”子句的语法更新了与数据库关联的目录的名称,以使用 MySQL 5.1 中实现的编码将数据库名称映射到数据库目录名称。本条款在以下条件下使用:
- 它旨在将 MySQL 从较早版本升级到 5.1 或更高版本。
- 如果名称中包含需要编码的特殊字符,则打算将数据库目录名称更新为当前的编码格式。
- 该语句由“mysqlcheck”使用(由“mysql_upgrade”调用)。
例如,如果 MySQL 5.0 中的数据库名称为“a-b-c”,则该名称包含“-”(破折号)字符的实例。在 MySQL 5.0 中,数据库目录也命名为“a-b-c”,它不一定对所有文件系统都是安全的。在 MySQL 5.1 和更高版本中,相同的数据库名称被编码为“a@002db@002dc”,以产生文件系统无关的目录名称。
示例:
当 MySQL 安装从旧版本升级到 MySQL 5.1 或更高版本时,服务器将诸如“a-b-c”(采用旧格式)的名称显示为“#mysql50#a-b-c”,并且您必须使用“#mysql50#”前缀来引用该名称。在这种情况下,请使用“UPGRADE DATA DIRECTORY NAME”明确告诉服务器将数据库目录名称重新编码为当前编码格式:
ALTER DATABASE `#mysql50#a-b-c` UPGRADE DATA DIRECTORY NAME;
执行此语句后,您可以将数据库命名为“a-b-c”,而没有特殊的“#mysql50#”前缀。
- “UPGRADE DATA DIRECTORY NAME”子句在 MySQL 5.7 中已弃用,在 MySQL 8.0 中已删除。
- 如果需要转换 MySQL 5.0 数据库或表名,一种解决方法是在升级到 MySQL 8.0 之前将 MySQL 5.0 安装升级到 MySQL 5.1.
ALTER EVENT 语句
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”语句更改了现有事件的一个或多个 Feature,而无需删除并重新创建它。
- “DEFINER”,“ON SCHEDULE”,“ON COMPLETION”,“COMMENT”,“ENABLE/DISABLE”和“DO”子句的语法与其用于“CREATE EVENT”的语法完全相同。
- 任何用户都可以更改在该用户具有“EVENT”权限的数据库上定义的事件。当用户执行成功的“ALTER EVENT”语句时,该用户将成为受影响事件的定义者。
示例:
禁用EVENT“myevent”:
ALTER EVENT myevent
DISABLE;
- “ON SCHEDULE”子句可以使用涉及内置 MySQL 函数和用户变量的表达式来获取其中包含的“timestamp”或“interval”值中的任何一个。您不能在此类表达式中使用存储的例程或用户定义的函数,也不能使用任何表引用。但是,您可以使用“SELECT FROM DUAL”。 【“ALTER EVENT”和“CREATE EVENT”语句均是如此】
- 尽管在“DO”子句中包含另一个“ALTER EVENT”语句的“ALTER EVENT”语句似乎成功,但是当服务器尝试执行生成的计划事件时,执行失败并显示错误。【即,不能嵌套】
- 没有“RENAME EVENT”语句。【而应使用“ALTER EVENT”语句的“RENAME TO”子句】
- 还可以使用“ALTER EVENT ... RENAME TO ...”和“db_name.event_name”表示法将事件移动到其他数据库,如下所示:
ALTER EVENT olddb.myevent RENAME TO newdb.myevent;
- 还可以使用“ALTER EVENT ... RENAME TO ...”和“db_name.event_name”表示法将事件移动到其他数据库,如下所示:
- 在复制从属服务器上使用“DISABLE ON SLAVE”(而不是“ENABLE”或“DISABLE”)来指示那些“在主服务器上创建并复制到从属服务器的”但“未在从属服务器上执行的”EVENT。
ALTER FUNCTION 语句
ALTER FUNCTION func_name [characteristic ...]
characteristic: {
COMMENT 'string'
| LANGUAGE SQL
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
}
该语句可用于更改存储函数的 Feature。
- “ALTER FUNCTION”语句中可以指定多个更改。但是,不能使用此语句更改参数或存储函数的主体。【类似于“ALTER PROCEDURE”语句】
- 要进行此类更改,必须使用“DROP FUNCTION”和“CREATE FUNCTION”删除并重新创建该函数。
- 必须具有该功能的“ALTER ROUTINE”特权【???】(该特权会自动授予函数创建者)。
- 如果启用了二进制日志记录,则“ALTER FUNCTION”语句可能还需要“SUPER”特权【???】。
ALTER INSTANCE 语句【???】
ALTER INSTANCE ROTATE INNODB MASTER KEY
“ALTER INSTANCE”语句,【MySQL 5.7.11 中引入】,定义了适用于 MySQL 服务器实例的操作。此操作将旋转(即“ROTATE”)用于 InnoDB 表空间加密的主加密密钥。
- 密钥轮换需要“SUPER”权限。要执行此操作,必须安装并配置密钥环插件。
- “ALTER INSTANCE ROTATE INNODB MASTER KEY”支持并发 DML。但是,它不能与“CREATE TABLE ... ENCRYPTION”或“ALTER TABLE ... ENCRYPTION”操作同时运行,并且会采取锁定措施来防止由于同时执行这些语句而引起的冲突。如果其中一个冲突的语句正在运行,则必须先完成该语句,然后才能 continue 执行。
- “ALTER INSTANCE”操作被写入二进制日志,以便可以在复制的服务器上执行它们。
ALTER LOGFILE GROUP 语句【???和 NDB 群集有关】
ALTER LOGFILE GROUP logfile_group
ADD UNDOFILE 'file_name'
[INITIAL_SIZE [=] size]
[WAIT]
ENGINE [=] engine_name
该语句将名为“file_name ”的 UNDO文件【?】 添加到现有日志文件组“logfile_group”中。
- “ALTER LOGFILE GROUP”语句只有一个“ADD UNDOFILE”子句。当前不支持“DROP UNDOFILE”子句。
- “ALTER LOGFILE GROUP”仅对 NDB 群集的磁盘数据存储有用。
【。。。略】
【???和 NDB 群集有关】
ALTER PROCEDURE 语句
ALTER PROCEDURE proc_name [characteristic ...]
characteristic: {
COMMENT 'string'
| LANGUAGE SQL
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
}
该语句可用于更改存储过程的 Feature。
- “ALTER PROCEDURE”语句中可以指定多个更改。但是,您不能使用此语句更改参数或存储过程的主体。【类似于“ALTER FUNCTION”语句】
- 要进行此类更改,必须使用“DROP PROCEDURE”和“CREATE PROCEDURE”删除并重新创建该过程。
- 您必须具有该过程的“ALTER ROUTINE”权限【???】(默认情况下,该特权自动授予过程创建者)。
- 可以通过禁用“automatic_sp_privileges”系统变量来更改此行为。
ALTER SERVER 语句
ALTER SERVER server_name
OPTIONS (option [, option] ...)
更改 server_name 的服务器信息,并调整“CREATE SERVER”语句中允许的任何选项。【“mysql.servers”表中的相应字段将相应更新】
- 此语句需要“SUPER”权限。【???】
- 不管使用哪种日志记录格式,都不会将“ALTER SERVER”写入二进制日志。
ALTER TABLE 语句
【见:“MySQL 语句:数据定义语句(DDL):“ALTER TABLE”语句”】
ALTER TABLESPACE 语句【???和 NDB 群集有关】
ALTER TABLESPACE tablespace_name
{ADD | DROP} DATAFILE 'file_name'
[INITIAL_SIZE [=] size]
[WAIT]
ENGINE [=] engine_name
该语句用于添加新数据文件或从表空间删除数据文件。
- “ADD DATAFILE”变体使您可以使用“INITIAL_SIZE”子句指定初始大小:
- 其中 size 以字节为单位;【默认值为 134217728(128 MB)】
- 可以在 size 之后加上一个字母的缩写表示数量级。【通常使用字母:M(兆字节)或G(千兆字节)之一】
- 【在 32 位系统上,INITIAL_SIZE 的最大支持值为 4294967296(4 GB)】
- 一旦创建了数据文件,就无法更改其大小。但是,您可以使用其他“ALTER TABLESPACE ... ADD DATAFILE”语句将更多数据文件添加到表空间。
- “ALTER TABLESPACE ... DROP DATAFILE”用于从表空间中删除数据文件,但不能从表空间中删除“正在被任何表使用的”数据文件。【即,数据文件必须为空】
- “ALTER TABLESPACE ... ADD DATAFILE”和“ALTER TABLESPACE ... DROP DATAFILE”都需要一个“ENGINE”子句,该子句指定表空间使用的存储引擎。
- 当前,engine_name 唯一可接受的值为 NDB 和 NDBCLUSTER。
当“ALTER TABLESPACE ... ADD DATAFILE”与“ENGINE = NDB”一起使用时,将在每个 Cluster 数据节点上创建一个数据文件。您可以通过查询“INFORMATION_SCHEMA.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)
- “WAIT”语句在 MySQL 5.7 中没有效果,而是在将来扩展使用。
- “ALTER TABLESPACE”仅对 NDB 群集的磁盘数据存储有用。
- 【所有 NDB 群集磁盘数据对象共享相同的名称空间。这意味着“每个磁盘数据对象”必须被唯一命名(而不仅仅是给定类型的每个磁盘数据对象)。例如,不能有一个具有相同名称的表空间和一个数据文件,或具有相同名称的撤消日志文件和一个表空间。】
【???和 NDB 群集有关】
ALTER VIEW 语句
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 语句
CREATE DATABASE 语句
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
[create_option] ...
create_option: {
[DEFAULT] CHARACTER SET [=] charset_name
| [DEFAULT] COLLATE [=] collation_name
}
使用给定名称创建一个数据库。
- 需要数据库的“CREATE”权限。
- “CREATE SCHEMA”是“CREATE DATABASE”的同义词。
- 也可以使用 mysqladmin 程序创建数据库。
Note:
- 如果数据库存在并且您未指定“IF NOT EXISTS”,则会发生错误。
- 具有有效“LOCK TABLES”语句的会话不允许“CREATE DATABASE”。【???】
- 每个“create_option”指定一个数据库 Feature。数据库 Feature 存储在数据库目录的“db.opt”文件中。
- “CHARACTER SET”选项指定默认的数据库字符集。“COLLATE”选项指定默认的数据库排序规则。
- MySQL 中的数据库被实现为包含与数据库表相对应的文件的目录。
- 如果您在数据目录下手动创建目录(例如,使用“mkdir”),则服务器会将其视为数据库目录,并显示在“SHOW DATABASES”的输出中:
- 创建数据库时,让服务器 Management 目录及其中的文件。直接操作数据库目录和文件可能会导致不一致和意外结果。
- MySQL 对数据库的数量没有限制。基础文件系统可能对目录数有限制。
CREATE EVENT 语句
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}
该语句创建并安排新事件。
- 除非启用了事件计划程序,否则事件将不会运行。
- 要求具有在其中创建事件的架构的“EVENT”权限。
- 如果存在“DEFINER”子句,则所需的权限取决于“user”值。
有效的“CREATE EVENT”语句的最低要求如下:
- 关键字“CREATE EVENT”加上事件名称,该名称在数据库架构中唯一标识事件。
- “ON SCHEDULE”子句,用于确定事件的执行时间和频率。
- “DO”子句,其中包含要由事件执行的 SQL 语句。
示例:
CREATE EVENT myevent
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
UPDATE myschema.mytable SET mycol = mycol + 1;
“event_name”:事件名称必须是有效的 MySQL 标识符,最大长度为 64 个字符,不区分大小写。通常,控制事件名称的规则与存储例程名称的规则相同。
- 事件与模式(数据库)关联。如果没有模式指示为“event_name”的一部分,则假定为默认(当前)模式。
- 要在特定架构中创建事件,请使用“schema_name.event_name”语法用架构限定事件名称。
“DEFINER”子句:指定在事件执行时检查访问权限时要使用的 MySQL 帐户。
- 如果存在“DEFINER”子句,则“user”值应为指定为:“'user_name'@'host_name'”、“CURRENT_USER”或“CURRENT_USER()”的 MySQL 帐户。
- 如果省略“DEFINER”子句,则默认定义器是执行“CREATE EVENT”语句的用户。这与显式指定“DEFINER = CURRENT_USER”相同。
- 在事件主体内,“CURRENT_USER”函数返回用于在事件执行时检查权限的帐户,该帐户是“DEFINER”用户。
“ON SCHEDULE”子句:确定为事件定义的“event_body”重复的时间,频率和持续时间。此子句采用以下两种形式之一:
- “AT timestamp”用于一次性事件。它指定事件仅在“timestamp”给定的日期和时间执行一次,该时间必须同时包括日期和时间,或者必须是可解析为“datetime”值的表达式。为此,您可以使用“DATETIME”或“TIMESTAMP”类型的值。
- 如果日期是过去的日期,则会发生警告,如下所示:
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.
- 可以使用“CURRENT_TIMESTAMP”指定当前日期和时间。在这种情况下,事件在创建后立即起作用。
- 要创建相对于当前日期和时间在将来某个时间发生的事件,可以使用可选的子句“+ INTERVAL interval”。(也可以使用多个间隔表示,或合并间隔)
- 例如,“AT CURRENT_TIMESTAMP + INTERVAL 3 WEEK + INTERVAL 2 DAY”等效于“从现在起三周零两天”。该子句的每个部分都必须以+ INTERVAL开头。
- “EVERY interval”子句用于定期重复执行操作。“EVERY”关键字后跟“interval”。(“+ INTERVAL”不能与“EVERY”一起使用)
- 例如,“EVERY 6 WEEK”表示“每六个星期”。
- “EVERY”子句包含可选的“STARTS”子句,后跟一个“timestamp”值,该值指示何时应开始重复该操作,并且还可以使用“+ INTERVAL interval”指定“从现在开始”的时间。
- 例如,“EVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEK”表示“每三个月,从现在开始的一个星期开始”。
- 未指定“STARTS”与使用“STARTS CURRENT_TIMESTAMP”相同。也就是说,为事件指定的操作在创建事件后立即开始重复。
- “EVERY”子句包含可选的“ENDS”子句。后跟一个“timestamp”值,该值指示何时应停止重复事件,并且还可以将“+ INTERVAL interval”与“ENDS”结合使用。
- 例如“EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK”等价于“每 12 个小时,从 30 分钟后开始,到 4 周后结束”。
- 不使用“ENDS”意味着事件将无限期 continue 执行。
- 如果重复事件未在其调度间隔内终止,则结果可能是事件的多个实例同时执行。如果这是不希望的,则应构建一种机制来防止同时发生实例。例如,您可以使用“GET_LOCK()”函数、行或表锁定。
- “ON SCHEDULE”子句可以使用涉及内置 MySQL 函数和用户变量的表达式来获取其中包含的“timestamp”或“interval”值中的任何一个。您不得在此类表达式中使用存储的函数或用户定义的函数,也不得使用任何表引用。但是,您可以使用“SELECT FROM DUAL”。【???】
- “ON SCHEDULE”子句中的时间使用当前会话“time_zone”值进行解释。这成为事件时区;也就是说,用于事件调度的时区,在事件执行时有效。这些时间将转换为 UTC,并与事件时区一起存储在“mysql.event”表中。这使得事件执行可以按定义进行,而不管服务器时区的任何后续更改或夏令时影响如何。【与时区无关】
“ON COMPLETION [NOT] PRESERVE”子句:通常,一旦事件过期,它将立即被丢弃。您可以通过指定“ON COMPLETION PRESERVE”来覆盖此行为。使用“ON COMPLETION NOT PRESERVE”只会使默认的非持久行为明确。
“ENABLE | DISABLE | DISABLE ON SLAVE”子句:指示实现状态“启用”、“停用”、“从属服务器上的事件状态:启用|停用”
“DO”子句指定事件所执行的操作,并包含一个 SQL 语句。(几乎可以在存储例程中使用的任何有效 MySQL 语句也可以用作计划事件的操作语句)
- 创建或更改事件时,MySQL 存储有效的“sql_mode”系统变量设置,并始终在有效的情况下执行该事件,而与事件开始执行时当前的服务器 SQL 模式无关。【???】
- “DO”子句中包含“ALTER EVENT”语句的“CREATE EVENT”语句似乎成功;但是,当服务器尝试执行生成的计划事件时,执行失败并显示错误。
- 与存储例程一样,可以通过使用“BEGIN”和“END”关键字在“DO”子句中使用复合语句语法,如下所示:
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”命令更改语句定界符。【????????????????】
- 事件中可能会出现更复杂的复合语句,例如存储例程中使用的复合语句。此示例使用局部变量,错误处理程序和流控制构造:
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);
- 如果事件的定义者具有足以设置全局系统变量的权限,则该事件可以读取和写入全局变量。由于授予此类特权可能会导致滥用行为,因此必须格外小心。
- 通常,在存储的例程中有效的任何语句都可以用于事件执行的动作语句。。您可以将事件创建为存储例程的一部分,但是另一个事件不能创建一个事件。
CREATE FUNCTION 语句
CREATE INDEX 语句
CREATE LOGFILE GROUP 语句
CREATE PROCEDURE 和 CREATE FUNCTION 语句
CREATE SERVER 语句
CREATE TABLE 语句
CREATE TABLESPACE 语句
CREATE TRIGGER 语句
CREATE VIEW 语句
DROP 语句
DROP DATABASE 语句
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name
DROP DATABASE 将删除数据库中的所有表并删除数据库。
- 要使用“DROP DATABASE”,需要对数据库具有“DROP”权限。
- “DROP SCHEMA”是“DROP DATABASE”的同义词。
- 删除数据库后,不会自动删除专门为该数据库授予的特权。必须手动删除它们。
- 您也可以使用 mysqladmin 删除数据库。
Note:
- “IF EXISTS”用于防止数据库不存在时发生错误。
- 如果删除了默认数据库,则未设置默认数据库(“DATABASE()”函数将返回“NULL”)。
- 如果在符号链接的数据库上使用“DROP DATABASE”,则链接和原始数据库都将被删除。
- DROP DATABASE 返回已删除的 table 数。这对应于已删除的“.frm”文件的数量。
DROP DATABASE 语句从给定的数据库目录中删除 MySQL 本身在正常操作期间可能创建的那些文件和目录:
- 所有具有以下 extensions 的文件:
.BAK .DAT .HSH .MRG .MYD .MYI .TRG .TRN .cfg .db .frm .ibd .ndb .par
- “db.opt”文件(如果存在)。
如果在 MySQL 删除上述的文件或目录后,其他文件或目录仍保留在数据库目录中,则无法删除数据库目录。在这种情况下,您必须手动删除所有剩余的文件或目录,然后再次发出“DROP DATABASE”语句。
删除数据库不会删除该数据库中创建的任何“TEMPORARY”表。【“TEMPORARY”表在创建它们的会话结束时自动删除】
DROP EVENT 语句
DROP EVENT [IF EXISTS] event_name
该语句删除名为“event_name”的事件。该事件立即停止活动,并已从服务器中完全删除。
如果事件不存在,则会发生错误“ERROR 1517(HY000): Unknown event ' event_name '”。您可以不使用“IF EXISTS”而是覆盖它,使该语句针对不存在的事件生成警告。【?】
- 此语句要求要删除的事件所属的架构具有“EVENT”权限。
DROP INDEX 语句
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 从表中删除索引。该语句映射到“ALTER TABLE”语句以删除索引。
要删除主键,则必须将索引名称(始终为“PRIMARY”)指定为带引号的标识符,因为“PRIMARY”是保留字:
DROP INDEX `PRIMARY` ON t;
NDB 表的可变宽度列上的索引被联机删除;也就是说,没有任何 table 复制。尽管该 table 在操作期间未针对相同 API 节点上的其他操作进行锁定,但仍未针对其他 NDB Cluster API 节点的访问锁定该 table。只要服务器确定有可能这样做,服务器就会自动完成此操作。您不必使用任何特殊的 SQL 语法或服务器选项即可使其发生。【???】
可以提供“ALGORITHM”(算法?)和“LOCK”子句以影响 table 复制方法以及在修改 table 索引时用于读写 table 的并发级别。它们的含义与“ALTER TABLE”语句的含义相同。
NDB Cluster 以前使用“ONLINE”和“OFFLINE”关键字支持联机“DROP INDEX”操作。这些关键字在 MySQL NDB Cluster 7.5 和更高版本中不再受支持,它们的使用会导致语法错误。
- 相反,MySQL NDB Cluster 7.5 和更高版本使用与标准 MySQL Server 相同的“ALGORITHM=INPLACE”语法支持联机操作。
DROP LOGFILE GROUP 语句
DROP LOGFILE GROUP logfile_group
ENGINE [=] engine_name
该语句删除名为“logfile_group”的日志文件组。
- 日志文件组必须已经存在,否则将导致错误。
- 在删除日志文件组之前,必须删除所有“使用该日志文件组进行UNDO日志记录的”表空间。
- “ENGINE”子句(必需的)提供要删除的日志文件组使用的存储引擎的名称。
- 当前,“engine_name”的唯一允许值为NDB和NDBCLUSTER。
- 删除日志文件组仅对 NDB 群集的磁盘数据存储有用。
DROP PROCEDURE 和 DROP FUNCTION 语句
DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name
该语句用于删除存储过程或函数。即,将指定的例程从服务器中删除。
- 必须对该例程具有“ALTER ROUTINE”权限。
- (如果启用了“automatic_sp_privileges”系统变量,则在创建例程时会自动将该权限和“EXECUTE”授予例程创建者,并在删除例程后从创建者中删除该权限和“EXECUTE”。)
- “IF EXISTS”子句是 MySQL 扩展。如果过程或功能不存在,则可以防止发生错误。
- 产生一个警告,可以使用“SHOW WARNINGS”查看。
- “DROP FUNCTION”还用于删除用户定义的功能。
DROP SERVER 语句
DROP SERVER [ IF EXISTS ] server_name
删除名为“server_name”的服务器的服务器定义。“mysql.servers”表中的相应行将被删除。
- 此语句需要“SUPER”权限。
- 为表删除服务器不会影响任何创建了此连接信息的“FEDERATED”表。
- DROP SERVER 导致隐式提交。
- 不管使用哪种日志记录格式,都不会将 DROP SERVER 写入二进制日志。
DROP TABLE 语句
DROP [TEMPORARY] TABLE [IF EXISTS]
tbl_name [, tbl_name] ...
[RESTRICT | CASCADE]
DROP TABLE 删除一个或多个表。
- 每个表都必须具有“DROP”权限。
- 它将删除 table 定义和所有 table 数据。
- 如果 table 已分区,则该语句将删除 table 定义,其所有分区,分区中的所有数据,以及与被删除 table 关联的所有分区定义。【?】
- 删除 table 也会删除该 table 的所有触发器。
- DROP TABLE 导致隐式提交,除非与“TEMPORARY”关键字一起使用。
- 删除 table 后,不会自动删除专门为该 table 授予的特权。必须手动删除它们。
如果在参数列 table 中命名的 table 不存在,则 DROP TABLE 的行为取决于是否提供了“IF EXISTS”子句:
- 如果没有“IF EXISTS”,则该语句将删除所有确实存在的命名 table,并返回错误,指出无法删除哪些不存在的 table。
- 使用“IF EXISTS”,不存在的 table 不会发生错误。该语句删除所有确实存在的命名 table,并为每个不存在的 table 生成NOTE诊断。这些 Comments 可以用“SHOW WARNINGS”显示。
【IF EXISTS 在异常情况下删除 table 很有用】
“TEMPORARY”关键字具有以下效果:
- 该语句仅删除 TEMPORARY 表。
- 该语句不会导致隐式提交。
- 没有检查访问权限。 TEMPORARY 表仅在创建它的会话中可见,因此无需检查。
【包含 TEMPORARY 关键字是防止意外删除 非TEMPORARY 表的好方法】
“RESTRICT”和“CASCADE”关键字无效。允许它们使从其他数据库系统的移植更加容易。【“RESTRICT”?“CASCADE”?】
“DROP TABLE”并非支持所有“innodb_force_recovery”设置。【?】
DROP TABLESPACE 语句
DROP TABLESPACE tablespace_name
[ENGINE [=] engine_name]
该语句删除先前使用“CREATE TABLESPACE”创建的表空间。
- (所有 MySQL NDB Cluster 7.5 版本以及标准 MySQL Server 中的InnoDB都支持它。)
“ENGINE”设置使用表空间的存储引擎,其中“engine_name”是存储引擎的名称【当前,支持值“InnoDB”和“NDB”】。
- 如果未设置,则使用值“default_storage_engine”。
- 如果它与用于创建表空间的存储引擎不同,则 DROP TABLESPACE 语句失败。
- 对于 InnoDB 表空间:必须在进行 DROP TABLESPACE 操作之前从表空间中删除所有 table。如果表空间不为空,则 DROP TABLESPACE 返回错误。
- 对于常规表空间:与 InnoDB 系统表空间一样,“截断”或“删除”存储在常规表空间中的 InnoDB 表会在表空间的“.ibd”数据文件中创建可用空间,该空间只能用于新的 InnoDB 数据。
- 空间不会这些操作而释放回 os,因为它是用于“每表一文件”(file-per-table)的表空间。
- 对于 NDB 表空间:要删除的表空间不得包含任何数据文件;换句话说,在删除 NDB 表空间之前,必须首先使用“ALTER TABLESPACE ... DROP DATAFILE”删除其每个数据文件。
注意:表空间不会自动删除。必须使用“DROP TABLESPACE”明确删除表空间。即使“DROP DATABASE”操作删除属于该表空间的所有表,表空间依然存在。
InnoDB 示例:【删除 InnoDB 常规表空间】
通用表空间 ts1 是使用单个表创建的。在删除表空间之前,必须删除表。
mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB;
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1 Engine=InnoDB;
mysql> DROP TABLE t1;
mysql> DROP TABLESPACE ts1;
NDB 示例:【删除 NDB 表空间】
在创建表空间之后,删除具有数据文件“mydata-1.dat”的NDB表空间 myts,并假设存在名为 mylg 的日志文件组:
mysql> CREATE TABLESPACE myts
-> ADD DATAFILE 'mydata-1.dat'
-> USE LOGFILE GROUP mylg
-> ENGINE=NDB;
必须先使用 ALTER TABLESPACE 从表空间中删除所有数据文件,然后才能将其删除:
mysql> ALTER TABLESPACE myts
-> DROP DATAFILE 'mydata-1.dat'
-> ENGINE=NDB;
mysql> DROP TABLESPACE myts;
DROP TRIGGER 语句
DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name
该语句删除触发器。模式(数据库)名称是可选的。如果省略模式,则从默认模式删除该触发器。
- DROP TRIGGER 要求具有与触发器关联的 table 的“TRIGGER”权限。
- 使用“IF EXISTS”可以防止不存在的触发器发生错误。使用IF EXISTS时,为不存在的触发器生成NOTE。
- 如果删除 table,则其触发器也会被删除。
DROP VIEW 语句
DROP VIEW [IF EXISTS]
view_name [, view_name] ...
[RESTRICT | CASCADE]
DROP VIEW 删除一个或多个视图。每个视图必须具有“DROP”权限。
- 如果在参数列 table 中命名的视图不存在,则该语句将返回错误,按名称指示无法删除哪些不存在的视图,但还会删除列 table 中存在的所有视图。
- “IF EXISTS”子句可防止不存在的视图发生错误。
- “RESTRICT”和“CASCADE”将被解析并忽略。
RENAME、TRUNCATE
RENAME TABLE 语句
RENAME TABLE
tbl_name TO new_tbl_name
[, tbl_name2 TO new_tbl_name2] ...
RENAME TABLE 重命名一个或多个表。您必须具有原始表的“ALTER”和“DROP”权限,以及新表的“CREATE”和“INSERT”权限。
示例:
要将名为 old_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;
- 表上的元数据锁是按名称 Sequences 获取的,在某些情况下,当多个事务同时执行时,操作结果可能会有所不同。【???】
- 要执行 RENAME TABLE,必须没有活动的事务或被“LOCK TABLES”锁定的表。在满足事务表锁定条件的情况下,重命名操作是原子完成的;重命名过程中,没有其他会话可以访问任何表。【???】
- 如果在 RENAME TABLE 期间发生任何错误,则该语句将失败并且不会进行任何更改。
通过 RENAME 将表移动到其他数据库【???外键约束???】
可以使用 RENAME TABLE 将 table 从一个数据库移动到另一个数据库:
RENAME TABLE current_db.tbl_name TO other_db.tbl_name;
使用此方法实际上将所有 table 从一个数据库移动到另一个数据库,这实际上重命名了该数据库(MySQL 没有单个语句的操作),只是原始数据库仍然存在(尽管没有 table)。
- 像“RENAME TABLE”一样,“ALTER TABLE ... RENAME”也可以用于将 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 表 语句
TRUNCATE [TABLE] tbl_name
清空表。
- 它需要“DROP”权限。
从逻辑上讲,“TRUNCATE TABLE”类似于:1、删除所有行的“DELETE”语句;2、或“DROP TABLE”和“CREATE TABLE”语句序列。【但并不一样】
为了获得高性能,它绕过了删除数据的 DML 方法。因此:
- 它无法回滚,
- 也不会引发“ON DELETE”触发器,
- 并且无法对具有父子外键关系的InnoDB表执行该操作。
尽管“TRUNCATE TABLE”与“DELETE”类似,但它被分类为 DDL 语句而不是 DML 语句。它与 DELETE 在以下方面不同:
- TRUNCATE 操作可删除并重新创建表,这比逐行删除行要快得多,尤其是对于大型表。
- TRUNCATE 操作会导致隐式提交,因此无法回滚。
- 如果会话持有活动的表锁,则无法执行 TRUNCATE 操作。
- 如果 InnoDB 表或 NDB 表的其他表引用了“FOREIGN KEY”约束,则“TRUNCATE TABLE”失败。允许在同一表的列之间使用外键约束。
- TRUNCATE 操作不会为删除的行数返回有意义的值。通常的结果是“受影响的 0 行”,应解释为“无信息”。
- 只要表格式文件“tbl_name.frm”有效,就可以使用 “TRUNCATE TABLE” 将表重新创建为空 表,即使数据或索引文件已损坏。
- 任何“AUTO_INCREMENT”值都将重置为其初始值。
- 即使是MyISAM和InnoDB,也是如此,它们通常不重用序列值。
- 与分区表一起使用时,“TRUNCATE TABLE”保留分区;也就是说,数据和索引文件被删除并重新创建,而分区定义(.par)文件不受影响。
- “TRUNCATE TABLE”语句不调用“ON DELETE”触发器。
出于二进制日志记录和复制的目的,“TRUNCATE TABLE”被视为“DROP TABLE”,然后是“CREATE TABLE”,即 DDL 而不是 DML。这是由于以下事实:在使用InnoDB和其他事务隔离级别不允许基于语句的日志记录(READ COMMITTED或READ UNCOMMITTED)的事务存储引擎时,在使用“STATEMENT”或“MIXED”日志记录模式时未记录并复制该语句。但是,它仍以前述方式使用InnoDB应用于复制从属。
在具有大型 InnoDB 缓冲池并启用“innodb_adaptive_hash_index”的系统上,由于在删除 InnoDB 表的自适应哈希索引条目时发生 LRU【?】 扫描,因此“TRUNCATE TABLE”操作可能会导致系统性能暂时下降。在 MySQL 5.5.23 中解决了“DROP TABLE”的问题(错误#13704145,错误#64284),但对于“TRUNCATE TABLE”仍然是已知问题(错误#68184)。
“TRUNCATE TABLE”可以与 Performance Schema 摘要表一起使用,但是效果是将摘要列重置为 0 或 NULL,而不是删除行。