MySQL 语句:数据定义语句(DDL)

来自Wikioe
跳到导航 跳到搜索


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 中实现的编码将数据库名称映射到数据库目录名称。本条款在以下条件下使用:

  1. 它旨在将 MySQL 从较早版本升级到 5.1 或更高版本。
  2. 如果名称中包含需要编码的特殊字符,则打算将数据库目录名称更新为当前的编码格式。
  3. 该语句由“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;
      
  • 在复制从属服务器上使用“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 语句】

ALTER TABLESPACE 语句【???和 NDB 群集有关】

ALTER TABLESPACE tablespace_name
    {ADD | DROP} DATAFILE 'file_name'
    [INITIAL_SIZE [=] size]
    [WAIT]
    ENGINE [=] engine_name

该语句用于添加新数据文件或从表空间删除数据文件。

  • “ADD DATAFILE”变体使您可以使用“INITIAL_SIZE”子句指定初始大小:
    1. 其中 size 以字节为单位;【默认值为 134217728(128 MB)】
    2. 可以在 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 唯一可接受的值为 NDBNDBCLUSTER

当“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:

  1. 如果数据库存在并且您未指定“IF NOT EXISTS”,则会发生错误。
  2. 具有有效“LOCK TABLES”语句的会话不允许“CREATE DATABASE”。【???】
  3. 每个“create_option”指定一个数据库 Feature。数据库 Feature 存储在数据库目录的“db.opt”文件中。
    “CHARACTER SET”选项指定默认的数据库字符集。“COLLATE”选项指定默认的数据库排序规则。
  4. MySQL 中的数据库被实现为包含与数据库表相对应的文件的目录。
    由于最初创建数据库时数据库中没有 table,因此“CREATE DATABASE”语句仅:1、在 MySQL 数据目录下创建一个目录;2、并在目录中创建一个“db.opt”文件:
    MySQL:create database.png
  5. 如果您在数据目录下手动创建目录(例如,使用“mkdir”),则服务器会将其视为数据库目录,并显示在“SHOW DATABASES”的输出中:
    MySQL:手动在data目录创建文件夹.png
  6. 创建数据库时,让服务器 Management 目录及其中的文件。直接操作数据库目录和文件可能会导致不一致和意外结果。
  7. 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”语句的最低要求如下:

  1. 关键字“CREATE EVENT”加上事件名称,该名称在数据库架构中唯一标识事件。
  2. “ON SCHEDULE”子句,用于确定事件的执行时间和频率
  3. “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 帐户。

  1. 如果存在“DEFINER”子句,则“user”值应为指定为:“'user_name'@'host_name'”、“CURRENT_USER”或“CURRENT_USER()”的 MySQL 帐户。
  2. 如果省略“DEFINER”子句,则默认定义器是执行“CREATE EVENT”语句的用户。这与显式指定“DEFINER = CURRENT_USER”相同。
  • 在事件主体内,“CURRENT_USER”函数返回用于在事件执行时检查权限的帐户,该帐户是“DEFINER”用户。


ON SCHEDULE”子句:确定为事件定义的“event_body”重复的时间,频率和持续时间。此子句采用以下两种形式之一:

  1. 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开头。
  2. EVERY interval”子句用于定期重复执行操作。“EVERY”关键字后跟“interval”。(“+ INTERVAL”不能与“EVERY”一起使用)
    例如,“EVERY 6 WEEK”表示“每六个星期”。
    1. “EVERY”子句包含可选的“STARTS”子句,后跟一个“timestamp”值,该值指示何时应开始重复该操作,并且还可以使用“+ INTERVAL interval”指定“从现在开始”的时间。
      例如,“EVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEK”表示“每三个月,从现在开始的一个星期开始”。
      • 未指定“STARTS”与使用“STARTS CURRENT_TIMESTAMP”相同。也就是说,为事件指定的操作在创建事件后立即开始重复。
    2. “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”语句似乎成功;但是,当服务器尝试执行生成的计划事件时,执行失败并显示错误。
  1. 与存储例程一样,可以通过使用“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”命令更改语句定界符。【????????????????】
  2. 事件中可能会出现更复杂的复合语句,例如存储例程中使用的复合语句。此示例使用局部变量,错误处理程序和流控制构造
    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 ;
    
  3. 无法将参数直接传递给事件或从事件传递参数。但是,可以在事件中使用参数调用存储的例程:
    CREATE EVENT e_call_myproc
        ON SCHEDULE
          AT CURRENT_TIMESTAMP + INTERVAL 1 DAY
        DO CALL myproc(5, 27);
    


  • 如果事件的定义者具有足以设置全局系统变量的权限,则该事件可以读取和写入全局变量。由于授予此类特权可能会导致滥用行为,因此必须格外小心。
  • 通常,在存储的例程中有效的任何语句都可以用于事件执行的动作语句。。您可以将事件创建为存储例程的一部分,但是另一个事件不能创建一个事件。

【CREATE INDEX 语句】

CREATE LOGFILE GROUP 语句

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”子句。
  • 创建日志文件组仅对 NDB 群集的磁盘数据存储有用
    • 在任何给定时间,每个 NDB 群集实例只能有一个日志文件组


  • 所有 NDB 群集磁盘数据对象共享相同的名称空间。这意味着“每个磁盘数据对象”必须被唯一命名(而不仅仅是给定类型的每个磁盘数据对象)。例如,您不能具有相同名称的表空间和日志文件组,或具有相同名称的表空间和数据文件。【???】


可选的“INITIAL_SIZE”参数设置UNDO文件的初始大小,默认为128M

  1. INITIAL_SIZE的最小允许值为 1048576(1 MB)。
  2. 在 32 位系统上,INITIAL_SIZE 的最大支持值为 4294967296(4 GB)


可选的“UNDO_BUFFER_SIZE”参数设置UNDO缓冲区用于日志文件组的大小,默认值为8M

  • 此值不能超过可用的系统内存量。
  • 用于 UNDO_BUFFER_SIZE 的内存来自全局池,该全局池的大小由“SharedGlobalMemory”数据节点配置参数的值确定。这包括“InitialLogFileGroup”数据节点配置参数的设置对此选项隐含的任何默认值。


ENGINE”选项确定此日志文件组要使用的存储引擎。

  1. 在 MySQL 5.7 中,“engine_name”值必须为NDB(或NDBCLUSTER)。
  2. 如果未设置 ENGINE,则 MySQL 尝试使用“default_storage_engine”服务器系统变量(以前为“storage_engine”)指定的引擎。
  • 在任何情况下,如果未将引擎指定为 NDB 或 NDBCLUSTER,则“CREATE LOGFILE GROUP”看似成功,但实际上无法创建日志文件组,如下所示:【创建日志文件组仅对 NDB 群集的磁盘数据存储有用
    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)
    


“REDO_BUFFER_SIZE”,“NODEGROUP”,“WAIT”和“COMMENT”被解析但被忽略,因此在 MySQL 5.7 中无效。这些选项旨在用于将来的扩展。


与“ENGINE [=] NDB”一起使用时,将在每个“群集”数据节点上创建一个日志文件组和关联的UNDO日志文件。您可以验证UNDO文件已创建并通过查询“INFORMATION_SCHEMA.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 PROCEDURE 和 CREATE FUNCTION 语句

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

这些语句创建存储的例程。

  • 默认情况下,例程与默认数据库关联。要将例程与给定数据库显式关联,请在创建例程时将其名称指定为“db_name.sp_name”。
  • CREATE FUNCTION 语句在 MySQL 中也用于支持 UDF(用户定义的函数)。
    UDF 可以视为外部存储功能。存储的函数与 UDF 共享其名称空间

调用:

  1. 对 PROCEDURE:请使用“CALL”语句。
  2. 对 FUNCTION:请在表达式中引用它。该函数在表达式求值期间返回一个值。

权限:

  • CREATE PROCEDURE 和 CREATE FUNCTION 需要“CREATE ROUTINE”权限。如果存在“DEFINER”子句,则所需权限取决于 user 值。如果启用了二进制日志记录,则 CREATE FUNCTION 可能需要“SUPER”权限。
    默认情况下,MySQL 自动向例程创建者授予“ALTER ROUTINE”和“EXECUTE”权限。可以通过禁用“automatic_sp_privileges”系统变量来更改此行为。

名称:

  • 如果例程名称与内置 SQL 函数的名称相同,除非在名称和以下括号之间使用空格,否则在定义例程或稍后调用它时会发生语法错误。因此,请避免将现有 SQL 函数的名称用于您自己的存储例程。
    “IGNORE_SPACE” SQL 模式适用于内置函数,不适用于存储的例程。始终允许在存储的例程名称后留空格,无论是否启用了 IGNORE_SPACE。

参数:

  1. 对 PROCEDURE:参数可指定为“IN”,“OUT”或“INOUT”。【默认均为“IN”参数】
    1. “IN”参数将值传递给过程。该过程可能会修改该值,但是该过程返回时,调用者看不到该修改。
    2. “OUT”参数将值从过程传递回调用方。在过程中,其初始值为NULL,并且在过程返回时,调用者可以看到其初始值。
    3. “INOUT”参数由调用者初始化,可以由过程修改,并且过程返回时,调用者可以看到该过程所做的任何更改。
    • 对于每个“OUT”或“INOUT”参数,在调用该过程的“CALL”语句中传递用户定义的变量,以便在过程返回时可以获取其值。如果要从另一个存储过程或函数中调用过程,则还可以将例程参数或本地例程变量作为“OUT”或“INOUT”参数传递。如果要从触发器内调用过程,则还可以将“NEW.col_name”作为“OUT”或“INOUT”传递。
  2. 对 FUNCTION:参数始终被视为“IN”参数。
  • 括号内的参数列表必须始终存在。参数名称不区分大小写。
    如果没有参数,则应使用空的参数列表“()”。
  • 例程参数不能在例程中准备的语句中引用。【???】

返回值:

  1. 对 PROCEDURE:通过“OUT”或“INOUT”参数返回有效结果。
  2. 对 FUNCTION:必需指定“RETURNS”子句。它指示函数的返回类型,并且函数主体必须包含“RETURN value”语句。
    • 如果 RETURN 语句返回其他类型的值,则该值将被强制为正确的类型。
      例如,如果函数在 RETURNS子 句中指定 ENUM 或 SET 值,但 RETURN 语句返回整数,则从函数返回的值是 SET 成员集中相应 ENUM 成员的字符串。
  • 返回结果集的语句可以在存储过程中使用,但不能在存储函数中使用。
    此禁止包括不具有“INTO var_list”子句的“SELECT”语句,以及其他诸如“SHOW”,“EXPLAIN”和“CHECK TABLE”的语句。对于可以在函数定义时确定的语句以返回结果集的情况,发生“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)。


delimiter”命令:mysql client命令,用于修改 client 端的语句定界符


示例,PROCEDURE:

mysql> delimiter //

mysql> CREATE PROCEDURE citycount (IN country CHAR(3), OUT cities INT)
       BEGIN
         SELECT COUNT(*) INTO cities FROM world.city
         WHERE CountryCode = country;
       END//
Query OK, 0 rows affected (0.01 sec)

mysql> delimiter ;

mysql> CALL citycount('JPN', @cities); -- cities in Japan
Query OK, 1 row affected (0.00 sec)

mysql> SELECT @cities;
+---------+
| @cities |
+---------+
|     248 |
+---------+
1 row in set (0.00 sec)

mysql> CALL citycount('FRA', @cities); -- cities in France
Query OK, 1 row affected (0.00 sec)

mysql> SELECT @cities;
+---------+
| @cities |
+---------+
|      40 |
+---------+
1 row in set (0.00 sec)

如上,该示例在定义过程时使用mysql client delimiter命令将语句定界符从“;”更改为“//”。这使过程主体中使用的“;”分隔符可以传递到服务器,而不是由mysql本身解释


示例,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)

如上,该函数使用参数,使用 SQL 函数执行操作,然后返回结果。在这种情况下,不必使用“delimiter”,因为函数定义不包含内部语句定界符“;”。


可以声明参数类型和函数返回类型以使用任何有效的数据类型。如果带有“CHARACTER SET”规范,则可以使用“COLLATE”属性。


routine_body”:由有效的 SQL 例程语句组成。这可以是简单的语句,例如“SELECT”或“INSERT”,也可以是使用“BEGIN”和“END”编写的复合语句。【复合语句可以包含声明,循环和其他控制结构语句。】

  • MySQL 允许例程包含 DDL 语句(例如 CREATE 和 DROP )。
  • MySQL 还允许存储过程(但不能存储函数)包含 SQL 事务语句(例如 COMMIT)。存储的函数可能不包含执行显式或隐式提交或回滚的语句。

SQL 标准不需要支持这些语句,该标准指出每个 DBMS 供应商都可以决定是否允许它们。

  • 不允许在存储例程中使用“USE”语句。调用例程时,将执行隐式“USE db_name”(并且在例程终止时撤消),使例程在执行时具有给定的默认数据库。对例程默认数据库以外的数据库中对象的引用应使用适当的数据库名称进行限定。

SQL 模式:【???】

  • MySQL 会在创建或更改例程时存储有效的“sql_mode”系统变量设置,并始终在此设置有效的情况下执行该例程,而不管例程开始执行时当前的服务器 SQL 模式如何。【???】

在对参数进行评估并将结果值分配给例程参数之后,就会发生从调用者的 SQL 模式到例程模式的切换。如果以严格 SQL 模式定义例程但以非严格模式调用例程,则在严格模式下不会将参数分配给例程参数。如果需要以严格的 SQL 模式分配传递给例程的表达式,则应以有效的严格模式调用该例程。


COMMENT”特性是 MySQL 扩展,可用于描述存储的例程。此信息通过“SHOW CREATE PROCEDURE”和“SHOW CREATE FUNCTION”语句显示。


LANGUAGE”特性指示编写例程的语言。服务器忽略此 Feature;仅支持 SQL 例程。


DETERMINISTIC”和“NOT DETERMINISTIC”:如果例程对于相同的输入参数始终产生相同的结果,则将其视为“确定性”,否则将其视为“不确定性”。

  • 默认值为“NOT DETERMINISTIC”。要声明函数是确定性的,必须显式指定“DETERMINISTIC”。

MySQL 不会检查声明为“DETERMINISTIC”的例程是否没有产生不确定结果的语句。但是,错误声明例程可能会影响结果或影响性能。将不确定的例程声明为“DETERMINISTIC”可能会导致优化器做出错误的执行计划选择,从而导致意外结果。将确定性例程声明为“NONDETERMINISTIC”可能会导致不使用可用的优化,从而降低性能。

  • 如果启用了二进制日志记录,则“DETERMINISTIC”特性会影响 MySQL 接受哪些例程定义。

包含“NOW()”函数(或其同义词)或“RAND()”的例程是不确定的,但是它可能仍然是安全复制的:

  1. 对于“NOW()”,二进制日志包括时间戳记并可以正确复制。
  2. “ RAND()”也可以正确复制,只要在例程执行期间仅一次调用它即可。

(可以将例程执行时间戳和随机数种子视为隐式输入,它们在主服务器和从属服务器上是相同的。)


提供了有关例程使用数据的性质的信息。在 MySQL 中,这些 Feature 仅是建议性的。服务器不使用它们来约束例程将被允许执行的语句类型。

  1. “CONTAINS SQL”表示例程“不包含读取或写入数据的语句”。如果未明确给出这些 Feature,则为默认设置。此类语句的示例是“SET @x = 1”或“DO RELEASE_LOCK('abc')”,它们执行但既不读取也不写入数据。
  2. “NO SQL”表示例程“不包含 SQL 语句”。
  3. “READS SQL DATA”表示例程“包含读取数据的语句(例如 SELECT),但不包含写入数据的语句”。
  4. “MODIFIES SQL DATA”表示例程“包含可能写入数据的语句”(例如 INSERT 或 DELETE)。


DEFINER”和“SQL SECURITY”子句指定在例行执行时检查访问权限时要使用的安全上下文。

  1. “DEFINER”子句指定在例程执行时检查具有“SQL SECURITY DEFINER”特性的例程的访问权限时要使用的 MySQL 帐户。
    • 如果存在 DEFINER 子句,则 user 值应为指定为:“'user_name'@'host_name'”,“CURRENT_USER”或“CURRENT_USER()”的 MySQL 帐户。允许的 user 值取决于您所拥有的权限,
    • 如果省略 DEFINER 子句,则默认定义器是执行“CREATE TRIGGER”语句的用户。这与显式指定“DEFINER = CURRENT_USER”相同。
  2. “SQL SECURITY”特性可以是“DEFINER”(默认值)或“INVOKER”以指定安全上下文;【也就是说,例程是否使用“例程 DEFINER 子句中命名的帐户的”权限或“调用该例程的用户的”权限来执行】。
    • 该帐户必须有权访问与该例程关联的数据库。
    • 调用例程的用户必须具有该例程的“EXECUTE”权限,如果例程在“DEFINER”安全上下文中执行,则“DEFINER”帐户也必须具有该权限。
  • 在以“SQL SECURITY DEFINER”特性定义的存储例程的主体内,“CURRENT_USER”函数返回该例程的“DEFINER”值。【!】

示例1:考虑以下过程,该过程显示 mysql.user 系统表中列出的 MySQL 帐户数:

CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count()
BEGIN
  SELECT 'Number of accounts:', COUNT(*) FROM mysql.user;
END;
不管哪个用户定义了该程序,都为该程序分配了“'admin'@'localhost'”的 DEFINER 帐户。无论哪个用户调用该帐户,它都以该帐户的权限执行(因为默认的安全特性是 DEFINER)。该过程是成功还是失败,取决于调用者对其具有“EXECUTE”权限而“'admin'@'localhost'”对“mysql.user”表具有 SELECT 权限

示例2:现在假设该过程是用“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”表具有 SELECT 权限


服务器处理例程参数的数据类型,使用“DECLARE”创建的局部例程变量或函数返回值,如下所示:

  1. 检查分配是否存在数据类型不匹配和溢出。转换和溢出问题会导致警告或严格 SQL 模式下的错误。
  2. 只能分配标量值。例如,诸如“SET x = (SELECT 1, 2)”之类的语句无效。
  3. 对于字符数据类型:
    1. 如果声明中包含“CHARACTER SET”,则使用指定的字符集及其默认排序规则。如果“COLLATE”属性也存在,则使用该排序规则而不是默认排序规则。
    2. 如果“CHARACTER SET”和“COLLATE”不存在,则使用在例程创建时有效的数据库字符集和排序规则。
    • 为避免服务器使用数据库字符集和排序规则,请为字符数据参数提供显式的“CHARACTER SET”和“COLLATE”属性。
  • 如果更改数据库默认字符集或排序规则,则必须删除并重新创建要使用新数据库默认值的存储例程
    • 数据库字符集和排序规则由“character_set_database”和“collation_database”系统变量的值给出。

CREATE SERVER 语句

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”表中创建新行。
  • 此语句需要“SUPER”特权。
  • CREATE SERVER 导致隐式提交。
  • 不管使用哪种日志记录格式,都不会将 CREATE SERVER 写入二进制日志。
  • 【这与MySQL手册中“替代存储引擎”中的“联合存储引擎”(The FEDERATED Storage Engine)有关】


server_name”应该是服务器的唯一引用

  • 服务器定义在服务器范围内是全局的,因此无法将服务器定义限定为特定的数据库

server_name 的最大长度为 64 个字符(长于 64 个字符的名称会被自动截断),并且不区分大小写。您可以将名称指定为带引号的字符串。


wrapper_name”是一个标识符,可以用单引号引起来。


对于每个“option”,您必须指定字符 Literals 或数字 Literals。

  1. 字符 Literals 为 UTF-8,最大长度为 64 个字符,默认为空白(空)字符串。
  2. 字符串 Literals 被静默地截断为 64 个字符。
  3. 数字 Literals 必须是 09999 之间的数字,默认值为 0。


“OWNER”选项当前未应用,并且对创建的服务器连接的所有权或操作没有影响。


【???】
CREATE SERVER 语句在“mysql.servers”表中创建一个条目,以后可在创建“FEDERATED”表时与“CREATE TABLE”语句一起使用。您指定的选项将用于填充“mysql.servers”表中的列。表格列是: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');

确保指定与服务器构建连接所需的所有选项。用户名,主机名和数据库名是必需的。可能还需要其他选项,例如密码。

创建与“FEDERATED”表的连接时可以使用表中存储的数据:【?????】

CREATE TABLE t (s1 INT) ENGINE=FEDERATED CONNECTION='s';

【CREATE TABLE 语句】

【CREATE TABLESPACE 语句】

CREATE TRIGGER 语句

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 相关联的命名数据库对象,并在 table 发生特定事件时激活。触发器与名为 tbl_name 的 table 相关联,该 table 必须引用一个永久 table。您不能将触发器与 TEMPORARY 表或视图相关联。

  • 触发器名称存在于模式名称空间中,这意味着所有触发器在模式内必须具有唯一的名称。不同架构中的触发器可以具有相同的名称。
  • CREATE TRIGGER 要求具有与触发器关联的 table 的“TRIGGER”权限。如果存在“DEFINER”子句,则所需的权限取决于 user 值。如果启用了二进制日志记录,则 CREATE TRIGGER 可能需要“SUPER”权限。


trigger_time”是触发动作时间。可以是BEFORE或AFTER来指示触发器在要修改的每一行之前或之后激活。


trigger_event”表示激活触发器的操作类型。这些 trigger_event 值是允许的:

  1. INSERT:每当在 table 中插入新行时(例如,通过“INSERT”,“LOAD DATA”和“REPLACE”语句),触发器就会激活。
  2. UPDATE:每当修改一行时(例如,通过“UPDATE”语句),触发器就会激活。
  3. DELETE:每当从 table 中删除一行时(例如,通过“DELETE”和“REPLACE”语句),触发器就会激活。
    • table 上的“DROP TABLE”和“TRUNCATE TABLE”语句不激活该触发器,因为它们不使用 DELETE。
    • 删除分区也不会激活 DELETE 触发器。

“trigger_event”并不表示激活触发器的 SQL 语句的 Literals 类型,而是表示 table 操作的类型。例如,INSERT 触发器不仅为“INSERT”语句激活,而且为“LOAD DATA”语句激活,因为这两个语句都将行插入 table 中。

  • 一个可能令人困惑的例子是“INSERT INTO ... ON DUPLICATE KEY UPDATE ...”语法:每行都会激活“BEFORE INSERT”触发器,然后是“AFTER INSERT”触发器或“BEFORE UPDATE”和“AFTER UPDATE”触发器,这取决于该行是否有重复的键。
  • 级联的外键操作不会激活触发器。


trigger_order”:

可以为给定的 table 定义具有相同触发事件和动作时间的多个触发。(例如,一个 table 可以有两个“BEFORE UPDATE”触发器)。默认情况下,具有相同触发事件和动作时间的触发器将按照其创建 Sequences 进行激活。

要影响触发器的 Sequences,请指定“trigger_order”子句以指示“FOLLOWS”或“PRECEDES”以及现有触发器的名称,该触发器也具有相同的触发器事件和动作时间:

  1. 使用“FOLLOWS”,新触发器将在现有触发器之后激活。
  2. 使用“PRECEDES”,新触发器将在现有触发器之前激活。


trigger_body”是触发触发器时要执行的语句。要执行多个语句,请使用“BEGIN ... END”复合语句构造。这也使您能够使用存储例程中允许的相同语句。

  • 在触发器主体内,您可以使用别名“OLD”和“NEW”来引用主题 table(与触发器关联的 table)中的列。
    “OLD.col_name”指的是更新或删除现有行的列。“NEW.col_name”是指要插入的新行或更新后的现有行的列。
    • 触发器不能使用“NEW.col_name”或“OLD.col_name”来引用生成的列。

MySQL 会在创建触发器时存储有效的“sql_mode”系统变量设置,并始终在有效的情况下执行触发器主体,而与触发器开始执行时当前的服务器 SQL 模式无关。【???】


DEFINER”子句指定在触发器激活时检查访问权限时要使用的 MySQL 帐户。如果存在 DEFINER 子句,则 user 值应为指定为:“'user_name'@'host_name'”,“CURRENT_USER”或“CURRENT_USER()”的 MySQL 帐户。允许的 user 值取决于您所拥有的特权,

  • 如果省略 DEFINER 子句,则默认定义器是执行“CREATE TRIGGER”语句的用户。这与显式指定“DEFINER = CURRENT_USER”相同。

当检查触发特权时,MySQL 将 DEFINER 用户考虑在内:

  1. 在“CREATE TRIGGER”时间,发出该语句的用户必须具有“TRIGGER”权限。
  2. 在触发器激活时,将针对 DEFINER 用户检查特权。该用户必须具有以下特权:
    1. 主题 table 的“TRIGGER”权限。
    2. 如果使用触发器主体中的“NEW.col_name”或“OLD.col_name”引用 table 列,则主题 table 具有“SELECT”权限。
    3. 如果 table 列是触发器主体中“SET NEW.col_name = value”分配的目标,则主题 table 具有“UPDATE”权限。
    • 触发器执行的语句通常需要任何其他特权。

在触发器主体中,“CURRENT_USER”函数返回用于在触发器激活时检查特权的帐户。这是 DEFINER 用户,而不是其操作导致触发器被激活的用户。


如果您使用“LOCK TABLES”锁定具有触发器的 table,则该触发器中使用的 table 也会被锁定。

CREATE VIEW 语句

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”子句,则替换现有视图。如果该视图不存在,则“CREATE OR REPLACE VIEW”与“CREATE VIEW”相同。如果该视图确实存在,则“CREATE OR REPLACE VIEW”替换它。

  • CREATE VIEW 语句对视图具有“CREATE VIEW”权限,并且对“SELECT”语句选择的每一列都具有某些权限。对于“SELECT”语句中使用的其他地方的列,您必须具有“SELECT”权限。如果存在“OR REPLACE”子句,则您还必须具有该视图的“DROP”权限。如果存在“DEFINER”子句,则所需的权限取决于 user 值


ALGORITHM”子句影响 MySQL 处理视图的方式。


DEFINER”和“SQL SECURITY”子句指定在视图调用时检查访问权限时要使用的安全上下文。


WITH CHECK OPTION”子句以约束对视图引用的 table 中行的插入或更新。


DEFINER”和“SQL SECURITY”子句确定在执行引用该视图的语句时检查该视图的访问权限时使用哪个 MySQL 帐户。

  1. 有效的“SQL SECURITY”值是“DEFINER”(默认值,所需的权限由定义视图的用户拥有)和“INVOKER”(所需的权限由调用视图的用户拥有)。
  2. 如果存在“DEFINER”子句,则 user 值应为指定为:“'user_name'@'host_name'”,“CURRENT_USER”或“CURRENT_USER()”的 MySQL 帐户。允许的 user 值取决于您所拥有的权限。
    • 如果省略 DEFINER 子句,则默认定义器是执行“CREATE TRIGGER”语句的用户。这与显式指定“DEFINER = CURRENT_USER”相同。

关于“CURRENT_USER”函数:

  1. 在视图定义中,“CURRENT_USER”函数默认返回视图的“DEFINER”值。
  2. 对于使用“SQL SECURITY INVOKER”特性定义的视图,“CURRENT_USER”返回该视图的调用者的帐户。
  3. 对于以“SQL SECURITY DEFINER”特性定义的存储例程中,“CURRENT_USER”函数该例程的“DEFINER”值。
  • 如果视图定义包含“DEFINER”值为“CURRENT_USER”,则这也会影响在此例程中定义的视图。【?】


select_statement”是提供视图定义的“SELECT”语句。(实际上,使用SELECT语句从视图中进行选择。)

  • select_statement 可以从基本 table 或其他视图中进行选择。
  • 视图定义在创建时被“冻结”,并且不受基础 table 定义的后续更改影响
    例如,如果在 table 上将视图定义为“SELECT *”,则以后添加到 table 中的新列将不成为视图的一部分,并且从 table 中删除的列在从视图中进行选择时将导致错误。
  • SELECT 语句检索的列可以是对 table 列的简单引用,也可以是使用函数,常量值,运算符等的表达式。
  • 可以使用多种SELECT语句创建视图。它可以引用基 table 或其他视图。它可以使用 joins,UNION和子查询。SELECT甚至不需要引用任何 table:
    CREATE VIEW v_today (today) AS SELECT CURRENT_DATE;
    
    mysql> CREATE TABLE t (qty INT, price INT);
    mysql> INSERT INTO t VALUES(3, 50);
    mysql> CREATE VIEW v AS SELECT qty, price, qty*price AS value FROM t;
    mysql> SELECT * FROM v;
    +------+-------+-------+
    | qty  | price | value |
    +------+-------+-------+
    |    3 |    50 |   150 |
    +------+-------+-------+
    


视图属于数据库。默认情况下,将在默认数据库中创建一个新视图。要在给定的数据库中显式创建视图,请使用“db_name.view_name”语法用数据库名称限定视图名称:

CREATE VIEW test.v AS SELECT * FROM t;

视图可以通过用适当的数据库名称限定 table 或视图的名称来引用其他数据库中的 table 或视图。对于 SELECT 语句中的不合格 table 名或视图名会相对于默认数据库进行解释。

  • 在数据库中,基表和视图共享相同的名称空间,因此基表和视图不能具有相同的名称


视图定义受以下限制:

  1. SELECT 语句不能引用系统变量或用户定义的变量。
  2. 在存储程序中,SELECT 语句不能引用程序参数或局部变量。
  3. SELECT 语句不能引用准备好的语句参数。
  4. 定义中引用的任何 table 或视图都必须存在。如果在创建视图后删除了定义所引用的 table 或视图,则使用该视图会导致错误。要检查视图定义中是否存在此类问题,请使用“CHECK TABLE”语句。
  5. 该定义不能引用“TEMPORARY”table,并且您不能创建“TEMPORARY”视图。
  6. 您不能将触发器与视图关联。
  7. SELECT语句中列名的别名会对照最大列长度 64 个字符(而不是别名最大长度 256 个字符)进行检查。
  • 视图定义中允许使用“ORDER BY”,但是如果您从“具有自己的 ORDER BY 语句的”视图中进行选择,则将忽略“ORDER BY”。
  • 对于定义中的其他选项或子句,它们被添加到引用该视图的语句的选项或子句中,但效果未定义。例如,如果视图定义包含“LIMIT”子句,并且您从“使用具有自己的 LIMIT 子句的”视图中进行选择,则不确定哪个限制适用。
    • 相同的原理适用于“SELECT”关键字后的选项(例如“ALL”,“DISTINCT”或“SQL_SMALL_RESULT”)以及子句(例如“INTO”,“FOR UPDATE”,“LOCK IN SHARE MODE”和“PROCEDURE”)。


如果通过更改系统变量来更改查询处理环境,则从视图获得的结果可能会受到影响:【???】

mysql> CREATE VIEW v (mycol) AS SELECT 'abc';
Query OK, 0 rows affected (0.01 sec)

mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT "mycol" FROM v;
+-------+
| mycol |
+-------+
| mycol |
+-------+
1 row in set (0.01 sec)

mysql> SET sql_mode = 'ANSI_QUOTES';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT "mycol" FROM v;
+-------+
| mycol |
+-------+
| abc   |
+-------+
1 row in set (0.00 sec)


WITH CHECK OPTION”:为可更新视图提供WITH CHECK OPTION子句,以防止对“select_statement”中 WHERE 子句为 true 的行进行插入或更新。

在可更新视图的 WITH CHECK OPTION 子句中,当使用另一个视图定义视图时,“LOCAL”(仅将“CHECK OPTION”限制为正在定义的视图)和“CASCADED”(默认值,也会评估对基础视图的检查)关键字确定检查测试的范围。


在包含“ORDER BY integer”的 MySQL 5.7.3 之前创建的视图可能会在视图评估时导致错误。【???】
如,请考虑以下视图定义,它们使用“ORDER BY”以及序数:

CREATE VIEW v1 AS SELECT x, y, z FROM t ORDER BY 2;
CREATE VIEW v2 AS SELECT x, 1, z FROM t ORDER BY 2;

在第一种情况下,“ORDER BY 2”指的是命名列y。在第二种情况下,它引用常量 1。对于从任一视图中选择少于 2 列(在ORDER BY子句中命名的数字)的查询,如果服务器使用 MERGE 算法评估视图,则会发生错误。

mysql> SELECT x FROM v1;
ERROR 1054 (42S22): Unknown column '2' in 'order clause'
mysql> SELECT x FROM v2;
ERROR 1054 (42S22): Unknown column '2' in 'order clause'

从 MySQL 5.7.3 开始,为了处理这样的视图定义,服务器将它们不同地写入存储视图定义的“.frm”文件中。此差异在“SHOW CREATE VIEW”可见。以前,“.frm”文件包含ORDER BY 2子句的内容:

For v1: ORDER BY 2
For v2: ORDER BY 2

从 5.7.3 开始,“.frm”文件包含以下内容:

For v1: ORDER BY `t`.`y`
For v2: ORDER BY ''

也就是说,对于v1,将 2 替换为对所引用列名称的引用。对于v2,将 2 替换为常量字符串表达式(按常量排序无效,因此按任何常量排序都可以)。

如果遇到如上所述的视图评估错误,请删除并重新创建视图,以使“.frm”文件包含更新的视图表示形式。另外,对于像v2这样按恒定值排序的视图,请删除并重新创建没有ORDER BY子句的视图。

DROP 语句

DROP DATABASE 语句

DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

DROP DATABASE 将删除数据库中的所有表并删除数据库。

  • 要使用“DROP DATABASE”,需要对数据库具有“DROP”权限。
  • “DROP SCHEMA”是“DROP DATABASE”的同义词
  • 删除数据库后,不会自动删除专门为该数据库授予的特权。必须手动删除它们。
  • 您也可以使用 mysqladmin 删除数据库。


Note:

  1. “IF EXISTS”用于防止数据库不存在时发生错误。
  2. 如果删除了默认数据库,则未设置默认数据库(“DATABASE()”函数将返回“NULL”)。
  3. 如果在符号链接的数据库上使用“DROP DATABASE”,则链接和原始数据库都将被删除。
  4. DROP DATABASE 返回已删除的 table 数。这对应于已删除的“.frm”文件的数量。


DROP DATABASE 语句从给定的数据库目录中删除 MySQL 本身在正常操作期间可能创建的那些文件和目录:

  1. 所有具有以下 extensions 的文件:
    .BAK
    .DAT
    .HSH
    .MRG
    .MYD
    .MYI
    .TRG
    .TRN
    .cfg
    .db
    .frm
    .ibd
    .ndb
    .par
    
  2. 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”的唯一允许值为NDBNDBCLUSTER
  • 删除日志文件组仅对 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”子句:

  1. 如果没有“IF EXISTS”,则该语句将删除所有确实存在的命名 table,并返回错误,指出无法删除哪些不存在的 table。
  2. 使用“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 语句失败。
  1. 对于 InnoDB 表空间:必须在进行 DROP TABLESPACE 操作之前从表空间中删除所有 table。如果表空间不为空,则 DROP TABLESPACE 返回错误。
  2. 对于常规表空间:与 InnoDB 系统表空间一样,“截断”或“删除”存储在常规表空间中的 InnoDB 表会在表空间的“.ibd”数据文件中创建可用空间,该空间只能用于新的 InnoDB 数据。
    空间不会这些操作而释放回 os,因为它是用于“每表一文件”(file-per-table)的表空间。
  3. 对于 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 TABLE 语句

TRUNCATE [TABLE] tbl_name

清空表

  • 它需要“DROP”权限


从逻辑上讲,“TRUNCATE TABLE”类似于:1、删除所有行的“DELETE”语句;2、或“DROP TABLE”和“CREATE TABLE”语句序列。【但并不一样】

为了获得高性能,它绕过了删除数据的 DML 方法。因此:

  1. 它无法回滚
  2. 不会引发“ON DELETE”触发器
  3. 并且无法对具有父子外键关系的InnoDB表执行该操作。


尽管“TRUNCATE TABLE”与“DELETE”类似,但它被分类为 DDL 语句而不是 DML 语句。它与 DELETE 在以下方面不同:

  1. TRUNCATE 操作可删除并重新创建表,这比逐行删除行要快得多,尤其是对于大型表。
  2. TRUNCATE 操作会导致隐式提交,因此无法回滚
  3. 如果会话持有活动的表锁,则无法执行 TRUNCATE 操作。
  4. 如果 InnoDB 表或 NDB 表的其他表引用了“FOREIGN KEY”约束,则“TRUNCATE TABLE”失败。允许在同一表的列之间使用外键约束。
  5. TRUNCATE 操作不会为删除的行数返回有意义的值。通常的结果是“受影响的 0 行”,应解释为“无信息”。
  6. 只要表格式文件“tbl_name.frm”有效,就可以使用 “TRUNCATE TABLE” 将表重新创建为空 表,即使数据或索引文件已损坏。
  7. 任何“AUTO_INCREMENT”值都将重置为其初始值。
    即使是MyISAM和InnoDB,也是如此,它们通常不重用序列值。
  8. 与分区表一起使用时,“TRUNCATE TABLE”保留分区;也就是说,数据和索引文件被删除并重新创建,而分区定义(.par)文件不受影响。
  9. “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,而不是删除行。