数据定义语句

目录

 

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语句

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 SCHEMAALTER DATABASE的同义词。

可以从第一种语法中省略数据库名称,在这种情况下,该语句适用于默认数据库。

国家语言特征

CHARACTER SET子句更改默认数据库字符集。COLLATE子句更改默认数据库排序规则。

您可以分别使用SHOW CHARACTER SETSHOW COLLATION 语句查看可用的字符集和排序规则。

如果更改数据库的默认字符集或排序规则,则必须删除并重新创建使用数据库默认值的存储例程,以便它们使用新的默认值。

(在存储的例程中,如果未明确指定字符集或排序规则,则具有字符数据类型的变量将使用数据库默认值。请参见第13.1.16节“ CREATE PROCEDURE和CREATE FUNCTION语句”。)

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语句可以更改现有事件的一个或多个特征,而无需删除并重新创建它。当使用 CREATE EVENT时,此语法适用于每个 DEFINERON SCHEDULEON COMPLETIONCOMMENTENABLE / 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 函数和用户变量的表达式来获取它包含的任何timestampinterval值。

您不能在此类表达式中使用存储的例程或 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;

要执行前一个语句,执行它的用户必须对olddbnewdb数据库都具有EVENT特权。

注意

没有RENAME EVENT语句

DISABLE ON SLAVE被用来复制从站而不是ENABLEDISABLE,以指示在 master 上创建并复制到从站的 event,但不会在从站上执行。通常,DISABLE ON SLAVE会根据需要自动设定;但是,在某些情况下,您可能需要或需要手动更改它。See Section 16.4.1.16, “Replication of Invoked Features”, for more information.

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 }

该语句可用于更改存储函数的特征。ALTER FUNCTION语句中可以指定多个更改 。但是,您不能使用此语句更改参数或存储函数的主体。要进行此类更改,必须使用DROP FUNCTIONCREATE FUNCTION删除并重新创建该函数。

您必须具有ALTER ROUTINE 该功能的特权。(该特权会自动授予函数创建者。)如果启用了二进制日志记录,则该ALTER FUNCTION 语句可能也需要 SUPER特权,如 第23.7节“存储的程序二进制日志记录”中所述

 

ALTER INSTANCE语句

ALTER INSTANCE ROTATE INNODB MASTER KEY

ALTER INSTANCEMySQL 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 语法

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 GROUPENGINE = 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语句

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 PROCEDURECREATE PROCEDURE删除并重新创建该过程。

您必须具有该过程的ALTER ROUTINE特权。默认情况下,该权限自动授予过程创建者。可以通过禁用automatic_sp_privileges系统变量来更改此行为。见第 23.2.2 节,“存储例程和 MySQL 权限”

ALTER SERVER 语法

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 语法

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语句

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 DATAFILEALTER TABLESPACE一起使用会从表空间中删除数据文件“file_name”。您不能从正在使用表的表空间中删除数据文件;换句话说,数据文件必须为空(不使用扩展数据块)。见Section 21.5.13.1,“NDB Cluster Disk Data Objects”。此外,要删除的任何数据文件必须先前已使用 CREATE TABLESPACEALTER TABLESPACE添加到表空间。

ALTER TABLESPACE ... ADD DATAFILEALTER TABLESPACE ... DROP DATAFILE都需要ENGINE子句,该子句指定表空间使用的存储引擎。目前,engine_name唯一可接受的值是 NDBNDBCLUSTER

WAIT被解析但被忽略,因此在 MySQL 5.7 中没有效果。它旨在用于未来的扩展。

ALTER TABLESPACE ... ADD DATAFILEENGINE = 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 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 DATABASE 语法

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 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}

该语句创建并安排新事件。除非启用了事件计划程序,否则事件将不会运行。有关检查事件调度程序状态并在必要时启用它的信息,请参见第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 中有两个名为myeventMyEvent的 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 的表达式。为此,您可以使用 DATETIMETIMESTAMP类型的值,如果 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 intervalENDS;例如,EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK相当于“每十二小时,从现在开始后三十分钟开始重复,从现在开始四周后停止”。不使用ENDS意味着 event 继续无限期执行。

ENDS支持与STARTS相同的复杂 time 单位语法。

您可以在EVERY子句中使用STARTSENDS,两个都用或者两个都不用。

如果重复 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一起使用最为有用。

第三个值也可能代替ENABLEDISABLEDISABLE 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可以通过使用BEGINand 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 INDEX语句

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 索引,其索引键由col1col2col3的值组成。

key_part规范可以以ASCDESC结尾。这些关键字允许用于将来的扩展,以指定升序或降序索引 value 存储。目前,他们被解析但被忽略;索引值始终以升序 order 存储。

以下各节描述了该CREATE INDEX语句的不同方面 :

字段前缀键部分

对于字符串列,可以创建仅使用列值的前导部分的索引,使用col_name(length)语法指定索引前缀长度:

  • 可以为CHARVARCHARBINARYVARBINARY key 部分指定前缀。
  • 前缀必须用于指定 BLOB和 TEXT关键零部件。此外, BLOB和 TEXT列可以只对索引InnoDB, MyISAMBLACKHOLE 表。
  • 前缀限制以字节为单位。但是,CREATE TABLEALTER TABLECREATE INDEX statements 中索引规范的前缀长度被解释为非二进制 string 类型(CHARVARCHAR文本)的字符数和二进制 string 类型(BINARYVARBINARYBLOB)的字节数。在为使用多字节字符集的非二进制 string 列指定前缀长度时,请考虑这一点。

前缀支持和前缀长度(支持的位置)取决于存储引擎。例如,前缀最大可为767个字节对于 InnoDB tables ,如果 innodb_large_prefix变量启用, 可有3072 bytes ;对于 MyISAM tables,前缀长度限制为1000个字节, NDB存储引擎不支持前缀。

从 MySQL 5.7.17 开始,如果指定的索引前缀超过最大列数据类型大小, CREATE INDEX将按如下方式处理索引:

  • 对于非唯一索引,要么发生错误(如果启用了严格的 SQL 模式),要么索引长度减少到最大列数据类型大小,并产生警告(如果未启用严格 SQL 模式)。
  • 对于唯一索引,无论 SQL 模式如何都会发生错误,因为减少索引长度可能会导致插入不符合指定唯一性要求的非唯一条目。

此处显示的语句使用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 KEYUNIQUE NOT NULL索引,该索引由具有 integer 类型的单个列组成,则可以使用 _rowid来引用SELECT 语句中的索引列,如下所示:

  • 如果PRIMARY KEY由单个 integer 列组成,_rowid指的是PRIMARY KEY列。如果有PRIMARY KEY但它不包含单个 integer 列,则不能使用_rowid
  • 否则,如果该索引由单个 integer 列组成,则_rowid引用第一个UNIQUE NOT NULL索引中的列。如果第一个UNIQUE NOT NULL索引不包含单个 integer 列,则不能使用_rowid

Full-Text 索引

FULLTEXT索引仅支持InnoDBMyISAM 数据表,并且只能包含CHARVARCHAR文本列。索引总是发生在整个列上;不支持列前缀索引,如果指定,则忽略任何前缀长度。有关操作的详细信息,请参阅第 12.9 节,“Full-Text 搜索功能”

空间索引

 MyISAMInnoDBNDB, and ARCHIVE 存储引擎支持 POINT and GEOMETRY等空间列。但是,空间列索引的支持因引擎而异。空间列上的空间和非空间索引可根据以下规则使用。

空间列上的空间索引(使用SPATIAL INDEX创建)具有以下特征:

  • 仅适用于MyISAM 数据InnoDB表。为其他存储引擎指定SPATIAL INDEX会导致错误。

  • 索引列必须为NOT NULL

  • 列前缀长度是禁止的。每列的全宽是索引。

 

空间列上的非空间索引(使用INDEXUNIQUEPRIMARY KEY创建)具有以下特征:

  • 允许支持除ARCHIVE之外的任何空间列的存储引擎。
  • 除非索引是主 key,否则列可以是NULL
  • 对于SPATIAL 除POINT列之外的非索引中的每个空间列,必须指定列前缀长度。(这与对索引BLOB列的要求相同 。)前缀长度以字节为单位。
  • SPATIAL索引的索引类型取决于存储引擎。目前,使用 B-tree。
  • 仅允许InnoDB, MyISAM和 MEMORY表可以有一个列NULL 。

索引选项

在 key 部分列表之后,可以给出索引选项。index_option value 可以是以下任何一种:

  • KEY_BLOCK_SIZE [=] value

对于MyISAM 数据表,KEY_BLOCK_SIZE可选地指定用于索引 key 块的大小(以字节为单位)。该值被视为提示,可以使用不同的尺寸。为单个索引定义指定的KEY_BLOCK_SIZE value 会覆盖 table-level KEY_BLOCK_SIZE value。

InnoDB表的索引 level 不支持KEY_BLOCK_SIZE

  • index_type

某些存储引擎允许您在创建索引时指定索引类型。例如:

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 EnginePermissible Index Types
InnoDBBTREE
MyISAMBTREE
MEMORY/HEAPHASHBTREE
NDBHASHBTREE (see note in text)

index_type子句不能用于FULLTEXT INDEXSPATIAL 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 ClassIndex TypeStores NULL VALUESPermits Multiple NULL ValuesIS NULL Scan TypeIS NOT NULL Scan Type
Primary keyBTREENoNoN/AN/A
UniqueBTREEYesYesIndexIndex
KeyBTREEYesYesIndexIndex
FULLTEXTN/AYesYesTableTable
SPATIALN/ANoNoN/AN/A

 MyISAM 存储引擎索引特征

Index ClassIndex TypeStores NULL VALUESPermits Multiple NULL ValuesIS NULL Scan TypeIS NOT NULL Scan Type
Primary keyBTREENoNoN/AN/A
UniqueBTREEYesYesIndexIndex
KeyBTREEYesYesIndexIndex
FULLTEXTN/AYesYesTableTable
SPATIALN/ANoNoN/AN/A

MEMORY 存储引擎索引特征

Index ClassIndex TypeStores NULL VALUESPermits Multiple NULL ValuesIS NULL Scan TypeIS NOT NULL Scan Type
Primary keyBTREENoNoN/AN/A
UniqueBTREEYesYesIndexIndex
KeyBTREEYesYesIndexIndex
Primary keyHASHNoNoN/AN/A
UniqueHASHYesYesIndexIndex
KeyHASHYesYesIndexIndex

NDB 存储引擎索引特征

Index ClassIndex TypeStores NULL VALUESPermits Multiple NULL ValuesIS NULL Scan TypeIS NOT NULL Scan Type
Primary keyBTREENoNoIndexIndex
UniqueBTREEYesYesIndexIndex
KeyBTREEYesYesIndexIndex
Primary keyHASHNoNoTable (see note 1)Table (see note 1)
UniqueHASHYesYesTable (see note 1)Table (see note 1)
KeyHASHYesYesTable (see note 1)Table (see note 1)

Table note:

如果指定了USING HASH,则会阻止创建隐式有序索引。

  • WITH PARSER parser_name

此选项仅可用于FULLTEXT索引。如果 full-text 索引和搜索操作需要特殊处理,它会将解析器插件与索引相关联。 InnoDBMyISAM 数据支持 full-text 解析器插件。

  • COMMENT 'string'

索引定义可以包含最多 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 TABLEand ALTER TABLE语句在索引级别和表级别定义 。

表复制和锁定选项

可以给出ALGORITHMLOCK子句来影响 table 复制方法和 level 并发性,以便在修改索引时读取和写入 table。它们与ALTER TABLE语句具有相同的含义。有关更多信息,请参阅第 13.1.8 节,“ALTER TABLE 语法”

NDB Cluster 以前使用不再支持的替代语法支持在线CREATE INDEX操作。 NDB Cluster 现在支持使用与标准 MySQL 服务器相同的ALGORITHM=INPLACE语法进行在线操作。

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子句。有关 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_SIZENODEGROUPWAITCOMMENT被解析但被忽略,因此在 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 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

 

这些 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 PROCEDURECREATE 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 之前使用关键字OUTINOUT

注意
将参数指定为INOUTINOUT仅对PROCEDURE有效。对于FUNCTION,参数始终被视为IN参数。

IN参数将值传递给过程,该过程可能会修改 value,但过程返回时调用者看不到修改。它的初始 value 在过程中是NULL,当过程返回时,它的 value 对调用者是可见的。INOUT参数由调用者初始化,可以由过程修改,并且过程返回时调用者可以看到过程所做的任何更改。

对于每个OUTINOUT参数,在 CALL语句中传递一个 user-defined 变量来调用该过程,以便在过程返回时获取其 value。如果从另一个存储过程或 function 中调用该过程,还可以将例程参数或本地例程变量作为OUTINOUT参数传递。如果从触发器中调用过程,还可以将NEW.col_name作为OUTINOUT参数传递。

有关未处理条件对过程参数的影响的信息,请参阅第 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, 或使用BEGINEND编写的复合语句。复合语句可以包含声明,循环和其他控制结构 statements。这些 statements 的语法在第 13.6 节,“Compound-Statement 语法”中描述。实际上,存储的函数倾向于使用复合语句,除非正文由单个 RETURN语句组成。

MySQL 允许例程包含 DDL statements,例如CREATEDROP。MySQL 还允许存储过程(但不是存储函数)包含 SQL transaction statements,例如 COMMIT.存储的函数可能不包含执行显式或隐式的提交或回滚语句。  SQL 标准不要求支持这些语句,该标准规定每个 DBMS 供应商可以决定是否允许它们。

语句的返回值可以在存储过程中使用,但不能在存储的 function 中使用。此禁止包括没有INTO var_list子句的 SELECT语句,和 SHOWEXPLAIN, 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 = 1DO RELEASE_LOCK('abc'),它们执行但既不读取也不写入数据。
  • NO SQL表示该例程不包含 SQL statements。
  • READS SQL DATA表示例程包含读取数据的 statements(例如 SELECT),但不包含写入数据的 statements。
  • MODIFIES SQL DATA表示例程包含可以写入数据的语句(例如 INSERT或 DELETE)。

SQL SECURITY特征可以是 DEFINERINVOKER用于指定安全上下文;也就是说,是否执行例程所用的特权账户名来自例程DEFINER子句中指定的帐户或调用它的用户。此帐户必须具有访问与例程关联的数据库的权限。默认的 value 是DEFINER。调用例程的用户必须具有 EXECUTE 特权,如果例程在 definer security context 中执行,则必须具有DEFINER帐户。

DEFINER子句指定在例程执行时检查具有该SQL SECURITY DEFINER特征的例程的访问权限时要使用的MySQL帐户。

如果存在DEFINER子句,user value 应该是指定为'user_name'@'host_name',,CURRENT_USERCURRENT_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或函数返回值创建的局部例程变量 ,如下所示:

  • 检查分配是否存在数据类型不匹配和溢出。转换和溢出问题会导致警告或严格SQL模式下的错误。
  • 只能分配标量值。例如,诸如这样的语句SET x = (SELECT 1, 2)无效。
  • 对于字符数据类型,如果声明中包含CHARACTER SET,则使用指定的字符集及其默认排序规则。如果还存在COLLATE属性,则使用该排序规则而不是默认排序规则。

如果CHARACTER SETCOLLATE不存在,则使用在例程创建 time 时生效的数据库字符集和排序规则。为避免服务器使用数据库字符集和排序规则,请为字符数据参数提供显式CHARACTER SETCOLLATE属性。

如果更改数据库缺省字符集或排序规则,则必须删除并重新创建使用数据库缺省值的存储例程,以便它们使用新的缺省值。

数据库字符集和排序规则由character_set_databasecollation_database系统变量的 value 给出。有关更多信息,请参阅第 10.3.3 节,“数据库字符集和整理”

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 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_nameHostDbUsernamePasswordPortSocket

例如:

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 TABLE 语法

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`

  • IF NOT EXISTS

防止创建的表已存在的错误,但是没有去验证已存在的表的表结构是否与新创建的表的结构相同。

临时表

创建表可以时使用TEMPORARY关键字。一个TEMPORARY表仅在当前会话中可见,并且在关闭会话时会自动删除。

表克隆和复制

  • LIKE

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

CREATE TABLE new_tbl LIKE orig_tbl;
  • [AS] query_expression

从另一个表创建一个新表,请在 CREATE TABLE语句的末尾添加 SELECT 语句:

CREATE TABLE new_tbl AS SELECT * FROM orig_tbl;
  • IGNORE|REPLACE

IGNOREREPLACE选项指示在使用 SELECT 语句复制表时如何处理复制唯一键值的行。

列数据类型和属性

每个表有4096列的硬限制,但是对于给定的表,有效最大值可能会更少,并且取决于第8.4.7节“表的列数和行大小的限制”中讨论的因素。

  • data_type

data_type表示列定义中的数据类型。

  1. 某些属性并不适用于所有数据类型。 AUTO_INCREMENT仅适用于整数和浮点类型。DEFAULT并不适用于BLOB, TEXT, GEOMETRY,和 JSON类型。
  2. 字符数据类型(CHAR, VARCHARTEXT类型, ENUM, SET,和任何同义词)可以包括CHARACTER SET指定该列的字符集。CHARSET 是CHARACTER SET的同义词。可以使用COLLATE属性以及任何其他属性指定字符集的排序规则 。
CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);

MySQL的5.7以字符的形式解释字符列定义中的长度规范。BINARYVARBINARY的长度以字节为单位。

对于CHARVARCHARBINARYVARBINARY列,可以创建仅使用列值的前导部分的索引,使用col_name(length)语法指定索引前缀长度。. BLOB and TEXT columns也能创建索引,但是必须给定前缀长度,对于二进制字符串类型,前缀长度以字节形式给出。也就是说,索引条目包含了字段值类型为 CHARVARCHAR, and TEXT字段值的第一个length (长度)的字符,还有字段值类型为 BINARYVARBINARY, and BLOB的字段值的第一个length (长度)的字节,像这样索引只取字段值的前缀可以使索引文件小很多,有关索引前缀的更多信息,see Section 13.1.14, “CREATE INDEX Statement”.

只有InnoDBMyISAM存储引擎支持 BLOB and TEXT列的索引。

CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));

从MySQL 5.7.17开始,如果指定的索引前缀超过了最大列数据类型的大小,则按 CREATE TABLE以下方式处理索引:

  1. 对于非唯一索引,可能会发生错误(如果启用了严格的SQL模式),或者索引长度被减小到最大列数据类型大小之内,并且会产生警告(如果未启用严格的SQL模式)。
  2. 对于唯一索引,无论SQL模式如何,都会发生错误,因为减小索引长度可能会导致插入不符合指定唯一性要求的非唯一条目。
  3. JSON列无法建立索引。您可以通过在生成的列上创建索引来解决此限制,该索引从列中提取标量值JSON
  • NOT NULL | NULL

如果既未指定NULL也未指定NOT NULL,则将列视为已指定NULL

在MySQL 5.7中,只有InnoDBMyISAMMEMORY存储引擎支持可以具有NULL值的列的索引。在其他情况下,您必须将索引列声明为NOT NULL,否则将导致错误结果。

  • DEFAULT

指定列的默认值。有关默认值处理的更多信息,包括列定义不包含显式DEFAULT 值的情况请参见第11.7节,“数据类型默认值”

如果启用了NO_ZERO_DATE或 NO_ZERO_IN_DATESQL模式,根据该模式使用的日期值默认值不正确,CREATE TABLE 则在未启用严格SQL模式的情况下产生警告,而在启用严格模式的情况下产生错误。例如, 启用NO_ZERO_IN_DATE c1 DATE DEFAULT '2010-00-00'将产生警告。

  • AUTO_INCREMENT

整数或浮点数列可以具有附加属性AUTO_INCREMENT。当您将NULL(推荐)或0的值插入索引的AUTO_INCREMENT列时,该列将设置为下一个序列值。通常为 value+1,其中 value是表中当前列的最大值。 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列仅包含正值时,它才能正常工作。插入负数被替换插入一个非常大的正数。这样做是为了避免数字从正到负“包裹”时的精度问题,并确保您不会意外地获得包含0AUTO_INCREMENT列。

对于MyISAM表,您可以在多列键中指定AUTO_INCREMENT辅助列。

要使MySQL与某些ODBC应用程序兼容,您可以使用以下查询找到最后一个插入行的AUTO_INCREMENT值:

SELECT * FROM tbl_name WHERE auto_col IS NULL

此方法要求sql_auto_is_null变量未设置为0。

有关InnoDBAUTO_INCREMENT的信息,请参见第14.6.1.4节,“ AUTO_INCREMENT在InnoDB中处理”。有关AUTO_INCREMENT和MySQL Replication的信息,请参见第16.4.1.1节,“复制和AUTO_INCREMENT”

  • COMMENT

可以使用COMMENT选项指定列的注释,最多1024个字符长。可以使用SHOW CREATE TABLE and SHOW FULL COLUMNS statements.来查看注释

  • COLUMN_FORMAT

在NDB群集中,还可以使用COLUMN_FORMAT为 NDB表的各列指定数据存储格式。允许的列格式为FIXEDDYNAMICDEFAULTFIXED用于指定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及更高版本中,被默默忽略。

  • STORAGE

对于 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 关键字均无法识别,尝试使用该关键字会导致语法错误。

  • GENERATED ALWAYS

用于指定生成的列表达式。

存储生成的列可以编入索引。 InnoDB支持虚拟生成列上的二级索引。

索引和外键

有几个关键字适用于创建索引和外键。除了以下描述之外,对于一般背景,请参阅第 13.1.14 节,“CREATE INDEX 语法”第 13.1.18.6 节,“使用 FOREIGN KEY 约束”

  • CONSTRAINT symbol

CONSTRAINT symbol子句可以赋予 name 约束。如果未给出该子句,或CONSTRAINT关键字后面不包含symbol,则 MySQL 会自动生成约束 name,并在下面指出表达式。如果使用symbol value,则每个约束类型的 schema(数据库)必须是唯一的。重复symbol会导致错误。

注意

如果未在外键定义中提供该子句,或者在CONSTRAINT关键字后面没有包含symbol则 NDB使用外键索引 name。

SQL 标准指定所有类型的约束 (primary key, unique index, foreign key, check)属于同一名称空间。因此,每种类型约束的名称对于 schema 必须是唯一的。

  • PRIMARY KEY

一个唯一索引,其中所有 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 KEYUNIQUE 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通常是INDEX的同义词。在列定义中,key属性PRIMARY KEY也可以指定为KEY。这是为了与其他数据库系统兼容而实现的。

  • UNIQUE

UNIQUE索引创建一个约束,使索引中的所有值必须是不同的。如果您尝试添加一个 key value 与现有行匹配的新行,则会发生错误。对于所有引擎,UNIQUE索引允许包含可为NULL列的多个NULL值。如果为UNIQUE索引中的列指定前缀 value,则列值必须在前缀长度内是唯一的。

如果 table 具有PRIMARY KEYUNIQUE NOT NULL索引,该索引由具有 integer 类型的单个列组成,则可以使用_rowid来引用SELECT statements 中的索引列,如Unique Indexes.中所述。

  • FULLTEXT

FULLTEXT索引是用于 full-text 搜索的特殊索引类型。只有InnoDBMyISAM 数据存储引擎支持FULLTEXT索引。它们只能从CHARVARCHAR文本列创建。索引总是在整个列上进行;不支持列前缀索引,并且如果指定,则将忽略任何前缀长度。如果 full-text 索引和搜索操作需要特殊处理,则可以将WITH PARSER子句指定为index_option value 以将解析器插件与索引相关联。该子句仅对FULLTEXT索引有效。 InnoDBMyISAM 数据都支持 full-text 解析器插件。

  • SPATIAL

您可以在空间数据类型上创建SPATIAL索引。空间类型仅支持MyISAMInnoDB表,索引列必须声明为NOT NULL

  • FOREIGN KEY

MySQL 支持外键,这些外键使您可以跨表交叉引用相关数据,外键约束可以帮助保持扩展数据的一致性。有关定义和选项的信息,请参见 reference_definition和 reference_option

  • CHECK

CHECK子句被解析但被所有存储引擎忽略。

  • key_part
  1. key_part规范可以以ASCDESC结尾。这些关键字允许将来用于指定升序或降序索引值存储的扩展。目前,它们已被解析但被忽略;索引值始终按升序存储。
  2. length属性定义的前缀对于InnoDB表最多可为 767 字节 (如果启用innodb_large_prefix选项,则为 3072 字节),对于MyISAM表,前缀长度限制为 1000 个字节。

前缀限制以字节为单位。但是CREATE TABLEALTER TABLECREATE INDEX语句中索引规范的前缀长度被解释为非二进制 string 类型(CHARVARCHAR, TEXT)的字符数和二进制 string 类型(BINARYVARBINARYBLOB)的字节数。在为使用多字节字符集的非二进制 string 列指定前缀长度时,请考虑这一点。

  • index_type

某些存储引擎允许您在创建索引时指定索引类型。 index_type说明符的语法是USING type_name

CREATE TABLE lookup
  (id INT, INDEX USING BTREE (id))
  ENGINE = MEMORY;

首选位置USING在索引列列表之后。可以在列列表之前给出它,但是不赞成在该位置使用该选项,并且在以后的MySQL版本中将删除该支持。

  • index_option

index_option values 指定索引的其他选项。

  • KEY_BLOCK_SIZE

对于MyISAM表, KEY_BLOCK_SIZE可以选择指定用于索引键块的字节大小。该值被视为提示;如有必要,可以使用其他大小。KEY_BLOCK_SIZE为单个索引定义指定的值将覆盖表级KEY_BLOCK_SIZE值。有关表级 KEY_BLOCK_SIZE属性的信息,请 参见表选项

  • WITH PARSER

WITH PARSER选项只能与FULLTEXT索引一起使用。如果 full-text 索引和搜索操作需要特殊处理,它会将解析器插件与索引相关联。

 InnoDBMyISAM 数据都支持 full-text 解析器插件。如果你有一个带有关联 full-text 解析器插件的MyISAM 数据 table,你可以使用ALTER TABLE将 table 转换为InnoDB

  • COMMENT

在 MySQL 5.7 中,索引定义可以包含最多1024个字符的可选注释。

您可以使用index_option COMMENT子句为单个索引设置InnoDB MERGE_THRESHOLD value。

  • reference_definition

InnoDB和 NDB表支持检查外键约束。被引用表的列必须始终明确命名。支持外键上的ON DELETEON UPDATE操作。

对于其他存储引擎,MySQL Server 解析并忽略 CREATE TABLE语句中的FOREIGN KEYREFERENCES语法。

重要

对于熟悉 ANSI/ISO SQL 标准的用户,请注意,任何存储引擎(包括InnoDB)都不会识别或强制执行参照完整性约束定义中使用的MATCH子句。使用显式MATCH子句将不具有指定的效果,并且还会导致忽略ON DELETEON UPDATE子句。出于这些原因,应避免指定MATCH

SQL 标准中的MATCH子句控制在与主 key 进行比较时如何处理复合(multiple-column)外键中的NULL值。 InnoDB本质上实现了MATCH SIMPLE定义的语义,它允许外部 key 全部或部分NULL。在这种情况下,允许插入包含此类外键的(child table)行,并且该行与引用的(父)表中的任何行都不匹配。使用触发器可以实现其他语义。

另外,MySQL要求对引用的列进行索引以提高性能。但是,InnoDB 不强制要求将引用的列声明为UNIQUENOT NULL。对于诸如UPDATE或DELETE CASCADE之类的操作,对非唯一键或包含空值的键的外键引用的处理没有很好地定义。建议您使用只引用UNIQUE(或PRIMARY)和NOT NULL的的外键。

MySQL解析但忽略“ 内联 REFERENCES规范 ”(如SQL标准所定义),其中引用被定义为列规范的一部分。 MySQL 仅在指定为单独的FOREIGN KEY规范的一部分时才接受REFERENCES子句。

 

  • reference_option

有关RESTRICTCASCADESET NULLNO ACTIONSET DEFAULT选项的信息,请参阅第 13.1.18.6 节,“使用 FOREIGN KEY 约束”

 Table 选项

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

  • ENGINE

使用下表中显示的名称之一指定表的存储引擎。引擎名称可以不加引号或加引号。引号名称 'DEFAULT'可以识别但可以忽略。

Storage EngineDescription
InnoDBTransaction-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的同义词。
MERGEA 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 中,这适用于MyISAMMEMORYInnoDBARCHIVE表。要为不支持该AUTO_INCREMENT表选项的引擎设置第一个自动增量值,请在创建表后插入一个“ dummy ”行,其值比期望值小一,然后删除该虚拟行。

对于支持CREATE TABLEstatements 中的AUTO_INCREMENT table 选项的引擎,您还可以使用ALTER TABLE tbl_name AUTO_INCREMENT = N重置AUTO_INCREMENT value。 value 不能设置为低于列中当前的最大 value。

  • AVG_ROW_LENGTH

表的平均行长的近似值。您仅需要为具有可变大小行的大型表设置此选项。

创建MyISAM表时,MySQL使用MAX_ROWS和 AVG_ROW_LENGTH选项的乘积来确定结果表的大小。如果您未指定任何选项,则MyISAM默认情况下,数据和索引文件的最大大小为256TB。(如果操作系统不支持那么大的文件,则表的大小受文件大小限制的约束。)如果要减小指针大小以使索引变小和变快,而且实际上并不需要大文件,则可以通过设置myisam_data_pointer_size 系统变量来减小默认指针大小 。

  • [DEFAULT] CHARACTER SET

指定 table 的默认字符集。 CHARSETCHARACTER SET的同义词。如果字符集 name 是DEFAULT,则使用数据库字符集。

  • CHECKSUM

如果您希望MySQL维护所有行的实时校验和(即,当表更改时MySQL自动更新的校验和),请将其设置为1。这使表的更新速度稍慢,但也更容易找到损坏的表。

  • [DEFAULT] COLLATE

指定 table 的默认排序规则。

  • COMMENT

table 的 comment,最多 2048 个字符 long。

您可以使用table_option COMMENT子句为 table 设置InnoDB MERGE_THRESHOLD value。

Setting NDB_TABLE options.  

在 MySQL NDB Cluster 7.5.2 及更高版本中,CREATE TABLEALTER TABLE语句中的 table comment 也可用于指定一至四个NDB_TABLE选项NOLOGGINGREAD_BACKUPPARTITION_BALANCEFULLY_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选项(忽略它)。

  • COMPRESSION

用于InnoDB表的页面 level 压缩的压缩算法。支持的值包括ZlibLZ4NoneCOMPRESSION 属性是通过透明页面压缩功能引入的

页面压缩仅受驻留在file-per-table表空间中的InnoDB表的支持,并且仅在支持稀疏文件和打孔的Linux和Windows平台上可用。

  • CONNECTION

FEDERATED 表 的连接字符串。

注意

较早版本的MySQL使用COMMENT 连接字符串选项。

  • DATA DIRECTORY , INDEX DIRECTORY

对于InnoDBDATA DIRECTORY='directory'子句允许在数据目录之外创建 file-per-table 表空间。表空间数据文件在指定目录中创建,该目录位于与 schema 具有相同 name 的子目录中。必须启用innodb_file_pertable变量才能使用DATA DIRECTORY子句。必须指定完整目录路径。
在创建MyISAM表时,可以使用DATA DIRECTORY='directory'子句,INDEX DIRECTORY='directory'子句或两者。它们分别指定放置MyISAM table 的数据文件和索引文件的位置。与InnoDB表不同,当_用DATA DIRECTORYINDEX DIRECTORY选项创建MyISAM table 时,MySQL 不会创建与数据库 name 对应的子目录。 Files 在指定的目录中创建。

从 MySQL 5.7.17 开始,您必须具有FILE特权才能使用DATA DIRECTORYINDEX 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 DIRECTORYINDEX DIRECTORY选项创建MyISAM table 并且找到现有的.MYD.MYI文件,则 MyISAM 始终返回错误。它不会覆盖指定目录中的文件。

重要
您不能将包含 MySQL 数据目录的路径名用于DATA DIRECTORYINDEX DIRECTORY。这包括分区表和单个 table 分区。 (见 Bug#32167.)

  • DELAY_KEY_WRITE

如果要延迟 table 的 key 更新,直到 table 关闭,请将此值设置为 1

  • ENCRYPTION

ENCRYPTION选项设置为'Y',以便为file-per-table表空间中创建的InnoDB table 启用 page-level 数据加密。选项值不是 case-sensitive。 ENCRYPTION选项是在InnoDB tablespace encryption feature 中引入的;

  • INSERT_METHOD

如果要将数据插入MERGE table,则必须使用INSERT_METHOD指定要插入行的 table。 INSERT_METHOD是仅对MERGE表有用的选项。使用FIRSTLAST的值将插入转到第一个或最后一个 table,或使用 value NO来防止插入。

  • KEY_BLOCK_SIZE

对于MyISAM 数据表,KEY_BLOCK_SIZE可选地指定用于索引 key 块的大小(以字节为单位)。 value 被视为提示;如有必要,可以使用不同的尺寸。为单个索引定义指定的KEY_BLOCK_SIZE value 会覆盖 table-level KEY_BLOCK_SIZE value。

太多了,暂略,待补充。

 CREATE TABLE语句保留

CREATE TABLE 创建表时, 原始语句(包括所有规范和表选项)由MySQL存储。该信息将保留,以便在您使用ALTER TABLE语句更改存储引擎,排序规则或其他设置时,保留指定的原始表选项。即使两个引擎支持的行格式不同,这也使您可以在InnoDB和 MyISAM表类型之间进行切换 。

因为保留了原始语句的文本,但是由于某些值和选项可能以静默方式重新配置(例如ROW_FORMAT),因此,活动表定义(可通过DESCRIBE或通过 SHOW TABLE STATUS进行访问)和表创建字符串(可通过进行SHOW CREATE TABLE访问)将报告不同的值。

通过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.frmTable 格式(定义)文件
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_lengthENUM和 SET 列的值列表相关。在这个 context 中,“ int”并不意味着“integer”。它表示“间隔”,一个统称为ENUM和 SET 列的术语。
  • int_count是唯一ENUM和 SET 定义的数量。
  • com_length是列 comments 的总长度。

刚才描述的表达式对允许的 table 定义有几个含义

  • 使用 long 列名称可以减少最大列数,也可以包含ENUM或 SET 列,或使用列 comments。
  • table 可以具有不超过 255 个唯一的ENUM定义。具有相同元素 lists 的列被认为与此 limt 相同。例如,如果 table 包含这两列,则它们将计为一个(而不是两个),因为定义相同:
e1 ENUM('a','b','c')
e2 ENUM('a','b','c')

唯一ENUM和 SET 定义中元素名称长度的总和计入 64KB 限制,因此尽管给定ENUM列中元素数量的理论限制为 65,535,但实际限制小于 3000。

CREATE TEMPORARY TABLE 语法

创建 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, INSERTUPDATE,或 SELECT

这种行为的一个暗示是,即使当前用户没有创建临时表的权限,会话也可以操纵其临时表。假设当前用户没有CREATE TEMPORARY TABLES 特权,但是能够执行定义者上下文存储过程,该存储过程以拥有CREATE TEMPORARY TABLES并创建临时表的用户的特权执行。在执行过程时,会话将使用定义用户的特权。该过程返回后,有效特权将恢复为当前用户的特权,该用户仍可以看到临时表并对其执行任何操作。

注意

自MySQL 5.7.24起, CREATE TEMPORARY TABLE不再支持TABLESPACE = innodb_file_per_tableand TABLESPACE = innodb_temporary子句,会在将来的MySQL版本中移除。

 

CREATE TABLE ... LIKE 语法

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

CREATE TABLE new_tbl LIKE orig_tbl;

使用与原始表相同的表存储格式版本创建副本。原始 table 需要SELECT特权。

LIKE 仅适用于基表,不适用于视图。

重要
锁表语句生效时,您无法执行CREATE TABLECREATE TABLE ... LIKE

CREATE TABLE ... LIKECREATE TABLE 进行相同的检查,并不只是复制.frm文件。这意味着如果当前 SQL 模式与创建原始 table 时生效的模式不同,则对于新模式,table 定义可能被视为无效,并且语句将失败。

对于CREATE TABLE ... LIKE,目标 table 保留原始 table 中生成的列信息。

CREATE TABLE ... LIKE不保留为原始表指定的任何 DATA DIRECTORYINDEX DIRECTORY表选项,或任何外键定义。

如果原始 table 是TEMPORARY table,则CREATE TABLE ... LIKE不会保留TEMPORARY。要创建TEMPORARY目标 table,请使用CREATE TEMPORARY TABLE ... LIKE

CREATE TABLE ... SELECT 语法

您可以通过在 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表有三列,ab,和 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之前加IGNOREREPLACE来指示如何处理重复的唯一键值的行。使用IGNORE,将删除在唯一键值上重复存在的行,使用REPLACE时,新行将替换相同唯一索引键的值。如果既未指定IGNORE也未指定REPLACE,则重复的唯一 key 值将导致错误。

 SELECT语句表下面的行顺序始终无法确认,因此CREATE TABLE ... IGNORE SELECTCREATE 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 SETCOLLATIONCOMMENT, 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的一部分。如果您尝试这样做,则该语句失败。

使用 FOREIGN KEY 约束

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关键字之后未包含符号 :
  1. 对于InnoDB表,将自动生成约束名称。
  2. 对于NDB表,使用该 FOREIGN KEY index_name值(如果已定义)。否则,将自动生成约束名称。
  • CONSTRAINT symbol值(如果已定义)在数据库中必须唯一。重复symbol会导致类似以下错误错误1005(HY000):无法创建表'test.fk1'(errno:121)。 

条件和限制

外键约束受以下条件和限制的约束:

  • 父表和子表必须使用相同的存储引擎,并且不能将它们定义为临时表。
  • 创建外键约束需要父表具有REFERENCES特权。
  • 外键和引用键中的对应列必须具有相似的数据类型。整数类型的大小和符号必须相同。字符串类型的长度不必相同。对于非二进制(字符)字符串列,字符集和排序规则必须相同。
  • MySQL支持表中一列与另一列之间的外键引用。(一列不能对其自身进行外键引用。)在这些情况下, “ 子表记录 ”是指同一表中的从属记录。
  • MySQL需要在外键和引用键上建立索引,以便外键检查可以快速进行,而无需进行表扫描。在引用表中,必须有一个索引,其中外键列以相同的顺序列为 第一列。如果这样的索引不存在,则会在引用表上自动创建。如果您创建另一个可用于强制执行外键约束的索引,则以后可能会静默删除该索引。 index_name如果给定,则如前所述使用。
  • InnoDB允许外键引用任何索引列或列组。但是,在引用表中,必须有一个索引,其中引用列是 相同顺序的第一列。InnoDB还考虑了添加到索引的隐藏列 

NDB在引用为外键的任何列上都需要一个显式唯一键(或主键)。 InnoDB不需要,这是标准SQL的扩展。

  • 不支持外键列上的索引前缀。因此,BLOB和 TEXT列不能包含在外键中,因为这些列上的索引必须始终包含前缀长度。
  • InnoDB当前不支持具有用户定义分区的表的外键。这包括父表和子表。

此限制不适用于由KEYLINEAR KEY(NDB存储引擎支持的唯一用户分区类型)分区的NDB表;它们可能具有外键引用,也可能是此类引用的目标。

  • 具有外键关系的表不能更改为使用其他存储引擎。要更改存储引擎,必须首先删除任何外键约束。
  • 外键约束不能引用虚拟生成的列。
  • 在5.7.16之前,外键约束不能引用在虚拟生成的列上定义的二级索引。

Referential Actions(参照动作)

当“ UPDATE或” DELETE操作影响子表中具有匹配行的父表中的键值时,结果取决于使用FOREIGN KEY子句的ON UPDATEON DELETE子句指定的引用操作。 MySQL 支持关于要采取的操作的五个选项,如下所示:

  • CASCADE:删除或更新 parent table 中的行,并自动删除或更新 child table 中的匹配行。支持ON DELETE CASCADEON UPDATE CASCADE。在两个表之间,不要定义几个ON UPDATE CASCADE子句作用于 parent table 或 child table 中的同一列。

如果在外键关系中的两个表上定义FOREIGN KEY子句,使两个表成为 parent 和 child,则必须在 order 中为另一个FOREIGN KEY子句定义ON UPDATE CASCADEON DELETE CASCADE子句,以便成功进行级联操作。如果仅为一个FOREIGN KEY子句定义了ON UPDATE CASCADEON DELETE CASCADE子句,则级联操作将失败并显示错误。

注意

级联的外键操作不会激活触发器。

  • SET NULL:删除或更新 parent table 中的行,并将 child table 中的外键列设置为NULL。支持ON DELETE SET NULLON UPDATE SET NULL子句。如果指定SET NULL操作,请确保未将 child table 中的列声明为NOT NULL
  • RESTRICT:拒绝 parent table 的删除或更新操作。指定RESTRICT(或NO ACTION)与省略ON DELETEON UPDATE子句相同。
  • NO ACTION:标准SQL中的关键字。在MySQL中,等效于RESTRICT。如果引用表中有相关​​的外键值,则MySQL服务器会拒绝父表的删除或更新操作。某些数据库系统具有延迟检查,并且NO ACTION是延迟检查。在MySQL中,外键约束会立即检查,因此NO ACTION与相同RESTRICT
  • SET DEFAULT:MySQL 解析器识别此操作,但InnoDB导航台拒绝包含ON DELETE SET DEFAULTON UPDATE SET DEFAULT子句的 table 定义。

对于未指定的ON DELETEON UPDATE,默认操作始终为RESTRICT

对于支持外键的存储引擎,MySQL将拒绝任何INSERT或 UPDATE操作,如果有父表中没有匹配的候选键值试图创建一个子表的外键的值。

对于未指定的ON DELETEON 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;

二级索引和生成的列

设置NDB_TABLE选项

 

 

CREATE TABLESPACE语句

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 [=] tablespacenameALTER 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_SIZEINITIAL_SIZE时,您可以选择使用带有 one-letter 缩写的数字作为数量级,类似于my.cnf中使用的数字。通常,这是字母M(兆字节)或G(千兆字节)之一。

INITIAL_SIZEEXTENT_SIZE需要四舍五入如下:

  • EXTENT_SIZE向上舍入到最近的 32K 的整数倍。
  • INITIAL_SIZE向下舍入到最近的 32K 的整数倍;此结果向上舍入到EXTENT_SIZE(在四舍五入后)最接近的整数倍。

刚才描述的舍入是明确完成的,当执行任何这样的舍入时,MySQL 服务器会发出警告。 NDB 内核还使用舍入值来计算INFORMATIONSCHEMA.FILES列值和其他用途。但是,为避免出现意外结果,我们建议您在指定这些选项时始终使用 32K 的整数倍。

CREATE TABLESPACEENGINE [=] 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,则表空间只能包含具有未压缩行格式(COMPACTREDUNDANTDYNAMIC)的表。具有COMPRESSED行格式的表具有与未压缩表不同的物理页大小。因此,压缩表不能与未压缩表共存于同一表空间中。

对于包含压缩表的常规表空间,必须指定FILE_BLOCK_SIZE,并且FILE_BLOCK_SIZE value 必须是与innodb_page_size value 相关的有效压缩页大小。此外,压缩 table(KEY_BLOCK_SIZE)的物理页面大小必须等于FILE_BLOCK_SIZE/1024

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

schema 命名空间中存在触发器名称,这意味着所有触发器在 schema 中必须具有唯一的名称。不同模式中的触发器可以具有相同的 name。

创造触发器需要与触发器关联的 table 的触发特权。如果存在DEFINER子句,则所需的权限取决于user value,如果启用了 binary logging,则创造触发器可能需要特权

DEFINER子句确定在触发器激活 time 时检查访问权限时要使用的安全性 context,如本节后面所述。

trigger_time是触发器动作 time。它可以是BEFOREAFTER,表示触发器在每行要修改之前或之后激活。

基本列 value 检查在触发器激活之前发生,因此您不能使用BEFORE触发器将不适合列类型的值转换为有效值。

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

trigger_event不代表文本类型激活触发器的语句,因为它代表了一种类型的表操作的SQL语句。例如, INSERT触发器不仅会激活INSERT语句,还会 激活LOAD DATA语句,因为这两个语句都会在表中插入行。

一个可能令人困惑的示例是INSERT INTO ... ON DUPLICATE KEY UPDATE ...语法:BEFORE INSERT触发器为每一行激活,后跟AFTER INSERT触发器或BEFORE UPDATEAFTER UPDATE触发器,具体取决于该行是否有重复的 key。

 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子句时替换现有视图。如果视图不存在,则创建或替换视图创建视图相同。如果视图确实存在,创建或替换视图将替换它。

DROP DATABASE 语法

DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

DROP DATABASE删除数据库中的所有表并删除数据库。对此声明要非常小心!要使用DROP DATABASE,您需要数据库的DROP特权。 DROP SCHEMADROP DATABASE的同义词。 

DROP EVENT语句

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 语法

DROP FUNCTION语句用于删除存储的函数和 user-defined 函数(UDF):

 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从 table tbl_name中删除名为index_name的索引。此语句映射到ALTER TABLE语句以删除索引。

要删除主 key,索引 name 始终为PRIMARY,必须将其指定为带引号的标识符,因为PRIMARY是保留字:

DROP INDEX `PRIMARY` ON t;

DROP LOGFILE GROUP 语法

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 和 DROP FUNCTION 语法

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 语法

DROP SERVER [ IF EXISTS ] server_name

删除名为server_name的服务器的服务器定义。 mysql.servers table 中的相应行将被删除。此语句需要 SUPER特权。

删除 table 的服务器不会影响在创建它们时使用此连接信息的任何FEDERATED表。

DROP SERVER导致隐式提交。

无论正在使用的 logging 格式如何,DROP SERVER都不会写入二进制 log。

DROP TABLE 语法

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表的好方法。

RESTRICTCASCADE关键字不执行任何操作。允许它们从其他数据库系统中轻松移植。

所有innodb_force_recovery设置均不支持DROP TABLE

DROP TABLESPACE 语法

DROP TABLESPACE tablespace_name
    [ENGINE [=] engine_name]

此语句删除以前使用 CREATE TABLESPACE创建的表空间。它支持所有 MySQL NDB Cluster 7.5 版本,以及标准 MySQL 服务器中的InnoDB

ENGINE使用表空间放置存储引擎,其中engine_name是存储引擎的 name。目前,支持值InnoDBNDB。如果未设置,则使用 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删除表空间。
  • 与系统表空间类似,截断或删除存储在通用表空间中的表会在通用表空间.ibd 数据文件内部创建可用空间,该空间只能用于新的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 语法

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 语法

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

RESTRICTCASCADE(如果提供)将被解析并忽略。

RENAME TABLE 语法

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 TABLEALTER 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

TRUNCATE TABLE完全清空一张表。它需要DROP 特权。

从逻辑上讲,TRUNCATE TABLE它类似于DELETE删除所有行的语句或DROP TABLEand CREATE TABLE 语句的序列。为了获得高性能,它绕过了删除数据的DML方法。因此,它不能回滚,它不会导致ON DELETE触发器触发,也不能对InnoDB具有父子外键关系的表执行。

虽然TRUNCATE TABLE类似于DELETE,但它被归类为 DDL 语句而不是 DML 语句。它在以下方面与 DELETE不同:

  • 截断操作可删除并重新创建表,这比一一删除行要快得多,特别是对于大型表。
  • 截断操作会导致隐式提交,因此无法回滚。
  • 如果会话持有活动表锁,则无法执行截断操作。
  • 对于InnoDB table和 NDB table,如果有任何其他表的外键约束来引用此表,则TRUNCATE TABLE 会失败,允许使用相同 table 的列之间的外键约束。
  • 截断操作不会为已删除的行数返回有意义的 value。通常的结果是“0 行受影响”,应该被解释为“没有信息”。
  • 只要表格式文件 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 COMMITTEDREAD 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,而不是删除行。

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值