13章SQL语句语法

目录

13.1数据定义语句
13.1.1原子数据定义语句的支持
13.1.2数据库语句的句法
13.1.3改变事件语法
13.1.4改变函数的语法
13.1.5改变实例的语法
13.1.6改变程序的语法
改变服务器13.1.7 syntax
13.1.8修改表的语法
13.1.9改变表空间语法
13.1.10改变视图的语法
13.1.11创建数据库的语法
13.1.12创建事件语法
13.1.13创建函数的语法
13.1.14创建索引的语法
13.1.15创建过程和创建函数的语法
13.1.16创建服务器的语法
13.1.17创造空间参考系统的语法
13.1.18创建表的语法
肌酸片合成器
13.1.20创建触发器的语法
13.1.21创建视图的语法
13.1.22删除数据库的语法
排气合成器
13.1.24降功能语法
13.1.25删除索引的语法
13.1.26下降过程和降功能语法
13.1.27滴Server语法
13.1.28下降空间参考系统的语法
13.1.29下拉表的语法
13.1.30删除表空间语法
13.1.31删除触发器语法
13.1.32删除视图的语法
13.1.33重命名表语法
13.1.34截断表语法
13.2 . Data Managing statements
13.2.1调用语法
13.2.2删除语法
13.2.3的语法
13.2.4样本处理表
13.2.5进口表的语法
13.2.6插入语法
13.2.7 LOAD DATA INFILE语法
13.2.8加载XML语法
13.2.9取代语法
13.2.10 SELECT语法
13.2.11查询语法
13.2.12更新语法
13.2.13语法(公用表表达式)
13.3事务和锁的陈述
13.3.1启动事务,提交和回滚语法
13.3.2语句不能回滚
13.3.3陈述引起隐式提交
13.3.4保存点回滚保存点和两个保存点语法,释
13.3.5备份锁和解锁实例语法实例
13.3.6表加锁和解锁表语法
13.3.7事务语法
13.3.8 XA事务
13.4 .折叠定制
13.4.1控制主服务器的SQL语句
13.4.2控制从服务器的SQL语句
控制组的复制13.4.3 SQL语句
13.5编写的SQL语句的语法
13.5.1准备表
13.5.2执行语法
13.5.3释放准备表
13.6复合语句语法
13.6.1开始…端复合语句语法
13.6.2 syntax语言标签
13.6.3声明的语法
13.6.4变量中存储的程序
13.6.5流控制语句
13.6.6 cursors
13.6.7条件处理
13.7数据库管理报表
13.7.1账户管理报表
13.7.2资源集团管理报表
13.7.3表维护报表
13.7.4组件,插件,和用户定义的函数语句
13.7.5集语法
13.7.6显示语法
13.7.7其他管理报表
13.8实用语句
138.SYNTAX描述
13.8.2解释语法
13.8.3语法帮助
13.8.4使用语法

本章描述的语法SQLMySQL的负载模式的声明。

13.1数据定义语句

13.1.1原子数据定义语句的支持

MySQL 8支持原子数据定义语言(DDL)语句。此功能称为原子DDL。一个原子的DDL语句将数据字典的更新,存储引擎的操作,和二进制日志写入相关的DDL操作成一个单一的原子事务。事务提交,适用的改变保存到数据字典,存储引擎,和二进制日志,或回滚,即使服务器停止运行期间。

Atomic DDL是由MySQL 8 MySQL数据字典的引入成为可能。在早期的MySQL版本,元数据存储在元数据文件,非事务表,存储引擎特定的字典,这中间有必要。集中、事务元数据存储由MySQL数据字典提供了消除这一障碍,使它能够重组DDL语句操作原子事务。

原子DDL的特征是本节中的以下主题下的描述:

支持DDL语句

原子DDL功能支持表、无表的DDL语句。表相关的DDL操作需要的存储引擎的支持,而非表的DDL操作不。目前,只有InnoDB存储引擎支持原子DDL。

  • 支持表的DDL语句包括CREATE改变,和DROP报表数据库、表空间、表和索引,和TRUNCATE TABLE声明

  • 支持非表的DDL语句包括:

    • CREATE报表,以及,如果适用,ALTER用于存储程序,触发器,视图报表和用户自定义函数(UDF)。

    • 账户管理报表:CREATE改变DROP,和,如果适用,重命名为用户和角色的陈述,以及GRANTREVOKE声明.

下面的语句是不是由原子DDL支持特征:

Atomic DDL的特点

原子DDL语句的特点包括以下内容:

  • 元数据更新,二进制日志中写道,和存储引擎的操作,在适用的情况下,组合成一个单一的交易。

  • 有没有中间层即在SQL DDL操作期间。

  • 在适用:

    • 数据字典、程序、事件的状态,和UDF的缓存与DDL操作的状态一致,即高速缓存被更新以反映是否DDL操作成功完成或回滚。

    • 存储引擎的方法涉及一个DDL操作不执行中间有、和存储引擎寄存器本身作为交易的一部分的DDL。

    • 存储引擎支持重做和DDL操作回滚,这是对的后DDL在DDL操作阶段

  • DDL操作的可见行为的原子,从而改变一些DDL语句的行为。看到在DDL语句的行为变化

笔记

DDL语句,原子或其他任何隐式结束当前会话中是活跃的交易,如果你做了COMMIT在执行该语句。这意味着,DDL语句不能在另一个事务内执行,如事务控制语句START TRANSACTION ... COMMIT,或结合在同一个交易的其他报表。

在DDL语句的行为变化

本节描述了由于原子DDL支持介绍DDL语句的行为变化。

  • DROP TABLE如果所有的命名表使用一个原子的DDL支持的存储引擎的操作是完全原子。声明或者丢弃所有表成功或回滚。

    DROP TABLE失败与错误如果命名表不存在,并没有改变,不管存储引擎。这种行为的变化是在以下的例子证明,在DROP TABLE因为一个命名表不存在语句失败:

    MySQL的>CREATE TABLE t1 (c1 INT);MySQL的>DROP TABLE t1, t2;错误1051(未知42s02):表”测试。t2'mysql >SHOW TABLES;|表出发_ in _测试|出发| T1 |出发

    在原子的DDL出台之前,DROP TABLE报告指定的表不存在但成功的命名表,确实存在一个错误:

    MySQL的>CREATE TABLE t1 (c1 INT);MySQL的>DROP TABLE t1, t2;错误1051(未知42s02):表”测试。t2'mysql >SHOW TABLES;空集(0.001秒)
    笔记

    由于这种行为的变化,部分完成DROP TABLE在MySQL 5.7主失败时,复制到MySQL 8奴隶的声明。为了避免这种失败的情况下,使用如果存在语法DROP TABLE语句来阻止错误的发生不存在的表。

  • DROP DATABASE如果所有的表使用的是原子的原子DDL支持的存储引擎。声明或者丢弃所有对象成功或回滚。然而,从文件系统中移除数据库目录过去发生的并不是原子交易的一部分。如果由于文件系统错误或服务器停止数据库目录去除失败的DROP DATABASE交易不是回滚

  • 表不使用存储引擎原子DDL,表缺失时外面的atomicDROP TABLEDROP DATABASE交易这样的表删除写入二进制日志单独,这限制了存储引擎之间的差异数据字典,和二进制日志到一个表在一个中断的情况最DROP TABLEDROP DATABASE运营操作删除多个表,不使用存储引擎原子DDL表格被放弃之前,做表。

  • CREATE TABLEALTER TABLERENAME TABLETRUNCATE TABLECREATE TABLESPACE,和DROP TABLESPACE表格使用存储引擎原子DDL操作要么全部提交或回滚如果服务器在运行过程中死机。在早期的MySQL版本,这些操作的中断可能导致存储引擎之间的差异数据字典,和二进制日志文件,或留下的孤儿。RENAME TABLE如果所有的命名表使用一个原子的DDL支持的存储引擎操作是原子。

  • DROP VIEW如果一个未命名视图不存在,并且不进行任何更改。在行为的改变是这个例子表明,在DROP VIEW因为一个命名视图不存在语句失败:

    MySQL的>CREATE VIEW test.viewA AS SELECT * FROM t;MySQL的>DROP VIEW test.viewA, test.viewB;错误1051(未知42s02):表”测试。viewb'mysql >SHOW FULL TABLES IN test WHERE TABLE_TYPE LIKE 'VIEW';---------------- ------------ | tables_in_test | table_type | ---------------- ------------ |一|观| ---------------- ------------

    在原子的DDL出台之前,DROP VIEW返回指定的视图不存在但成功的命名来看,确实存在一个错误:

    MySQL的>CREATE VIEW test.viewA AS SELECT * FROM t;MySQL的>DROP VIEW test.viewA, test.viewB;错误1051(未知42s02):表”测试。viewb'mysql >SHOW FULL TABLES IN test WHERE TABLE_TYPE LIKE 'VIEW';空集(0.001秒)
    笔记

    由于这种行为的变化,部分完成DROP VIEW在MySQL 5.7主失败时,复制到MySQL 8从操作。为了避免这种失败的情况下,使用如果存在语法DROP VIEW语句来防止错误发生的视图不存在。

  • 账户管理报表部分的执行不再是允许的。账户管理报表要么成功,所有指定用户或回滚,如果出现错误没有影响。在早期的MySQL版本,账户管理报表名称多个用户能够成功的和失败的人对一些用户。

    在行为的改变是这个例子表明,在第二CREATE USER语句将返回一个错误而失败,因为它不能为所有指定用户成功。

    MySQL的>CREATE USER userA;MySQL的>CREATE USER userA, userB;错误1396(hy000):操作创建用户失败的用户“@ % 'mysql >SELECT User FROM mysql.user WHERE User LIKE 'user%';用户| ------- | ------- | usera | -------

    在原子的DDL出台之前,第二CREATE USER语句返回指定的用户不存在,但成功的命名用户,确实存在一个错误:

    MySQL的>CREATE USER userA;MySQL的>CREATE USER userA, userB;错误1396(hy000):操作创建用户失败的用户“@ % 'mysql >SELECT User FROM mysql.user WHERE User LIKE 'user%';用户| ------- | ------- | usera | | USERb | -------
    笔记

    由于这种行为的变化,部分完成的账户管理报表在MySQL 5.7主失败时,复制到MySQL 8的奴隶。为了避免这种失败的情况下,使用IF EXISTS如果不存在语法,适当的账户管理报表,以防止用户错误相关的命名。

存储引擎支持

目前,只有InnoDB存储引擎支持原子DDL。不支持原子DDL存储引擎免征DDL的原子性。DDL操作涉及免税存储引擎仍然能够引入不一致时可能发生的操作中断或只有部分完成。

支持重做和DDL操作回滚,InnoDBDDL日志写的mysql.innodb_ddl_log表,这是一个隐藏的数据字典表驻留在mysql.ibd数据字典的表空间

查看DDL日志写入mysql.innodb_ddl_logDDL操作表的过程中,使innodb_print_ddl_logs配置选项。有关更多信息,参见查看DDL日志

笔记

重做日志的变化mysql.innodb_ddl_log表刷新到磁盘立即不管的innodb_flush_log_at_trx_commit设置冲洗的重做日志立即避免数据的情况下,文件的修改由DDL操作而更改的重做日志mysql.innodb_ddl_log通过这些操作,得到的表没有保存到磁盘。这种情况可能回滚或恢复过程中导致错误。

这个InnoDB存储引擎执行DDL操作阶段。DDL操作,如ALTER TABLE可以执行的准备执行阶段之前的多次承诺

  1. 准备:创建所需对象的DDL日志写的mysql.innodb_ddl_log表DDL日志定义如何向前滚动并回滚DDL操作。

  2. 执行:执行DDL操作。例如,创建一个执行程序CREATE TABLE运营

  3. 承诺:更新数据字典和提交数据字典事务。

  4. 后DDL:从回放和删除DDL日志mysql.innodb_ddl_log表确保回滚可以安全的进行而不引入不一致,文件操作,如重命名或删除数据文件在这最后阶段进行。这一阶段从还消除动态元数据mysql.innodb_dynamic_metadata数据字典表DROP TABLETRUNCATE TABLE,和其他DDL操作rebuild,真的结束了。

DDL日志重放和去除mysql.innodb_ddl_log表中后DDL阶段,无论是否提交或回滚事务。DDL日志应该只停留在mysql.innodb_ddl_log如果服务器是一个DDL操作期间停止。在这种情况下,DDL日志回放和删除后的恢复。

在经济复苏的情况下,一个DDL事务可以提交或回滚当服务器重启。如果数据字典进行交易,在承诺一个DDL操作阶段是目前在重做日志和二进制日志,手术被认为是成功的,向前滚动。否则,不完整的数据字典事务回滚时InnoDB录像数据字典的重做日志,和DDL事务回滚。

查看DDL日志

查看DDL日志写入mysql.innodb_ddl_log数据字典表的DDL操作过程中涉及的原子InnoDB存储引擎,使innodb_print_ddl_logs有MySQL写DDL日志标准错误。根据主机操作系统和MySQL的配置,stderr可能的错误日志,终端或控制台窗口。看到第5.4.2.2,“默认错误日志的目的配置”

InnoDBDDL日志写的mysql.innodb_ddl_log表支持重做和DDL操作回滚。这个mysql.innodb_ddl_log表是一个隐藏的数据字典表驻留在mysql.ibd数据字典表空间。像其他隐藏的数据字典表,themysql.innodb_ddl_log表不能在非直接访问的调试版本的MySQL。(见14.1节,“数据字典”的结构。)mysql.innodb_ddl_log表对应这个定义:

创建表mysql.innodb_ddl_log(id bigint符号的非空auto_increment主键,thread_id bigint unsigned int类型的符号不空,不空,space_id int unsigned int,page_no符号,index_id bigint符号,table_id bigint符号,old_file_path varchar(512)整理utf8_bin,new_file_path varchar(512)整理utf8_bin,关键(thread_id));
  • id:一个DDL日志记录的唯一标识符。

  • thread_id:每个DDL日志记录分配一个thread_id,这是用来回放和删除DDL日志,属于一个特定的DDL事务。DDL事务涉及多个数据文件,生成多个DDL操作日志记录。

  • typeDDL操作类型。类型包括免费(删除索引树)DELETE(删除文件)重命名(重命名一个文件),或DROP(从下拉元数据mysql.innodb_dynamic_metadata数据字典的表)

  • space_id:表空间ID

  • page_no:一个页面包含配置信息;索引树的根页面,例如。

  • index_id: The index ID.

  • table_id:表的ID

  • old_file_path:旧表空间文件路径。通过DDL操作创建或删除表空间文件使用;也用于DDL操作重命名一个表空间。

  • new_file_path:新的表空间文件路径。通过DDL操作表空间文件重命名。

这个例子演示了使innodb_print_ddl_logs查看DDL日志写入strderr对于一个CREATE TABLE运营

mysql> SET GLOBAL innodb_print_ddl_logs=1;mysql> CREATE TABLE t1 (c1 INT) ENGINE = InnoDB;
[Note] [000000] InnoDB: DDL log insert : [DDL record: DELETE SPACE, id=18, thread_id=7, 
space_id=5, old_file_path=./test/t1.ibd]
[Note] [000000] InnoDB: DDL log delete : by id 18
[Note] [000000] InnoDB: DDL log insert : [DDL record: REMOVE CACHE, id=19, thread_id=7, 
table_id=1058, new_file_path=test/t1]
[Note] [000000] InnoDB: DDL log delete : by id 19
[Note] [000000] InnoDB: DDL log insert : [DDL record: FREE, id=20, thread_id=7, 
space_id=5, index_id=132, page_no=4]
[Note] [000000] InnoDB: DDL log delete : by id 20
[Note] [000000] InnoDB: DDL log post ddl : begin for thread id : 7
[Note] [000000] InnoDB: DDL log post ddl : end for thread id : 7

13.1.2数据库语句的句法

ALTER {DATABASE | SCHEMA} [db_name]
    alter_specification ...

alter_specification:
    [DEFAULT] CHARACTER SET [=] charset_name
  | [DEFAULT] COLLATE [=] collation_name

ALTER DATABASE使您能够更改数据库的总体特征。这些特点是存储在数据字典。使用ALTER DATABASE,你需要的ALTER对数据库的权限ALTER SCHEMA是同义词ALTER DATABASE

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

民族语言特点

这个CHARACTER SET条款更改默认的数据库字符集。这个整理条款更改默认的数据库排序规则。10章,字符集Unicode排序规则,字符集和整理,讨论了名字。

你可以看到什么字符集和排序规则是可以使用的,分别SHOW CHARACTER SETSHOW COLLATION声明.看到第13.7.6.3,“显示字符集语法”,和第13.7.6.4,显示整理语法”为更多的信息

如果您更改默认字符集和整理为一个数据库,存储程序,使用默认的数据库必须删除并重新创建的,他们使用新的默认值。(在一个存储程序,字符数据类型使用默认的数据库如果字符集或整理不显式指定的变量。看到第13.1.15,创建过程和创建函数的语法”。)

13.1.3改变事件语法

ALTER
    [DEFINER = { user | CURRENT_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语句更改一个或一个以上的现有的事件而不需要删除并重新创建它的特点。每个的语法定义者ON SCHEDULE在完成COMMENT使/DISABLE,和DO条款是完全一样的使用时CREATE EVENT。。。。。。。(这第13.1.12,“创建事件语法”。)

任何用户都可以改变一个事件定义在数据库中,用户有EVENT特权。当用户成功executesALTER EVENT声明,用户成为影响事件的定义。

ALTER EVENT只能在现有的事件:

MySQL的>ALTER EVENT no_such_event >ON SCHEDULE >EVERY '2:3' DAY_HOUR;1 . Error 1517(HY000):unknown ' s no dech such such a event .

在下面的例子,假设命名事件myevent定义如下所示:

CREATE EVENT myevent    ON SCHEDULE      EVERY 6 HOUR    COMMENT 'A sample comment.'    DO      UPDATE myschema.mytable SET mycol = mycol + 1;

以下语句更改时间表myevent从每六小时一次,立即开始每隔十二小时,四小时开始时间从语句运行:

改变事件事件的时间表每12小时开始current_timestamp间隔4小时;

它有可能改变一个声明事件的多重特征。此示例更改执行的SQL语句myevent一,删除所有的记录空白表;它也改变时间表的事件,执行一次,一天以后ALTER EVENT语句运行

改变在current_timestamp间隔1天的日程安排表myschema.mytable事件做事件;

指定一个选项ALTER EVENT声明只为那些特征,你想改变;略选择保持他们现有的价值观。这包括任何默认值CREATE EVENT使

禁用myevent,使用这ALTER EVENT声明:

Alter event Myevent Myevent;

这个ON SCHEDULE子句可以使用内置的MySQL的功能和用户变量来获得任何的表情timestampinterval值,它包含。您不能使用存储过程或用户定义的函数在这样的表情,你不能使用任何表引用;但是,您可以使用选择双。这是真实的ALTER EVENTCREATE EVENT声明.存储程序,用户自定义函数的引用,在这种情况下,表是不允许的,和失败与错误(见虫# 22830)。

虽然ALTER EVENT声明中包含另一个ALTER EVENT声明在其DO条款似乎成功了,当服务器试图执行生成的预定事件,执行失败与错误。

要重命名的事件,使用ALTER EVENT声明的重命名为的条款。这句话的意思是myeventyourevent

ALTER EVENT myevent
    RENAME TO yourevent;

你也可以移动到一个不同的数据库使用一个事件ALTER EVENT ... RENAME TO ...db_name.event_name符号,如下所示:

另一个事件olddb.myevent重命名to newdb.myevent;

执行上述语句中,用户必须执行它EVENT在两privilege的olddbnewdb数据库

笔记

没有RENAME EVENT声明

的价值DISABLE ON SLAVE用于复制的奴隶而不是使DISABLE表示一个事件,在主创造和复制的奴隶,但是这不是奴隶执行。通常,禁用的奴隶自动设置的要求;然而,有一些情况下,你可能想要或需要手工改变它。看到第17.4.1.16”功能,调用“复制为更多的信息

13.1.4改变函数的语法

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节,“二进制日志存储程序”

13.1.5改变实例的语法

ALTER INSTANCE ROTATE INNODB MASTER KEY

ALTER INSTANCE定义了适用于MySQL服务器实例的行为。

这个ALTER INSTANCE ROTATE INNODB MASTER KEY声明用于旋转用于主密钥InnoDB表空间加密。一个钥匙圈插件必须装用这个语句。默认情况下,MySQL服务器的负载keyring_file插件。旋转requires密钥。ENCRYPTION_KEY_ADMINSUPER特权

ALTER INSTANCE ROTATE INNODB MASTER KEY支持并行DML。然而,它不能同时运行着CREATE TABLE ... ENCRYPTIONALTER TABLE ... ENCRYPTION操作,并锁定以防止冲突产生于这些语句的并行执行。如果其中一个冲突语句正在运行,它必须完成之前,另一个可以进行。

ALTER INSTANCE行动是二进制日志写的,他们可以复制服务器执行。

额外的ALTER INSTANCE ROTATE INNODB MASTER KEY使用信息,看第15.7.11,“InnoDB表空间加密”。的信息keyring_file插件,看第6.5.4,“MySQL的钥匙”

13.1.6改变程序的语法

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的特权”

改变服务器13.1.7 syntax

ALTER SERVER  server_name
    OPTIONS (option [, option] ...)

改变服务器信息server_name,调节任何选项允许在CREATE SERVER声明。在相应的字段mysql.servers表的更新。这一声明要求SUPER特权

例如,更新USER选项:

对服务器的选择(使用情况);

ALTER SERVER一个隐含的承诺的原因。看到13.3.3部分,”声明,因为一个隐含的承诺”

ALTER SERVER不写入二进制日志,不管日志格式,使用。

13.1.8修改表的语法

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 [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 FULLTEXT [INDEX|KEY] [index_name]
        (key_part,...) [index_option] ...
  | ADD SPATIAL [INDEX|KEY] [index_name]
        (key_part,...) [index_option] ...
  | ADD [CONSTRAINT [symbol]]
        FOREIGN KEY [index_name] (key_part,...)
        reference_definition
  | ALGORITHM [=] {DEFAULT|INSTANT|INPLACE|COPY}
  | ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
  | ALTER INDEX index_name {VISIBLE | INVISIBLE}
  | 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 COLUMN old_col_name TO new_col_name
  | RENAME {INDEX|KEY} old_index_name TO new_index_name
  | RENAME [TO|AS] new_tbl_name
  | {WITHOUT|WITH} VALIDATION
  | 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)] | (expr)} [ASC | DESC]

index_type:
    USING {BTREE | HASH}

index_option:
    KEY_BLOCK_SIZE [=] value
  | index_type
  | WITH PARSER parser_name
  | COMMENT 'string'
  | {VISIBLE | INVISIBLE}

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
  | UNION [=] (tbl_name[,tbl_name]...)

partition_options:
    (see CREATE TABLE options)

ALTER TABLE修改表的结构。例如,您可以添加或删除列,创造或毁灭的指标,改变现有的柱型,或重命名的列或表本身。你也可以改变,如用于表或表的存储引擎特性的评论。

有几个方面的额外ALTER TABLE声明,本节中的以下主题下的描述:

表选项

table_options就是那种可以用表中的选项CREATE TABLE语句,如引擎AUTO_INCREMENTavg_row_lengthMAX_ROWSrow_format,或TABLESPACE

对于所有表选项的说明,见第13.1.18,“创建表的语法。然而,ALTER TABLE忽略数据目录INDEX DIRECTORY当表选项ALTER TABLE允许他们作为分区选项,并要求你文件特权

随着表的选择使用ALTER TABLE提供了一个便捷的方式改变单一特征表。例如:

为了验证表选项改为目的,使用SHOW CREATE TABLE,或查询INFORMATION_SCHEMA.TABLES

性能和空间要求

ALTER TABLE操作是使用下面的算法处理:

  • COPY:手术是在原表的一个副本,和表数据复制从原始表到新表的行。并行DML是不允许的。

  • INPLACE:操作避免复制表中的数据可在地方重建表。桌子上有一个专属的元数据锁可操作的准备和执行阶段中采取简单。通常,支持并行DML。

  • INSTANT:操作只修改元数据在数据字典。没有专用的元数据锁进行准备和执行过程中的表和表数据不受影响,使操作瞬时。并行DML是允许的。(介绍MySQL 8.0.12)

这个ALGORITHM子句是可选的。如果算法从句的省略,MySQL的使用ALGORITHM=INSTANT存储引擎ALTER TABLE条款支持。否则,ALGORITHM=INPLACE使用。如果ALGORITHM=INPLACE不支持,ALGORITHM=COPY使用

指定一个ALGORITHM条款要求操作使用指定的算法对条款和存储引擎,支持它,或失败与错误否则。指定ALGORITHM=DEFAULT是一样的省略ALGORITHM条款.

ALTER TABLE操作使用复制其他的操作,修改表的完整算法等。通过改变应用于表复制,数据复制过来的,原来的表被删除,复制和表更名为原始表的名称。而ALTER TABLE操作执行,原表是可读的其他会议(除注意不久)。更新和写表开始后ALTER TABLE操作开始停滞,直到新的桌子已经准备好了,然后被自动重定向到新表。桌子的临时副本创建的原始表的数据库目录,除非它是一个重命名为操作移动表数据库驻留在一个不同的目录。

除了前面提到的是,ALTER TABLE块读取(不只是写)在它准备收拾桌上和表定义缓存过时的表结构。在这一点上,它必须获得独占锁。这样做,它等待当前读者来完成,并阻止新的读取和写入。

一个ALTER TABLE操作使用复制算法防止并发DML操作。并发查询还是允许的。这是一台复印作业总是至少包括并发限制LOCK=SHARED(允许查询而不是DML)。你可以进一步限制并发操作支持锁具子句指定LOCK=EXCLUSIVE,以防止DML和查询。有关更多信息,参见并发控制

强制使用的COPY算法一ALTER TABLE操作,否则将不会使用它,使old_alter_table系统变量或指定ALGORITHM=COPY。如果有冲突old_alter_table设置一个算法一个比其他价值条款DEFAULT,的算法条款优先

InnoDB表一ALTER TABLE操作使用复制在桌子上,驻留在一个算法共享表空间可以增加表空间使用的空间量。这样的操作需要在表格和索引数据的多少额外的空间。一个居住在一个共享表空间表,额外的空间用于在操作不回操作系统,因为它是一个表驻留在发布文件表表空间

信息在线DDL操作对空间的要求,看第15.12.3,“在线DDL空间要求”

ALTER TABLE运营支持到位算法包括:

  • ALTER TABLE支持的操作InnoDB在线DDL功能特色有关支持的操作的概述,看第15.12.1,“在线DDL操作”

  • 重命名一个表。MySQL将对应于表文件tbl_name没有复制。(你也可以使用RENAME TABLE语句重命名表。看到第13.1.33,“重命名表语法”权限。)专门为table没有迁移到新的名字。他们必须手动更改。

  • 操作只修改表元数据。这些操作都是直接由于服务器只需要修改表frm文件,不碰表内容。元数据操作包括:

    • 重命名一个列

    • 更改列的默认值

    • 修改一个定义ENUMSET通过添加新的枚举或组成员列结束对有效的成员值的列表,只要该数据类型的存储大小没有变化。例如,添加一个成员了SET柱有8成员变化所需的存储每值从字节字节数;这需要一个表复制。在列表中添加成员造成重编现有成员,这就需要一个表复制。

    • 改变定义一个空间列删除SRID属性。(添加或更改SRID属性不需要重建并不能做到位,因为服务器必须验证所有的值都有指定的SRID值。)

  • 重命名索引

  • 增加或下降的二次指数,是InnoDB。看到第15.12.1,“在线DDL操作”

  • 一个修改指标能见度ALTER INDEX运营

  • 含有产生依赖列与列的表列的修改DEFAULT如果修改列值不参与生成的列的表达式。例如,改变无效的一个单独的列属性可以在地方没有表重建。

ALTER TABLE运营支持即时算法包括:

  • 添加列。此功能称为即时ADD COLUMN。限制适用。看到第15.12.1,“在线DDL操作”

  • 添加或删除虚拟柱

  • 添加或删除列的默认值。

  • 修改一个定义ENUMSET专栏相同的限制适用于上述ALGORITHM=INSTANT

  • 改变索引类型

  • 重命名一个表。相同的限制适用于上述ALGORITHM=INSTANT

更多关于操作,支持信息ALGORITHM=INSTANT,看到第15.12.1,“在线DDL操作”

ALTER TABLE升级MySQL 5.5的时间列5.6格式添加列CHANGE COLUMN修改列ADD INDEX,和运营这种转换不能使用INPLACE算法因为表必须重建,因此指定ALGORITHM=INPLACE在这些情况下导致错误。指定ALGORITHM=COPY如果有必要的话

如果一个ALTER TABLE在一个多列索引用于分区表的操作钥匙更改列的顺序,它只能用ALGORITHM=COPY

这个WITHOUT VALIDATION与验证影响条款ALTER TABLE执行就地操作虚拟生成的列修改看到第13.1.8.2,“修改表和生成的列”

ALTER TABLE丢弃…分区…表空间IMPORT ... PARTITION ... TABLESPACE不产生任何临时表或临时分区中的文件。

ALTER TABLE添加分区DROP PARTITION合并分区REBUILD PARTITION,或reorganize partition不创建临时表(除非用NDB表);然而,这些操作可以创建临时分区中的文件。

ADD操作RANGE列表分区是直接操作或近如此。ADD凝聚操作HASH钥匙分区之间复制所有分区的数据,除非LINEAR HASH线性键使用;这是有效的创建一个新表一样,虽然ADD凝聚操作是通过分区进行分区。REORGANIZE只有改变操作复制分区和触摸不不变的。

MyISAM表,你可以加快索引重新创造(的变更过程中的最慢的一部分)通过设置myisam_sort_buffer_size系统变量的高价值

并发控制

ALTER TABLE运营支持的话,你可以使用锁具子句来控制并发的读和写在桌子上,它正在改变。指定非默认值为该条款允许你改变操作过程中需要一定数量的并发访问或排他性,并停止操作,如果锁定要求的程度是不可用的。

只有LOCK = DEFAULT是操作允许使用ALGORITHM=INSTANT。其他的LOCK条款参数不适用

对于参数LOCK条款:

  • LOCK = DEFAULT
    

    对于给定的并发最大水平ALGORITHMclause(如果任何)和修改表操作:允许并发读取和写入如果支持。如果不是,允许并发读取,如果支持。如果没有,执行独家访问。

  • LOCK = NONE
    

    如果支持,允许并发读取和写入。否则,发生了一个错误。

  • LOCK = SHARED
    

    如果支持,允许并发读取,但块写入。写的是即使并行写入由给定的存储引擎支持封锁ALGORITHMclause(如果任何)和修改表运营如果不支持并发读取,出现错误。

  • LOCK = EXCLUSIVE
    

    实行独家访问。这是即使并发的读/写是由给定的存储引擎支持ALGORITHMclause(如果任何)和修改表运营

添加和删除列

使用ADD向表中添加新列,并删除现有列DROP col_name是一个mysql扩展标准的SQL。

在一个表中的行的特定位置添加一列,使用FIRSTcol_name。默认的是添加的列上。

如果一个表只包含一个列,列不能丢。如果你打算是删除表,使用DROP TABLE语句

如果列从一个表中的列也下降了,从任何指标其中的一部分删除。如果所有的列组成指数的下降,该指数同样下跌。如果你使用CHANGE修改缩短一个列,列上存在索引,以及由此产生的柱长度小于指数长度缩短自动索引,MySQL。

ALTER TABLE ... ADD,如果列有表达的默认值,使用非确定性函数,声明可能会产生一个警告或错误。详情见第17.1.3.6,”与GTIDs的“复制限制

重命名,重新定义,并对列重新排序

这个CHANGE修改RENAME COLUMN,和改变条款使现有的列的名称和定义被改变。他们有这些特点的比较:

  • CHANGE

    • 可以重命名一个列并改变其定义,或两者。

    • 有更多的能力比MODIFY重命名字段,但在牺牲一些操作方便。CHANGE需要命名列两次如果不改名,并要求respecifying列定义如果重命名。

    • FIRST,可以重新排序的列

  • MODIFY

    • 可以更改列的定义而不是它的名字。

    • 更方便CHANGE要更改列定义不改名

    • FIRST,可以重新排序的列

  • RENAME COLUMN

    • 可以更改列的名字而不是它的定义。

    • 更方便CHANGE要重命名一个列不改变它的定义。

  • ALTER:仅用于更改列的默认值。

CHANGE是一个mysql扩展标准的SQL。修改RENAME COLUMN是Oracle的MySQL扩展兼容性。

改变柱改变其名称和定义,使用CHANGE,指定的旧的和新的名字和新的定义。例如,重命名INT NOT NULLaB并改变其定义使用BIGINT数据类型而保留不为空属性:do this,

ALTER TABLE t1 CHANGE a b BIGINT NOT NULL;

要更改列的定义而不是它的名称,使用CHANGE修改。与CHANGE,语法要求两列名称,所以你必须指定相同的名字两次离开名称不变。例如,更改列的定义B,这样做:

ALTER TABLE t1 CHANGE b b INT NOT NULL;

MODIFY是改变的定义不改变名称更方便,因为它需要的字段名,只有一次:

修改表T1修改B INT NOT NULL;

要更改列的名字而不是它的定义,使用CHANGE重命名字段。与CHANGE,语法要求列定义,所以离开的定义不变,你必须指定定义的列目前已。例如,重命名INT NOT NULLb,这样做:

ALTER TABLE t1 CHANGE b a INT NOT NULL;

RENAME COLUMN是改变名称不改变定义更方便,因为它只需要旧的和新的名字:

改变重命名表列B到A;

在一般情况下,不能重命名一个列的名称,表中已经存在。然而,这有时并非如此,例如当你交换名字或移动通过一个周期。如果一个表的列aB,和c,这些都是有效的操作:

——交换和巴尔特重命名表列A到B,B列一个重命名;“旋转”,B、C通过cyclealter重命名表列A到B,B到C柱更名,更名列C一;

使用列定义的变化CHANGE修改,这个定义必须包含数据类型的所有属性,应适用于新的列,而不是指数等属性PRIMARY KEY独特。属性的原始定义而为新定义的不是了。假设一个柱col1被定义为int unsigned默认1评论我的专栏你修改列如下,打算改变INTbigint

ALTER TABLE t1 MODIFY col1 BIGINT;

这句话改变数据类型INTbigint,但也下降UNSIGNED默认,和COMMENT属性.为了留住他们,声明必须包括明确:

修改表T1修改col1 bigint符号默认1评论我的专栏;

数据类型的使用CHANGE修改,MySQL试图将现有的列值为新类型以及可能的。

警告

这个转换可能会导致更改数据。例如,如果你缩短一弦一柱,值可能被截断。为了防止手术成功如果转换到新的数据类型会导致数据丢失,使严格的SQL模式使用前ALTER TABLE(见第5.1.10,”服务器的SQL模式”

如果你使用CHANGE修改缩短一个列,列上存在索引,以及由此产生的柱长度小于指数长度缩短自动索引,MySQL。

对列重新命名CHANGE重命名字段,MySQL自动重命名这些引用重命名的列:

  • 指标,指的是老塔,包括无形的指标和残疾人MyISAM指标

  • 外键引用老柱

对列重新命名CHANGE重命名字段,MySQL不会自动重命名这些引用重命名的列:

  • 生成的列和分区表达式引用重命名的列。你必须使用CHANGE重新定义这样的表达式在同一ALTER TABLE声明一个命名列

  • 视图和存储程序,请参阅重命名列。手动改变这些对象的定义是指新的列名称必须。

对列重新排序表中,使用FIRST进入CHANGE修改运营

ALTER ... SET DEFAULT改变…删除默认的指定列或删除旧的默认值的一种新的默认值,分别。如果旧的默认删除和柱可NULL默认情况下,新的无效的。如果您发现有错误,请尽管发表评论!NULL指定一个默认值,MySQL中描述11.7节,“数据类型的默认值”

主键和索引

DROP PRIMARY KEY主键。如果没有主键,发生了一个错误。关于主键的性能特性的信息,特别是InnoDB表,看第8.3.2,“主键”的优化

如果你添加一个UNIQUE INDEX主键一个表,MySQL存储在任何非唯一索引允许重复键检测尽早。

DROP INDEX删除索引。这是一个mysql扩展标准的SQL。看到第13.1.25,“删除索引的语法”。确定指标的名称,使用SHOW INDEX FROM tbl_name

某些存储引擎允许你指定一个索引类型创建索引时。对于语法index_type说明符使用type_name。为详细了解使用,看到第13.1.14,“创建索引的语法”。首选位置是列列表后。在列列表使用该选项的支持将在未来的MySQL版本中删除。

index_option值指定索引选项使用就是这样的一个选项。详情可index_option值,见第13.1.14,“创建索引的语法”

RENAME INDEX old_index_name TO new_index_name重命名索引。这是一个mysql扩展标准的SQL。表格中的内容保持不变。old_index_name必须对现有的索引表中,不是下降了相同的名字ALTER TABLE声明new_index_name是新的索引名称,不能重复在结果表中的索引的名称变更后已应用。无论指数名称可首要

如果你使用ALTER TABLE在一个MyISAM表,所有非唯一索引是一个单独的批处理创建(如REPAIR TABLE)。this should makeALTER TABLE当你有很多指标更快

MyISAM表,密钥更新可以显式控制。使用修改表…禁用按键告诉MySQL停止更新非唯一索引。然后使用ALTER TABLE ... ENABLE KEYS重新创建丢失的指标MyISAM这是一个特殊的算法,比钥匙插入一个接一个的速度更快,所以禁用键执行批量插入操作之前,应该给一个相当大的加速比。使用ALTER TABLE ... DISABLE KEYS要求INDEX除了前面提到的特权的特权。

而非唯一索引是残疾人,他们对诸如忽视SELECTEXPLAIN否则将使用它们

后一个ALTER TABLE声明中,可能需要运行ANALYZE TABLE更新指标基数信息。看到第13.7.6.22,显示指数的语法”

这个ALTER INDEX经营许可证的指标是有形的或无形的。一个看不见的指标不是由优化器使用。指标可视修改适用于非主键索引(无论是明确的或隐含的)。此功能是存储引擎中性(任何引擎支持)。有关更多信息,参见第8.3.12节“隐形反射”

外键

这个FOREIGN KEY推荐信条款由InnoDB存储引擎,它实现了[ [添加约束symbol] [重点]外商index_name引用】(…)…(…)。看到第15.8.1.6,“InnoDB和外键约束”。其他的存储引擎,但忽略的条款解析。这个CHECK条款解析但所有存储引擎忽略。看到第13.1.18,“创建表的语法。接受而忽视语法条款是兼容性的原因,使它更容易从其他SQL服务器端口的代码,并运行应用程序,创建表的引用。看到第1.8.2,MySQL的区别标准SQL”

ALTER TABLE,不像CREATE TABLE添加外键忽略index_name如果使用一个自动生成的外键名称。作为一种变通方法,包括约束子句指定外键名称:

ADD CONSTRAINT name FOREIGN KEY (....) ...
重要

MySQL默默地忽略了内联REFERENCES规格,在引用被定义为列规范的一部分。MySQL只接受推荐信条款定义为一个单独的部分FOREIGN KEY规格

笔记

分区InnoDB表不支持外键。有关更多信息,参见第22.6.2,分区限制有关存储引擎”

MySQL支持使用ALTER TABLE下降的外键:

修改表tbl_name删除外键fk_symbol

添加在同一滴一个外键ALTER TABLE声明支持ALTER TABLE ... ALGORITHM=INPLACE但不适合ALTER TABLE ... ALGORITHM=COPY

服务器禁止更改外键列,就必须使参照完整性的潜在损失。它也禁止更改这些列的数据类型可能是不安全的。例如,改变VARCHAR(20)VARCHAR(30)是允许的,但改变它VARCHAR(1024)是不是因为改变长度的字节数需要存储个人价值。一种解决方法是使用ALTER TABLE ... DROP FOREIGN KEY更改列定义之前ALTER TABLE ... ADD FOREIGN KEY后来

ALTER TABLE tbl_name RENAME new_tbl_name改变内部生成的外键约束的名称和定义的外键约束名称包含字符串tbl_name_ ibfk _以反映新的表名InnoDB将外键约束名称包含字符串tbl_name_ ibfk _为自创的名字

更改字符集

改变表的默认字符集和字符列(CHARVARCHARTEXT)到一个新的字符集,使用这样的陈述:

修改表tbl_name转换字符集charset_name

声明还改变了所有字符列的排序规则。如果你不指定COLLATE条款表明使用的排序规则,声明使用的默认排序规则的字符集。如果这是不打算整理表的使用(例如,如果它想从一个敏感的排序变化不区分大小写的整理),指定排序规则明确。

一列的数据类型,VARCHAR或在一个TEXT类型,转换字符集改变数据类型以确保新列是足够长的时间来存储的许多人物,原柱。例如,一个TEXT柱有两个长度字节存储在列中的值的字节长度,最大值为65535。对于一个latin1TEXT柱,每个字符需要一个字节,所以列可以存储多达65535个字符。如果列转换为UTF8, each character might require up to three bytes, for a maximum possible length of 3 × 65,535 = 196,605 bytes. That length does not fit in aTEXT列的长度字节,所以MySQL转换数据类型MEDIUMTEXT,这是最小的字符串类型,长度的字节的记录值为196605。同样,一个VARCHAR列会被转换为MEDIUMTEXT

为了避免类型描述数据类型的变化,不要使用CONVERT TO CHARACTER SET。相反,使用修改要更改单个列。例如:

ALTER TABLE t MODIFY latin1_text_col TEXT CHARACTER SET utf8;
ALTER TABLE t MODIFY latin1_varchar_col VARCHAR(M) CHARACTER SET utf8;

如果你指定CONVERT TO CHARACTER SET binary,的CHARVARCHAR,和TEXT列转换为相应的二进制字符串类型(BINARYVARBINARYBLOB)。这意味着,不再会有一列的字符集属性和随后的转换操作不适用于他们

如果charset_name默认在一个CONVERT TO CHARACTER SET操作,字符集命名的character_set_database使用系统变量的冰

警告

这个CONVERT TO手术将列值和原指定的字符集之间。这是如果你有一个列在一个字符集,你想要的东西(如latin1)但存储的值实际上使用一些其他的,不兼容的字符集(如UTF8)。在这种情况下,你必须为每个这样的栏目做如下:

ALTER TABLE t1 CHANGE c1 c1 BLOB;
ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;

这样做是因为没有转换时转换或从BLOB专栏

只改变了默认设置一个表的字符,使用此语句:

ALTER TABLE tbl_name DEFAULT CHARACTER SET charset_name;

这个词DEFAULT是可选的。默认的字符集,如果不指定组添加到表后列的字符的字符集(例如,用修改表…添加列

foreign_key_checks系统变量是启用的,这是默认设置,允许在表中包括一个用于外键约束字符串列的不是字符集转换。解决办法是禁用foreign_key_checks执行字符集转换前。你必须在这两个表中的外键约束之前重新启用执行转换foreign_key_checks。如果你重新启用foreign_key_checks将唯一的表后,一个级联删除ON UPDATE CASCADE操作可能损坏数据的引用表由于隐式转换在这些操作中发生(bug # 45290,错误# 74816)。

InnoDB表空间和进口丢弃

一个InnoDB在自己创建的表文件表表空间可以被丢弃和进口使用DISCARD TABLESPACE导入表空间选项这些选项可以用来导入每表表空间文件从备份或复制的表的表空间文件从一个到另一个数据库服务器。看到第15.7.6,“每表表空间文件复制到另一个实例”

对于MyISAM表排序

ORDER BY让你在一个特定的命令行创建新表。这个选项很有用,当你知道你查询的行在一个特定的顺序大部分时间。通过在表的重大变化,使用此选项,您可以获得更高的性能。在某些情况下,它可能会使分类更容易为MySQL如果表是以列,你想为它以后。

笔记

桌子上没有停留在指定的命令后,插入和删除。

ORDER BY语法允许一个或多个被指定用于排序的列的名称,每一种选择可以通过ASCDESC表示升序或降序排序,分别。默认为升序。仅列名称可以任意表达式的排序标准;不允许。这一条款应给予任何其他条款上后。

ORDER BY没有道理的InnoDB表因为InnoDB总订单表行根据聚集索引

当使用一个分区表,ALTER TABLE ... ORDER BY命令行内每个分区只

期权的分解

partition_options标志的选项,可以使用分区表进行重新分区,添加,下降,丢弃,进口、合并、拆分分区,并进行分区保养。

一是可能的ALTER TABLE集装箱货物分区REMOVE PARTITIONING在一个除了改变规格条款,但分区REMOVE PARTITIONING条款必须指定任何其他规格上后。这个添加分区DROP PARTITION丢弃分区IMPORT PARTITION合并分区REORGANIZE PARTITION交换分区ANALYZE PARTITION检查分区,和REPAIR PARTITION选项不能与其他改变单一规格修改表,由于刚刚上市的行为在各个分区选项。

关于分区选项的更多信息,参见第13.1.18,“创建表的语法,和第13.1.8.1,“修改表分区操作”。有关的例子ALTER TABLE ... EXCHANGE PARTITION报表,看第22.3.3,“交换分区和子分区表”

13.1.8.1改变分区表的操作

分配相关条款ALTER TABLE可以使用分区表进行重新分区,添加,下降,丢弃,进口、合并、拆分分区,并进行分区保养。

  • 简单地使用partition_options条款ALTER TABLE对分区表进行重新分区,根据分区方案定义的表partition_options。这一条款总是开始分区,并且遵循相同的语法和规则适用于partition_options条款CREATE TABLE(更详细的信息,参见第13.1.18,“创建表的语法),也可以用于现有的表,是不是已经分区的分区。例如,考虑一个(未分区)表定义如下所示:

    CREATE TABLE t1 (
        id INT,
        year_col INT
    );
    

    这张桌子可以被分割的HASH,使用身份证件列作为分区键,分成了8个分区的这句话的意思是:

    ALTER TABLE t1
        PARTITION BY HASH(id)
        PARTITIONS 8;
    

    MySQL支持ALGORITHM选项[子]分区[线性]键ALGORITHM=1导致服务器使用相同的密钥散列函数作为MySQL 5.1在计算排在分区的位置;ALGORITHM=2意味着服务器采用密钥散列函数实现默认的新应用KEY分区表在MySQL 5.5及以后。(分区表创建关键散列函数mysql 5.5后来不能由MySQL 5.1服务器。使用)没有指定选项具有相同的效果,使用ALGORITHM=2。该选项用于主要使用在升级或降级[LINEAR] KEY分区表的MySQL 5.1及以后的版本之间,或创建表分区钥匙LINEAR KEY在MySQL 5.5或更高版本的服务器可在MySQL服务器5.1。

    表结果的使用ALTER TABLE ... PARTITION BY语句必须遵循一个创建使用相同的规则创建表…分区。这包括管理关系的任何唯一键之间的规则(包括任何主键),表可能有,和列用于分配表达式,讨论“22.6.1分解段,原钥匙,钥匙和钥匙,独特的”。这个CREATE TABLE ... PARTITION BY指定分区的数量也适用于规则修改表…分区

    这个partition_definition条款修改表添加分区支持相同的选项的名称相同的条款CREATE TABLE声明。(见第13.1.18,“创建表的语法,对于语法和描述。)假设你已分区表创建如下所示:

    CREATE TABLE t1 (
        id INT,
        year_col INT
    )
    PARTITION BY RANGE (year_col) (
        PARTITION p0 VALUES LESS THAN (1991),
        PARTITION p1 VALUES LESS THAN (1995),
        PARTITION p2 VALUES LESS THAN (1999)
    );
    

    你可以添加一个新的分区p3此表用于存储值小于二千零二如下:

    DROP PARTITION可用于删除一个或多个范围LIST走吧This statement cannot be with搞砸KEY相反,使用分区;合并分区(在本节稍后看到)。任何数据都存储在下降分区命名的partition_names列表是丢弃。例如,给定的表T1先前定义的,你可以删除分区命名p0P1如图所示:

    ALTER TABLE t1 DROP PARTITION p0, p1;
    

    ADD PARTITION删除分区目前不支持IF [NOT] EXISTS

    这个DISCARD PARTITION ... TABLESPACEIMPORT PARTITION ... TABLESPACE选项扩展传输表空间特征的个体InnoDB表。每个InnoDB表分区都有它自己的表空间文件(.idb队列)。the传输表空间功能可以很容易地复制表空间从运行MySQL服务器实例到另一个运行实例,或执行恢复在同一实例。都以逗号分隔的一个或多个分区的名称列表。例如:

    ALTER TABLE t1 DISCARD PARTITION p2, p3 TABLESPACE;
    
    修改表T1进口分区P2、P3表空间;

    当运行DISCARD PARTITION ... TABLESPACEIMPORT PARTITION ... TABLESPACE在subpartitioned表分区和子分区的名字,都是允许的。当一个分区,分区名称指定,包括子分区。

    这个传输表空间功能还支持复制或恢复分区InnoDB表(一次所有分区)。更多信息,参见第15.7.6,“每表表空间文件复制到另一个实例”,以及,第15.7.6.1,“可移动表空间的例子”

    重命名分区表支持。您可以重命名的单个分区的间接利用ALTER TABLE ... REORGANIZE PARTITION然而,这种操作;复制分区的数据。

    从选定的分区删除行,使用TRUNCATE PARTITION选项此选项需要一个或多个用逗号分隔的分区名称。考虑表T1这个语句创建:

    CREATE TABLE t1 (
        id INT,
        year_col INT
    )
    PARTITION BY RANGE (year_col) (
        PARTITION p0 VALUES LESS THAN (1991),
        PARTITION p1 VALUES LESS THAN (1995),
        PARTITION p2 VALUES LESS THAN (1999),
        PARTITION p3 VALUES LESS THAN (2003),
        PARTITION p4 VALUES LESS THAN (2007)
    );
    

    从分区删除所有行p0,使用以下语句:

    修改表T1删除分区P0;

    上面的语句如下具有相同的效果DELETE声明:

    DELETE FROM t1 WHERE year_col < 1991;

    当截断多个分区,分区不必是连续的:这可以大大简化删除分区表,否则将需要非常复杂的操作WHERE条件如果做DELETE声明.例如,这个语句删除分区的所有行P1p3

    修改表T1删除分区P1、P3;

    等效DELETE声明如下所示:

    DELETE FROM t1 WHERE    (year_col >= 1991 AND year_col < 1995)    OR    (year_col >= 2003 AND year_col < 2007);

    如果你使用ALL在分区名称列表位置关键词,在所有表分区表的行为。

    TRUNCATE PARTITION仅仅删除的行;它不改变表的定义本身,或其任何分区。

    验证行下降,检查INFORMATION_SCHEMA.PARTITIONS表,使用一个像这样的查询:

    SELECT PARTITION_NAME, TABLE_ROWS    FROM INFORMATION_SCHEMA.PARTITIONS    WHERE TABLE_NAME = 't1';

    COALESCE PARTITION可以使用已分区表的搞砸KEY减少分区数number。假设你已经创建了表T2如下:

    CREATE TABLE t2 (
        name VARCHAR (30),
        started DATE
    )
    PARTITION BY HASH( YEAR(started) )
    PARTITIONS 6;
    

    减少分区使用的号码t2从6到4,使用以下语句:

    修改表T2合并分区2;

    包含在最后的数据number分区将合并到其他分区。在这种情况下,分区4和5将被合并到第一4个分区(分区编号为0, 1, 2,和3)。

    改变一些但不是所有分区的分区表,您可以使用REORGANIZE PARTITION。这句话可以有几种方式:

    • 合并一组划分成一个分区。这是通过在几个分区命名了partition_names列表并提供一个单一的定义partition_definition

    • 将现有的分区到分区。通过命名一个分区partition_names并提供多partition_definitions

    • 改变范围的一个子集的分区定义使用VALUES LESS THAN或值列表的一个子集的分区定义使用价值观

    • 移动从一个空间到另一个分区。例如,看移动分区表之间的表空间使用ALTER TABLE

    笔记

    对于没有明确指定的分区,MySQL会自动提供的默认名称p0P1p2我们就这样另一方面,这是一个不可分割的组成部分。

    更详细的信息和例子ALTER TABLE ... REORGANIZE PARTITION报表,看第22.3.1,”管理的范围和列表分区”

  • 用一台交换表分区或子分区,使用ALTER TABLE ... EXCHANGE PARTITION声明说,将任何现有行的分区或子分区的未分区的表,和任何现有的行在未分区的表的表分区或子分区。

    使用信息和例子,看第22.3.3,“交换分区和子分区表”

  • 几个选项提供分区保养和维修,实施非分区表的语句等类似的功能CHECK TABLEREPAIR TABLE(这也是分区表;支持的更多信息,参见第13.7.3,“表维护报表”)。这些包括ANALYZE PARTITION检查分区OPTIMIZE PARTITION重建分区,和REPAIR PARTITION。每个选项需要partition_names由分区的一个或多个名称的条款,以逗号分隔。分区必须已经在目标表中存在。你也可以使用全部代替关键词partition_names,在这种情况下,所有的表分区表的行为。更多的信息和例子,看第22.3.4,“维护分区”

    InnoDB目前不支持每个分区优化;修改表…优化分区使整个表来重建和分析,和适当的警告发出。(错误# 11751825,错误# 42822)要解决此问题,使用ALTER TABLE ... REBUILD PARTITION修改表…分析分区相反

    这个ANALYZE PARTITION检查分区OPTIMIZE PARTITION,和修复分区选项不表不分区支持

  • REMOVE PARTITIONING可以删除一个表的分区而不影响表或数据。这个选项可以结合其他ALTER TABLE选项,如用于添加,下降,或重命名的列或索引。

  • 使用ENGINE选项ALTER TABLE存储引擎使用的表不影响分区的变化。目标存储引擎必须提供它自己的分区处理。只有InnoDBNDB存储引擎有本地分区处理;NDB目前不在MySQL 8的支持。

一是可能的ALTER TABLE集装箱货物分区REMOVE PARTITIONING在一个除了改变规格条款,但分区REMOVE PARTITIONING条款必须指定任何其他规格上后。

这个ADD PARTITION删除分区COALESCE PARTITIONreorganize partitionANALYZE PARTITION检查分区,和REPAIR PARTITION选项不能与其他改变单一规格修改表,由于刚刚上市的行为在各个分区选项。有关更多信息,参见第13.1.8.1,“修改表分区操作”

只有一个实例的下列选项可用于在一个给定的任何一个ALTER TABLE声明:分区ADD PARTITION删除分区TRUNCATE PARTITION交换分区REORGANIZE PARTITION,或合并分区ANALYZE PARTITION检查分区OPTIMIZE PARTITIONrebuild分区REMOVE PARTITIONING

例如,下面的两个声明是无效的:

ALTER TABLE t1 ANALYZE PARTITION p1, ANALYZE PARTITION p2;

ALTER TABLE t1 ANALYZE PARTITION p1, CHECK PARTITION p2;

在第一种情况下,你可以分析分区p1P2t1同时使用一个单一的声明与一个单一的分析分区选择列出的分区进行分析,这样的:

ALTER TABLE t1 ANALYZE PARTITION p1, p2;

在第二种情况下,它是不可能执行ANALYZE检查操作在同一表的不同分区同时。相反,你必须发出两个单独的语句,像这样:

ALTER TABLE t1 ANALYZE PARTITION p1;
ALTER TABLE t1 CHECK PARTITION p2;

REBUILD不支持的操作subpartitions正在研究。酒店重建关键词是明文禁止与子分区,和原因ALTER TABLE失败与错误如果

CHECK PARTITION 修复分区操作失败时,分区进行检查或修理任何包含重复键错误。

关于这些语句的更多信息,参见第22.3.4,“维护分区”

13.1.8.2修改表和生成的列

ALTER TABLE操作允许生成的列添加MODIFY,和改变

  • 生成的列可以添加

    CREATE TABLE t1 (c1 INT);
    ALTER TABLE t1 ADD COLUMN c2 INT GENERATED ALWAYS AS (c1 + 1) STORED;            
    
  • 数据类型和生成的列的表达可以被修改。

    CREATE TABLE t1 (c1 INT, c2 INT GENERATED ALWAYS AS (c1 + 1) STORED);
    ALTER TABLE t1 MODIFY COLUMN c2 TINYINT GENERATED ALWAYS AS (c1 + 5) STORED;
    
  • 生成的列可以重命名或删除,如果没有其他列指的是他们。

    CREATE TABLE t1 (c1 INT, c2 INT GENERATED ALWAYS AS (c1 + 1) STORED);
    ALTER TABLE t1 CHANGE c2 c3 INT GENERATED ALWAYS AS (c1 + 1) STORED;
    ALTER TABLE t1 DROP COLUMN c3;            
    
  • 虚拟生成的列不能更改存储生成的列,反之亦然。为了解决这个问题,降柱,然后把它与新的定义。

    CREATE TABLE t1 (c1 INT, c2 INT GENERATED ALWAYS AS (c1 + 1) VIRTUAL);
    ALTER TABLE t1 DROP COLUMN c2;
    ALTER TABLE t1 ADD COLUMN c2 INT GENERATED ALWAYS AS (c1 + 1) STORED;           
    
  • 无再生中继柱可以改变存储而不是虚拟生成的列。

    CREATE TABLE t1 (c1 INT, c2 INT);
    ALTER TABLE t1 MODIFY COLUMN c2 INT GENERATED ALWAYS AS (c1 + 1) STORED;            
    
  • 存储而不是虚拟生成的列可以改变无再生中继柱。存储生成的值变成了无再生中继列的值。

    CREATE TABLE t1 (c1 INT, c2 INT GENERATED ALWAYS AS (c1 + 1) STORED);
    ALTER TABLE t1 MODIFY COLUMN c2 INT;            
    
  • ADD COLUMN是不是到位操作存储列(没有使用临时表)因为表达必须由服务器计算。存储索引列,变化做到位,和表达的变化没有做到位。柱的意见变化做到位。

  • 非partitioned换表,ADD COLUMN下拉列在操作虚拟列。然而,添加或删除虚拟列不能结合其他地方进行ALTER TABLE运营

    对于分区表,ADD COLUMN下拉列不到位操作虚拟列

  • InnoDB支持二级指标虚拟生成的列。添加或删除次要指标上虚拟生成的列是一个地方的操作。有关更多信息,参见第13.1.18.9,“二级指标和生成的列”

  • 当一个VIRTUAL生成的列添加到表或改性,它不能保证被生成的列的表达式计算出来的数据不会超出范围的柱。这可能会导致不一致的数据被返回,意外失败的陈述。允许在验证是否发生这样的列控制,修改表支持WITHOUT VALIDATION与验证条款:

    • WITHOUT VALIDATION(默认如果没有条款规定),执行到位的操作(如果可能的话),数据的不完整性检查,并声明完成速度较快。然而,后来读表可能会报告列的警告或错误如果值超出范围。

    • WITH VALIDATION修改表复制表。如果超出范围或其他错误时,该语句将失败。因为执行表副本,声明需要更长的时间。

    WITHOUT VALIDATION与验证只允许用ADD COLUMN更改列,和MODIFY COLUMN操作。否则,在ER_WRONG_USAGE错误发生

  • 如果表达式计算导致截断或提供不正确的输入到一个功能的ALTER TABLE语句终止一个错误和DDL操作被拒绝。

  • 一个ALTER TABLE语句改变一列的默认值col_name也可能改变一个生成的列的表达,是指柱使用价值col_name,这可能改变一个生成的列的表达,是指柱使用价值DEFAULT(col_name)。for this reason,ALTER TABLE操作更改列的定义导致表重建如果任何生成的列的表达式使用DEFAULT()

13.1.8.3修改表的例子

首先用一个表t1创建如下所示:

创建表T1(一个整数,B查尔(10));

重命名的表t1T2

ALTER TABLE t1 RENAME t2;

改变柱aINTEGER字段不为空(留姓名相同),并改变柱bchar(10)CHAR(20)以及将其从Bc

修改表T2修改字段不为空,改变B C字符(20);

添加一个新的TIMESTAMP命名列D

ALTER TABLE t2 ADD d TIMESTAMP;

添加一个索引列d和一个独特索引列a

Alater T2 Add Index(D),Addénéunique(a);

要删除的列c

修改表T2降C柱;

添加一个新的AUTO_INCREMENT整数列命名C

ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
  ADD PRIMARY KEY (c);

我们的索引c(作为一个主键)因为AUTO_INCREMENT列必须被索引,并宣告C作为NOT NULL因为主键列不能无效的

当你添加一个AUTO_INCREMENT列,列的值填入序列号自动。为MyISAM表,你可以通过执行组的第一个序列号SET INSERT_ID=value之前ALTER TABLE或使用AUTO_INCREMENT=value表选项

MyISAM表,如果你不改变汽车柱,序列号不受影响。如果你把一个AUTO_INCREMENT柱,然后添加另一个汽车列数从1个

复制时使用,增加AUTO_INCREMENT列一个表可能不会产生对奴隶和主人的相同行排序。这是因为在这行编号的顺序取决于特定的存储引擎用于表和订单中的行插入。如果是对主人和奴隶的重要次序,行粘贴前必须在指定汽车数。假设你想要添加一个AUTO_INCREMENT列的表T1,下面的语句产生一个新的表t2相同T1但是有一个AUTO_INCREMENT专栏

创建表T2(ID int auto_increment主键)SELECT * FROM T1的col1,col2;

这个假定表t1有柱2col2

这套报表也将产生一个新的表t2相同T1另外,有一个AUTO_INCREMENT专栏

创建表T2像T1 T2;修改表添加ID int auto_increment主键;插入T2 SELECT * FROM T1的col1,col2;
重要

为了保证对主人和奴隶一样的命令,全部t1必须引用的顺序条款.

无论方法用来创建和填充的内容有AUTO_INCREMENT柱,最后一步是把原来的表,然后重命名该副本:

删除表T1 T2 T1表重命名;

13.1.9改变表空间语法

ALTER TABLESPACE tablespace_name
    RENAME TO tablespace_name 	
    [ENGINE [=] engine_name]

这句话可以用来重新命名InnoDB一般的表空间

这个CREATE TABLESPACE特权需要重命名一个一般的表空间。

这个ENGINE条款,指定的表空间用于存储引擎,是过时的、将在未来的版本中删除。表空间存储引擎是由数据字典,使引擎条款已经过时。如果指定的存储引擎,它必须匹配的表空间存储引擎在数据字典中定义。

RENAME TO操作是隐式执行autocommit模式,无论对autocommit设置

RENAME TO而不能进行手术LOCK TABLESFLUSH TABLES WITH READ LOCK实际上是为居住在表空间表。

独家元数据锁是以,居住在一个表空间,表空间一般为表,以防止并发DDL。支持并行DML。

13.1.10改变视图的语法

ALTER
    [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
    [DEFINER = { user | CURRENT_USER }]
    [SQL SECURITY { DEFINER | INVOKER }]
    VIEW view_name [(column_list)]
    AS select_statement
    [WITH [CASCADED | LOCAL] CHECK OPTION]

这句话改变了一个视图的定义,它必须存在。语法是类似的,CREATE VIEW看见第13.1.21,”创建视图的语法”)。This statement requires theCREATE VIEWDROP为视图的权限,而每一列中提到的一些特权SELECT声明ALTER VIEW只允许与定义者或用户SET_USER_IDSUPER特权

13.1.11创建数据库的语法

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

CREATE DATABASE是不是在一个会话中,有一个活跃的允许LOCK TABLES声明

create_specification选项指定数据库的特点。数据库的特点是存储在数据字典。这个字符集子句指定默认数据库字符集。这个COLLATE子句指定默认的数据库排序规则。10章,字符集Unicode排序规则,字符集和整理,讨论了名字。

MySQL数据库是一个目录包含对应于数据库中的表文件来实现。因为有一个数据库表的时候没有最初创建的,CREATE DATABASE声明只创建一个目录的MySQL数据目录下。允许数据库命名规则了9.2节,“架构对象名称”。如果一个数据库名称中包含特殊字符,用于数据库的目录名称中包含的编码版本的特征描述第9.2.3,“映射标识符文件名”

通过手动创建一个目录的数据目录下创建一个数据库目录(例如,用mkdir)暂时不支持MySQL 8.0.0。

你也可以使用mysqladmin程序创建数据库。看到4.5.2“,”mysqladmin客户管理MySQL服务器”

13.1.12创建事件语法

CREATE
    [DEFINER = { user | CURRENT_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}

此语句创建一个新的事件和时间表。事件将不会运行,除非事件调度程序启用。有关检查事件调度器状态并使其必要的信息,参见第234.2条,“Event Schdule配置”

CREATE EVENT要求EVENT在模式中,事件是被创造的特权。它可能还需要SET_USER_IDSUPER特权,取决于定义者价值,在本节后面介绍。

一个有效的最低要求CREATE EVENT声明如下:

  • 关键词CREATE EVENT再加上一个事件的名称,它唯一地标识事件的数据库架构。

  • 一个ON SCHEDULE条款,确定何时以及如何往往活动执行。

  • DO条款,其中包含的SQL语句被执行的事件。

这是一个最小的一个例子CREATE EVENT声明:

CREATE EVENT myevent    ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR    DO      UPDATE myschema.mytable SET mycol = mycol + 1;

前面的语句创建一个名为myevent。这一事件执行一次一小时后其创作以运行一个SQL语句的价值增量myschema.mytable表的mycol专栏1

这个event_name必须用最大长度为64个字符的标识符,一个有效的MySQL。事件名称不区分大小写的,所以你不可能有两个事件命名事件MyEvent在相同的模式。一般来说,执政的事件名称的规则是为那些对存储过程的名字相同。看到9.2节,“架构对象名称”

一个事件是一个架构相关。如果没有模式显示的一部分event_name,默认(当前)模式的假设。创建一个特定的模式与架构使用资格的事件,事件的名称schema_nameevent_name语法

这个DEFINER子句指定要使用的访问权限检查在活动执行时的MySQL账户。如果一个user值,它应该是一个指定的MySQL账户&#39;user_name“@”host_name&#39;CURRENT_USER,或CURRENT_USER()。默认的定义者价值是用户执行CREATE EVENT声明。This is the same as specifyingDEFINER = CURRENT_USER明确地.

如果您指定的DEFINERClause,These rules found the Valid定义者用户价值:

  • 如果你没有SET_USER_IDSUPER特权,唯一被允许的user价值是你自己的帐户,指定从字面上或用CURRENT_USER。不能设置定义到其他帐户。

  • 如果你有SET_USER_IDSUPER特权,你可以指定任何语法有效的帐户名。如果帐户不存在,将生成一条警告。

  • 虽然它可以创建一个不存在的事件DEFINER帐户,一个错误发生在事件的执行时间,如果帐户不存在。

有关事件的安全性的更多信息,参见23.6节,“访问控制用于存储程序和视图”

在一个事件的CURRENT_USER()函数返回用于在活动执行时检查权限的帐户,这是定义者用户有关用户审核事件的信息,参见第6.3.13,“基于SQL MySQL账户活动审计”

IF NOT EXISTS具有相同的意义CREATE EVENT至于CREATE TABLE:如果一个事件命名event_name已经存在相同的模式,不采取行动,没有错误的结果。(然而,警告是在这样的情况下,产生的)

这个ON SCHEDULE条款的决定时,多少和多久,event_body定义事件的重复。这句有两种形式:

  • AT timestamp用于一次性事件。它指定一个时间执行事件仅在日期和时间的timestamp,其中必须包括日期和时间,或者必须是一个表达式解析为DateTime值。你可以用一个价值的DATETIMETIMESTAMP为此类型。如果日期在过去,发生了警告,如下所示:

    MySQL的&#62;SELECT NOW();--------------------- | now() | --------------------- | 2006-02-10 23:59:01 | --------------------- 1行集(0.04秒)MySQL &#62;CREATE EVENT e_totals-&#62;ON SCHEDULE AT '2006-02-10 23:59:00'-&#62;DO INSERT INTO test.totals VALUES (NOW());查询行,0行的影响,1报警(0秒)MySQL &#62;SHOW WARNINGS\G*************************** 1。行***************************水平:注意代码:1588message:活动执行时间是在过去完成不保存设置。该事件被创建后立即下降。

    CREATE EVENT报告本身是无效的因为种种原因失败与错误。

    你可以使用CURRENT_TIMESTAMP指定当前日期和时间。在这种情况下,事件的行为就创造了。

    建立在未来的某一时刻相对于当前日期和时间等由短语表示发生的事件从现在开始的三周您可以使用可选的条款+ INTERVAL interval。这个interval部分由两部分组成,数量和时间单位,并且遵循相同的语法规则用于间隔DATE_ADD()函数(见12.7节,“戴特和时间函数”。单位的关键词也都是相同的,但你不能使用任何涉及微秒定义事件时,单位。有一些间隔类型,复杂的时间单位可以用。例如,2分十秒可以表示为+ INTERVAL '2:10' MINUTE_SECOND

    你也可以结合区间。例如,AT CURRENT_TIMESTAMP + INTERVAL 3 WEEK + INTERVAL 2 DAY相当于3周,两天后。这一条款的每一部分必须从+ INTERVAL

  • 重复的行为在有规律的时间间隔,使用EVERY条款.这个每一个关键词跟着一个interval在以往的讨论关键词(+ INTERVAL使用EVERY例如。),每6周方法每6周

    虽然+ INTERVAL条款是不允许的每一个条款,您可以使用相同的复杂的时间单位允许在+ INTERVAL

    一个EVERY条款可能包含一个可选的开始条款.STARTS其次是一个timestamp值,指示当行动应该开始重复,也可以使用区间interval指定的时间量从现在开始。例如,EVERY 3 MONTH STARTS CURRENT_TIMESTAMP + INTERVAL 1 WEEK方法每三个月,从现在开始的一个星期。同样的,你可以表达每两周,开始6小时15分钟从现在作为EVERY 2 WEEK STARTS CURRENT_TIMESTAMP + INTERVAL '6:15' HOUR_MINUTE。不指定开始是使用相同的STARTS CURRENT_TIMESTAMP即为事件指定行动开始后立即重复的事件创建。

    一个EVERY条款可能包含一个可选的末端条款.这个ENDS其次是由一个关键字timestamp价值告诉MySQL的事件时,应停止重复。你也可以使用区间interval末端;例如,EVERY 12 HOUR STARTS CURRENT_TIMESTAMP + INTERVAL 30 MINUTE ENDS CURRENT_TIMESTAMP + INTERVAL 4 WEEK相当于每十二小时三十分钟,从现在开始,和结束四个星期后的现在。不使用ENDS意味着事件继续执行下去。

    ENDS支持复杂的时间单位相同的语法开始做.

    你可以使用STARTS末端,,或不在EVERY条款.

    如果一个重复的事件不会终止在其调度间隔,结果可能是事件的同时运行多个实例。如果这是不可取的,你应该学会一种机制来防止同步实例。例如,您可以使用GET_LOCK()功能,或行或表锁定

这个ON SCHEDULE子句可以使用内置的MySQL的功能和用户变量来获得任何的表情timestampinterval值,它包含。你不可以在表达式中使用存储功能或用户定义的函数,也可以使用任何表引用;然而,你可以使用选择双。这是真实的CREATE EVENTALTER EVENT声明.存储功能,用户定义的函数的引用,在这种情况下,表是不允许的,和失败与错误(见虫# 22830)。

时间在ON SCHEDULE条款使用当前会话的解释time_zone价值。这成为事件的时间区;即是用于事件调度,实际上是在事件执行时的时区。这些时间转换为UTC并随着在事件发生的时间、区域存放mysql.event表这使得活动执行进行定义无论对服务器的时区和夏令时的任何后续变化的影响。关于事件的时间表示更多的信息,参见第23.4.4,事件“元数据”。参见第13.7.6.18,“显示事件的语法”,和24.8节,“information_schema事件表”

通常,当一个事件已经过期,则立即下降。您可以通过指定重写此行为ON COMPLETION PRESERVE。使用在完成不保存仅仅是默认的非持久性行为的明确。

你可以创建一个事件而防止主动使用DISABLE关键词或者,您可以使用使明确的默认状态,这是积极的。这是结合最有用ALTER EVENT(见第13.1.3,“改变的事件语法”

第三价值也可能出现在的地方ENABLE禁用DISABLE ON SLAVE是设置在一个复制的奴隶来表明该事件是在主创造和复制到从一个事件的状态,而不是从执行。看到第17.4.1.16”功能,调用“复制

你可以使用一个事件提供一个评论COMMENT条款.comment可以是任何64个字符的字符串,你想用于描述事件。注释文本,是一个字符串,必须用引号括起来。

这个DO子句指定动作的事件,包括SQL语句。几乎任何有效的MySQL语句可用于存储程序也可以被用作一个预定的事件动作语句。(见第1,“限制存储的程序”。)例如,以下事件e_hourly从删除所有行会议表每小时一次,在这张桌子的一部分site_activity架构:

创建事件e_hourly计划每1小时评论清除会话表的每一个小时,你删除site_activity.sessions;

MySQL存储sql_mode系统变量设置影响事件时创建或改变,始终执行事件与此设置生效,无论当前服务器的SQL模式当事件开始执行

CREATE EVENT语句中包含ALTER EVENT声明在其DO条款似乎成功;然而,当服务器试图执行生成的预定事件,执行失败与错误。

笔记

这样的语句SELECTSHOW只返回一个结果集没有效果时所使用的一种活动;从这些输出不是发送给MySQL的监控,也不存储任何地方。然而,你可以使用这样的语句:SELECT ... INTOINSERT INTO ... SELECT结果那家店。(见后者。实例本节中的一个例子)

图式的事件属于表中引用的默认架构DO条款.任何引用其他架构表必须具备适当的架构名称。

与存储程序,你可以在使用复合语句语法DO条款的运用开始END关键词,如下所示:

分隔符|创建事件e_daily进度每1天的评论保存会话总数然后清除表每一天的开始插入site_activity.totals(时间、总)选择current_timestamp,计数(*)从site_activity.sessions;删除site_activity.sessions;端|分隔符;

本示例使用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);

如果一个事件的定义有SYSTEM_VARIABLES_ADMINSUPER特权,事件可以读写全局变量。为授予这种特权是一个潜在的滥用,必须格外小心,这样做了。

一般来说,任何语句在存储程序是有效的可用于动作语句执行的事件。更多关于语句在存储过程允许的信息,参见第23.2.1,“存储程序的语法”。你可以创建一个事件作为一个存储程序的一部分,但不能由另一个事件创建事件。

13.1.13创建函数的语法

这个CREATE FUNCTION语句用于创建存储函数和用户自定义函数(UDF):

13.1.14创建索引的语法

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)] | (expr)} [ASC | DESC]

index_option:
    KEY_BLOCK_SIZE [=] value
  | index_type
  | WITH PARSER parser_name
  | COMMENT 'string'
  | {VISIBLE | INVISIBLE}

index_type:
    USING {BTREE | HASH}

algorithm_option:
    ALGORITHM [=] {DEFAULT | INPLACE | COPY}

lock_option:
    LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}

通常情况下,你创建一个表的所有指标在时间上本身就是创造CREATE TABLE。看到第13.1.18,“创建表的语法。本指南是特别重要的InnoDB表,其中主要的关键决定数据文件中的行的物理布局。CREATE INDEX使您可以添加到现有的表的索引。

CREATE INDEX映射到ALTER TABLE语句来创建索引。See第13.1.8,“ALTER TABLE语法”CREATE INDEX不能用于创建主键使用;ALTER TABLE相反。有关索引的更多信息,参见第8.3.1,“MySQL如何使用索引”

InnoDB支持二级指标对虚拟列。有关更多信息,参见第13.1.18.9,“二级指标和生成的列”

innodb_stats_persistent设置启用,运行ANALYZE TABLE声明一个InnoDB在创建一个表上的索引表。

该形式的索引规范(key_part1, key_part2, ...)创建多个关键指标。索引键的值是将给定的关键部分所形成的价值观。例如(COL1,COL2,col3)指定一个索引键的值从多个列的索引col1COL2,和col3

key_part规范可以结束ASCDESC指定索引值存储在升序或降序。默认情况下,如果没有了为提升说明符。ASCDESC也不允许搞砸indexes。世纪之mysql 8.0.12,ASCdesc也不允许SPATIAL指标

以下各节描述不同的方面CREATE INDEX声明:

列前缀的关键部分

弦列、索引可以创建只使用主角的列值,使用col_name(length)语法指定索引的前缀长度:

  • 前缀可以指定CHARVARCHARBINARY,和VARBINARY关键部件

  • 前缀必须被指定为BLOBTEXT关键部件。此外,BLOBTEXT列可以被索引只InnoDBMyISAM,和黑洞

  • 前缀限制以字节为单位。然而,前缀长度指标规格CREATE TABLEALTER TABLE,和CREATE INDEX语句被解释为非二进制字符串类型的字符数(CHARVARCHARTEXT)和二进制字符串类型的字节数(BINARYVARBINARYBLOB)。考虑到这一点时指定前缀长度为非二进制字符串列使用多字节字符集。

    前缀前缀长度(在支持和支持)是存储引擎的依赖。例如,一个前缀可达767字节长度InnoDB表使用冗余COMPACT行格式。前缀长度限制为3072字节InnoDB表使用DYNAMIC压缩的行格式。为MyISAM表前缀长度限制为1000字节。

如果指定的索引前缀超过最大列数据类型的大小,CREATE INDEX处理指标如下:

  • 对于非唯一索引,或者出现错误(如果严格的SQL模式启用),或索引的长度减少躺在最大列数据类型的大小,产生一个警告(如果严格的SQL模式不启用)。

  • 一个独特的指标,发生错误,无论SQL模式因为减少索引的长度可能使重复的条目不符合指定的唯一性要求插入。

这里显示的语句中使用的前10个字符创建一个索引name柱(假设姓名有一个二进制字符串类型):

CREATE INDEX part_of_name ON customer (name(10));

如果在列名在前10个字符通常不同,查找使用这个指标不应超过使用整个创建索引慢得多name专栏另外,使用列前缀索引可以使索引文件小得多,可以节省大量的磁盘空间,也可能加快INSERT运营

功能键部分

正常索引索引列的值或前缀的列值。例如,在下面的表格中,对于一个给定的索引项t1包括全行2值的前缀col2由最初的10字节值:

创建表T1(COL1,COL2 varchar varchar(10)(20),指数(col1,col2(10)));

MySQL 8.0.13高支持功能的关键部分,索引表达式的值而不是列或列前缀值。使用功能键部分使索引的值不直接存储在表。实例:

CREATE TABLE t1 (col1 INT, col2 INT, INDEX func_index ((ABS(col1))));
CREATE INDEX idx1 ON t1 ((col1 + col2));
CREATE INDEX idx2 ON t1 ((col1 + col2), (col1 - col2), col1);
ALTER TABLE t1 ADD INDEX ((col1 * 40) DESC);

与多个关键部分指标可以混合功能和功能的关键部件。

ASCdesc对关键零部件的支持功能。

功能键部分必须遵守以下规则。如果一个错误发生的一个关键部分定义包含不允许使用的构造。

  • 在指数的定义,将括号内的表达式以区别于列或列的前缀。例如,这是允许的;封闭在括号表达式:

    INDEX ((col1 + col2), (col3 - col4))
    

    这就产生了一个错误;表达不封闭在括号内:

    INDEX (col1 + col2, col3 - col4)
    
  • 功能键的一部分,不能只由一个列名称。例如,这是不允许的:

    INDEX ((col1), (col2))
    

    相反,写关键部分功能的关键部件,没有括号:

    INDEX (col1, col2)
    
  • 功能键部分表达不能引用列的前缀。一个变通方法,见的讨论SUBSTRING()CAST()在本节稍后

  • 功能的关键部件是不允许外国主要规格。

CREATE TABLE ... LIKE,目标表保存功能的关键部分从原始表。

功能指标为隐藏虚拟生成的列来实现,而这些影响:

UNIQUE是指标,包括关键零部件的支持功能。然而,主键不能包括功能键部分。一个关键要求生成的列被存储,但功能的关键部件虚拟生成的列执行,不存储生成的列。

SPATIAL全文指标不能有功能的关键部件。

如果一个表中没有主键,InnoDB自动提升第一唯一不空对主键索引。这是不支持的UNIQUE NOT NULL有功能的关键指标是方的。

非功能性的指标,如果有重复的指标提出了警告。包含功能的关键部分不具有这一特征指标。

删除一个由功能键部分引用的列的索引,必须先删除。否则,发生了一个错误。

虽然功能的关键部件支持前缀长度规格,功能的关键部件这是不可能的。解决方法是使用SUBSTRING()(或CAST(),在本节后面介绍)。一个功能键部分包含SUBSTRING()功能用于查询的哪里条款必须包含SUBSTRING()以相同的参数。在下面的例子中,只有第二SELECT能够使用索引,因为这是唯一的查询中的参数SUBSTRING()匹配索引规范:

CREATE TABLE tbl (col1 LONGTEXT, INDEX idx1 ((SUBSTRING(col1, 1, 10))));SELECT * FROM tbl WHERE SUBSTRING(col1, 1, 9) = '123456789';SELECT * FROM tbl WHERE SUBSTRING(col1, 1, 10) = '1234567890';

功能键部分使索引的值不能被索引,否则,如JSON价值观。然而,这种语法不工作:

CREATE TABLE employees (data JSON, INDEX ((data->>'$.name')));

不能因为语法->>运营商转化为JSON_UNQUOTE(JSON_EXTRACT(...))JSON_UNQUOTE()返回一个值的数据类型LONGTEXT因此,和隐藏生成的列指定数据类型相同。MySQL不能指数LONGTEXT列指定没有对关键部分的前缀长度,和前缀长度不允许在功能键部分。

索引JSON柱,使用CAST()功能:

CREATE TABLE employees (data JSON, INDEX ((CAST(data->>'$.name' AS CHAR(30)))));

隐藏生成的列指定为VARCHAR(30)数据类型,它可以被索引。为了使指数可用于不需要CAST()要包含在查询优化器自动带CAST()当寻找使用索引。在下面的例子中,该SELECT查询可以使用功能指标虽然CAST()是不能用在哪里条款:

CREATE TABLE employees (
  data JSON,
  INDEX str_index ((CAST(data->>'$.name' AS CHAR(30)))),
  INDEX int_index ((CAST(data->>'$.salary' AS SIGNED)))
);
INSERT INTO employees VALUES
  ('{ "name": "James", "salary": 10000 }'),
  ('{ "name": "Mary", "salary": 12000 }'),
  ('{ "name": "Peter", "salary": 8000 }');
SELECT * FROM employees WHERE data->>'$.name' = 'James';
SELECT * FROM employees WHERE data->>'$.salary' > 9000;

唯一索引

UNIQUE索引创建一个约束,索引中的所有值都必须是不同的。如果你想添加一个键值匹配现有行的新列时发生错误。如果你指定一列前缀值独特索引列值的前缀长度内必须是唯一的。一UNIQUE索引允许多个无效的这可以包含列的值NULL

如果一个表有一个PRIMARY KEY唯一不空指数,由一个单一的列有一个整数类型,您可以使用_rowid参考索引列中SELECT语句,如下:

  • _rowid是指primary key如果有一列PRIMARY KEY由一个单一的整数列。如果有一个主键但它并不是由一个单一的整数列,_rowid不能使用

  • 否则,_rowid是指在第一列唯一不空指数如果指数包括一个整数列。如果第一UNIQUE NOT NULL索引不包含一个整数列,_rowid不能使用

全文指数

FULLTEXT索引只支持为InnoDBMyISAM表只能包括CHARVARCHAR,和TEXT专栏索引总是发生在整个柱;柱前缀索引不支持任何被忽略如果指定前缀长度。看到12.9节,“全文搜索功能”,细节操作

空间索引

这个MyISAMInnoDBNDB,和ARCHIVE存储引擎支持空间列如POINTGEOMETRY。(11.5节,“数据类型”,描述了空间数据类型。)然而,在引擎的空间列索引支持变化。空间和非空间根据以下规则空间列的索引可以使用。

空间柱空间指标都有这些特征:

  • 仅适用于InnoDBMyISAM表指定空间索引在一个错误的其他存储引擎的结果。

  • 在MySQL 8.0.12,一个空间列的索引必须是一个SPATIAL指数这个空间关键词是可选的但隐式创建一个空间列的索引。

  • 提供单一的空间列。空间索引不能创造多个空间列。

  • 索引的列必须是NOT NULL

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

  • 对于主键或唯一索引不允许。

空间列(创建空间索引INDEX独特,或PRIMARY KEY有这些特征):

  • 允许任何存储引擎,支持空间列除外ARCHIVE

  • 列可NULL除非索引主键

  • 对于一个非指数型—SPATIAL指数取决于存储引擎。目前,B-树的应用。

  • 一列,可以允许NULL值仅为InnoDBMyISAM,和MEMORY

指数期权

以下的关键零件清单,指数期权可以给。一个index_option值可以被任何以下:

  • KEY_BLOCK_SIZE [=] value

    MyISAM桌子,key_block_size还可以指定字节大小使用索引键块。价值作为一个提示;不同的尺寸可以在必要时使用。一KEY_BLOCK_SIZE一个索引定义中指定的值将重写表级key_block_size价值

    KEY_BLOCK_SIZE不支持在水平指数InnoDB表。这第13.1.18,“创建表的语法

  • index_type

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

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

    表1,“索引类型,每个存储引擎”显示了不同的存储引擎支持允许索引类型的值。在多个指数型上市,第一个是默认时没有索引类型说明符给定。存储引擎的表中未列出的不支持index_type在索引定义条款

    表13.1每个存储引擎的索引类型

    存储引擎可允许的索引类型
    InnoDBBTREE
    MyISAMBTREE
    MEMORY/HASHB树

    这个index_type条款不能用于全文索引或(MySQL 8.0.12之前)SPATIAL INDEX规格全文索引实现存储引擎的依赖。空间索引是R-树索引实现。

    如果你指定一个索引类型无效,对于一个给定的存储引擎,但另一个索引类型是可用的发动机可以使用不影响查询结果,该引擎使用可用的类型。解析器识别RTREE作为类型名称。在MySQL 8.0.12,这是只允许空间指标。prior to 8.0.12,RTREE无法为任何指定的存储引擎。

    笔记

    使用的index_type选择之前打开(放)tbl_name条款已过时;使用这个位置的选择将在以后的MySQL版本中删除。如果一个index_type选择是在前、后的位置,最后的选择应用。

    TYPE type_name是公认的同义词使用type_name。然而,使用是首选的形式

    下表显示指数特征的存储引擎,支持index_type选项

    表2 InnoDB存储引擎索引特点

    指数类指数型存储空值允许多个空值是空的扫描类型不为空的扫描类型
    主键BTREEN / AN / A
    独特BTREE指数指数
    钥匙BTREE指数指数
    FULLTEXTN / A
    SPATIALN / AN / AN / A

    表13.3存储引擎MyISAM索引特点

    指数类指数型存储空值允许多个空值是空的扫描类型不为空的扫描类型
    主键BTREEN / AN / A
    独特BTREE指数指数
    钥匙BTREE指数指数
    FULLTEXTN / A
    SPATIALN / AN / AN / A

    表13.4内存存储引擎索引特点

    指数类指数型存储空值允许多个空值是空的扫描类型不为空的扫描类型
    主键BTREEN / AN / A
    独特BTREE指数指数
    钥匙BTREE指数指数
    主键HASHN / AN / A
    独特HASH指数指数
    钥匙HASH指数指数

  • WITH PARSER parser_name

    此选项只能用于FULLTEXT指标。它将解析器插件与索引全文索引和搜索操作,如果需要特殊处理。InnoDBMyISAM支持全文解析插件。看到全文解析插件第28.2.4.4,“写满文本解析器插件”更多信息

  • COMMENT 'string'

    指标定义可以包含最多1024个字符,一个可选的评论。

    这个MERGE_THRESHOLD索引页可以配置单个指标的使用index_option评论的条款CREATE INDEX声明。例如:

    CREATE TABLE t1 (id INT);CREATE INDEX id_index ON t1 (id) COMMENT 'MERGE_THRESHOLD=40';

    如果一个索引页的页全比例低于MERGE_THRESHOLD值时删除一行或一行后缩短了更新操作,InnoDB试图索引页与相邻的索引页合并。默认的merge_threshold值是50,这是以前的硬编码的值。

    MERGE_THRESHOLD也可以定义在表级使用指数CREATE TABLEALTER TABLE声明.有关更多信息,参见第15.6.12,“配置合并阈值的索引页”

  • VISIBLE看不见的

    指定索引的知名度。指标是可见的默认。一个看不见的指标不是由优化器使用。指数的知名度规范适用于非主键索引(无论是明确的或隐含的)。有关更多信息,参见第8.3.12节“隐形反射”

表复制和锁定选项

ALGORITHM锁具条款可能会影响表复制的方法,虽然其指标正在修改读写并发水平表。他们有同样的含义ALTER TABLE声明。有关更多信息,参见第13.1.8,“ALTER TABLE语法”

13.1.15创建过程和创建函数的语法

CREATE
    [DEFINER = { user | CURRENT_USER }]
    PROCEDURE sp_name ([proc_parameter[,...]])
    [characteristic ...] routine_body

CREATE
    [DEFINER = { user | CURRENT_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支持UDFs(用户自定义函数)。看到28.4节,“MySQL”添加新的功能。UDF可以被视为一个外部存储功能。存储函数与UDFs分享自己的命名空间。看到9.2.4节,“函数名称解析和解决”,用于描述服务器如何解释不同类型的函数的引用规则。

调用一个存储过程,使用CALL声明(见第13.2.1,“调用语法”)。调用一个存储功能,是指表达它。该函数返回一个值时,表达式求值。

CREATE PROCEDURECREATE FUNCTION要求CREATE ROUTINE特权。他们可能还需要SET_USER_IDSUPER特权,取决于定义者价值,在本节后面介绍。如果启用了二进制日志,CREATE FUNCTION可能需要SUPER特权,如23.7节,“二进制日志存储程序”

默认情况下,MySQL会自动授予ALTER ROUTINEEXECUTE在常规的创造者的特权。这种行为可以通过禁用automatic_sp_privileges系统变量。见第23.2.2,“存储程序和MySQL的特权”

这个DEFINERSQL安全子句指定安全上下文时要使用检查访问权限在程序的执行时间,在本节后面介绍。

如果程序的名字是作为一个内置的SQL函数的名称相同,发生语法错误除非你的名字和下面的括号之间的空间定义的常规或调用后。出于这个原因,避免使用现有的SQL函数的名字为自己的存储过程。

这个IGNORE_SPACESQL模式适用于内置函数,不存储程序。一个存储程序名后总是允许有空格,不管IGNORE_SPACE启用

封闭在括号中的参数列表必须存在。如果没有参数,一个空的参数列表()应使用。参数名称不区分大小写。

每个参数是一个IN参数的默认值。指定其他参数,使用关键字INOUT在参数名称

笔记

指定一个参数为IN,或INOUT有效期只有一个程序。对于一个FUNCTION,参数都被视为进入参数.

一个IN参数传递一个值到一个程序。程序可能会修改这个值,但修改不来电,可见当过程返回。一个参数传递一个值返回给调用者的程序。它的初始值NULL在过程中,其价值是调用者可见当过程返回。一个INOUT参数由调用初始化,可以通过程序修改,并通过程序做出任何改变是调用者可见当过程返回。

对于每个OUTINOUT参数,在通过一个用户定义的变量CALL语句调用的程序,这样你可以得到它的值在程序运行时。如果你调用程序在另一个存储过程或函数,也可以通过常规的参数或局部变量作为常规INOUT参数.如果你是在一个触发器调用的程序,你也可以通过col_name作为一个INOUT参数.

常规参数不能在常规的准备好的语句引用;见第1,“限制存储的程序”

下面的示例显示了一个简单的存储过程的使用OUT参数:

MySQL的&#62;delimiter //MySQL的&#62;CREATE PROCEDURE simpleproc (OUT param1 INT)-&#62;BEGIN-&#62;SELECT COUNT(*) INTO param1 FROM t;-&#62;END//查询好,为受影响的行(0.001秒)MySQL &#62;delimiter ;MySQL的&#62;CALL simpleproc(@a);查询好,为受影响的行(0.001秒)MySQL &#62;SELECT @a;------ | @ | ------ | 3 | ------ 1行集(0秒)

该示例使用MySQL客户delimiter命令更改语句分隔符从//当程序被定义。这使在程序中使用了身体必须通过服务器而不是被分隔符MySQL本身。看到23.1节,“定义存储的程序”

这个RETURNS条款可能只在特定的功能,它是强制性的。它表示函数的返回类型,函数体必须包含RETURN value声明。如果RETURN语句返回一个值类型的值是不同的,取决于适当的类型。例如,如果一个函数指定一个ENUMSET中的价值退货条款,但RETURN语句返回一个整数,返回值的函数为对应的字符串ENUM组成员SET会员

下面的示例函数接受一个参数,使用SQL函数执行一个操作,并返回结果。在这种情况下,没有必要使用delimiter因为函数定义不包含内部语句分隔符:

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)

参数类型和函数返回类型可以声明使用任何有效的数据类型。这个COLLATE如果前面的属性可以使用字符集属性

这个routine_body由一个有效的SQL例程声明。这可以是一个简单的语句,如SELECTINSERT复合语句,或用开始END。复合语句可以包含声明、循环等控制结构语句。这些语句的语法描述13.6节“复合语句语法”

MySQL允许例程包含DDL语句,如CREATE。MySQL也允许存储过程(而不是存储功能)包含SQL交易报表等COMMIT。存储功能可能不包含执行显式或隐式提交或回滚语句。这些语句不支持的SQL标准的要求,即每个DBMS厂商可以决定是否允许他们。

语句返回结果集可以在一个存储过程而不是在存储功能。这项禁令包括SELECT声明没有var_list条款和其他报表等SHOWEXPLAIN,和CHECK TABLE。语句可以确定在函数定义时返回一个结果集,一不允许返回结果集的功能出现错误(ER_SP_NO_RETSET)。语句,仅能确定在运行时返回一个结果集,一程序%s不能返回一个结果集在给定的上下文出现错误(ER_SP_BADSELECT

USE在存储程序语句是不允许的。当一个程序被调用时,一个隐含的使用db_name执行(了当程序终止)。原因有给定的默认数据库同时执行的程序。除了常规的默认数据库应具备适当的数据库名称,数据库对象的引用。

有关财务报表不允许在存储程序的更多信息,参见第1,“限制存储的程序”

有关调用存储过程的编写的一个语言,MySQL的接口程序的信息,参见第13.2.1,“调用语法”

MySQL存储sql_mode系统变量的设置在一个常规的创建或修改,并始终执行例程使用此设置生效,无论当前服务器的SQL模式时,程序开始执行

从调用SQL模式,常规的开关现象的争论和结果值常规参数赋值后评价。如果你定义了严格的SQL模式常规但调用它在非严格模式,论证常规参数赋值不发生严格模式。如果你需要通过一个常规的表达是严格的SQL模式分配,你应该调用程序与严格的模式。

这个COMMENT特点是MySQL扩展,可用来描述存储程序。这条信息显示的SHOW CREATE PROCEDURESHOW CREATE FUNCTION声明.

这个LANGUAGE特征表示的语言,常规是写。服务器忽略了这一特点;只支持SQL例程。

被认为是一个常规确定性如果它总是产生相同的结果相同的输入参数,并不确定性otherwise。如果曼弗雷迪或法拉利吗DETERMINISTIC也没有不确定性在常规定义,默认是NOT DETERMINISTIC。声明一个函数是确定性的,你必须指定确定性明确地.

对常规性的评估是基于诚实的创作者:MySQL不检查常规申报DETERMINISTIC是免费的,产生不确定的结果的陈述。然而,misdeclaring常规可能会影响结果或影响性能。声明一个不确定的路线确定性可能导致优化器做出错误的执行计划的选择,意想不到的结果。声明一个确定性的惯例NONDETERMINISTIC可能造成可不能用降低性能优化。

如果启用了二进制日志,DETERMINISTIC常规定义MySQL接受特性的影响。看到23.7节,“二进制日志存储程序”

一种程序,包含NOW()函数(或其同义词)或RAND()是不确定的,但它仍可能复制安全。为NOW(),二进制日志包含时间戳和复制正确。RAND()复制正确只要是程序执行期间被称为只有一次。(你可以考虑程序执行的时间戳和随机数种子为隐式输入,在主人和奴隶是相同的)

几个特点提供了常规的使用数据信息的性质。在MySQL数据库中,这些特征仅仅是咨询。服务器不使用它们来限制哪些语句的程序将被允许执行。

  • CONTAINS SQL表明常规不包含语句读取或写入数据。这是默认的如果没有这些特点给出明确。这样的陈述的例子SET @x = 1DO RELEASE_LOCK('abc')但是,执行不能读和写数据。

  • NO SQL表明常规不包含SQL语句。

  • READS SQL DATA表明例程包含语句读取数据(例如,SELECT),但没有说明写数据。

  • MODIFIES SQL DATA表明常规包含可能写数据报表(例如,INSERTDELETE

这个SQL SECURITY特性可以定义者INVOKER指定安全上下文;即,无论常规执行使用权限的帐户在常规命名定义者条款或用户调用它。此帐户必须有权访问数据库的日常关联。默认值是DEFINER。用户调用程序必须有EXECUTE特权,是必须的定义者如果在定义的安全上下文中执行的程序。

这个DEFINER子句指定MySQL帐户时要使用检查访问权限,在程序的执行时间为例程,有SQL安全定义特征

如果一个user给出值为定义者条款,它应该是一个指定的MySQL账户'user_name'@'host_name'CURRENT_USER,或CURRENT_USER()。默认的定义者价值是用户执行CREATE PROCEDURECREATE FUNCTION声明。这是作为指定相同的DEFINER = CURRENT_USER明确地.

如果您指定的DEFINERClause,These rules found the Valid定义者用户价值:

  • 如果你没有SET_USER_IDSUPER特权,唯一被允许的user价值是你自己的帐户,指定从字面上或用CURRENT_USER。不能设置定义到其他帐户。

  • 如果你有SET_USER_IDSUPER特权,你可以指定任何语法有效的帐户名。如果帐户不存在,将生成一条警告。

  • 虽然它是可以用一个不存在的创建一个常规DEFINER帐户,一个错误发生在程序的执行时间,如果SQL安全DEFINER但定义帐户不存在

为更多的信息关于存储程序的安全,看23.6节,“访问控制用于存储程序和视图”

在存储程序的定义与SQL SECURITY DEFINER特征,CURRENT_USER常规的回报定义者价值。有关用户审计在存储程序的信息,参见第6.3.13,“基于SQL MySQL账户活动审计”

考虑下面的程序,它显示一个数在上市的MySQL账户数量mysql.user

CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count()BEGIN  SELECT 'Number of accounts:', COUNT(*) FROM mysql.user;END;

程序分配一个DEFINER考虑“管理员”localhost无论哪个用户定义。它执行的,无论哪个用户调用它的特权(因为默认的安全特性DEFINER)。程序的成功或失败取决于是否调用了EXECUTE它与特权“管理员”localhostSELECT特权的mysql.user

现在假设程序中定义的SQL SECURITY INVOKER特征:

CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count()SQL SECURITY INVOKERBEGIN  SELECT 'Number of accounts:', COUNT(*) FROM mysql.user;END;

程序还具有DEFINER属于“管理员”localhost,但在这种情况下,它执行的调用用户的权限。因此,程序的成功或失败取决于调用的EXECUTE它与特权SELECT特权的mysql.user

服务器处理的常规参数的数据类型,局部常规变了DECLARE,或函数返回值如下:

  • 作业检查数据类型不匹配和溢出。转换和溢出问题导致的警告,或严格的SQL模式错误。

  • 只有标量值可以分配。例如,像这样的语句SET x = (SELECT 1, 2)是无效的

  • 字符数据类型,如果有CHARACTER SET在声明属性,指定字符集的默认排序规则使用。如果整理属性也在场,整理而不是使用的默认排序规则。

    如果CHARACTER SET整理属性不存在,数据库的字符集和整理效果在常规的创作时间的使用。为了避免服务器使用数据库字符集和整理,提供明确的CHARACTER SET整理对于字符数据参数属性。

    如果您更改数据库的默认字符集、整理、存储程序,使用默认的数据库必须删除并重新创建的,他们使用新的默认值。

    数据库的字符集和整理的价值了character_set_databasecollation_database系统变量。有关更多信息,参见第3,“数据库字符集和整理”

13.1.16创建服务器的语法

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存储引擎。这个创建服务器语句创建一个新的行servers表中MySQL数据库这一声明要求SUPER特权

这个server_name应该是服务器的一个独特的参考。服务器定义在服务器范围是全球性的,它不可能使服务器定义一个特定的数据库。server_name有一个64个字符的最大长度(名称不能超过64个字符会被自动截断),并且是不区分大小写。你可以指定名称为带引号的字符串。

这个wrapper_name是一个标识符,可以用单引号引用。

对于每个option您必须指定一个字符或数字的文字。字符是gb3212编码,支持64个字符,默认最大长度为空白(空)字符串。字符串字面值是默默截断到64字符。数字文字量必须在0和9999之间的数,默认值是0。

笔记

这个OWNER选择目前不适用,并对所创建的服务器连接的所有权或经营无影响。

这个CREATE SERVER语句创建在一个条目mysql.servers表,以后可以用CREATE TABLE当创建一个表联邦表该选项指定将用于填充在列mysql.servers表表列server_nameHostDBUsername密码Port插座

例如:

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';

有关更多信息,参见16.8节,“联邦存储引擎”

CREATE SERVER一个隐含的承诺的原因。看到13.3.3部分,”声明,因为一个隐含的承诺”

CREATE SERVER不写入二进制日志,不管日志格式,使用。

13.1.17创造空间参考系统的语法

CREATE OR REPLACE SPATIAL REFERENCE SYSTEM
    srid srs_attribute ...

CREATE SPATIAL REFERENCE SYSTEM
    [IF NOT EXISTS]
    srid srs_attribute ...

srs_attribute: {
    NAME 'srs_name'
  | DEFINITION 'definition'
  | ORGANIZATION 'org_name' IDENTIFIED BY org_id
  | DESCRIPTION 'description'
}

srid, org_id: 32-bit unsigned integer

这个语句创建一个空间参考系统(SRS)定义并存储在数据字典。这个定义可以检查使用INFORMATION_SCHEMAST_SPATIAL_REFERENCE_SYSTEMS桌子。这句话需要SUPER特权

如果没有OR REPLACE也没有如果不存在是指定的,如果用SRID值SRS定义已经存在发生错误。

CREATE OR REPLACE语法,任何现有的SRS定义具有相同SRID值代替,除非SRID值是通过一些列使用现有的表。在这种情况下,发生了一个错误。例如:

MySQL的&#62;CREATE OR REPLACE SPATIAL REFERENCE SYSTEM 4326 ...;错误3716(sr005):不能修改方案4326。有至少一列取决于它。

确定列使用抗血清,用这个查询:

SELECT * FROM INFORMATION_SCHEMA.ST_GEOMETRY_COLUMNS WHERE SRS_ID=4326;

CREATE ... IF NOT EXISTS语法,任何现有的SRS定义具有相同SRID值使得新的定义被忽略,一个警告出现。

SRID值必须在32位无符号整数的范围,这些限制:

  • SRID 0是一个有效的扩散但不能使用CREATE SPATIAL REFERENCE SYSTEM

  • 如果该值是一个保留SRID范围发生了警告。保留的范围[ 0, 32767 ](保留由EPSG),[ 60000000, 69999999 ](保留由EPSG),和[ 2000000000, 2147483647 ](保留MySQL)。每股收益增长率为欧洲石油调查组

  • 用户不应建立在保留SRIDs SRSS范围。这样跑,srids将与未来的SRS定义分布式MySQL冲突的风险,结果表明,新系统提供的SRSS没有安装MySQL升级或自定义的SRSS覆盖。

用于声明属性必须满足这些条件:

  • 属性可以是任意顺序,但没有属性可以不止一次。

  • 这个NAME定义属性是强制性的

  • 这个NAMEsrs_name属性值必须是唯一的。的组合组织org_nameorg_id属性值必须是独一无二的。

  • 这个NAMEsrs_name属性值组织org_name属性值不能为空或开始或结束的空白。

  • 属性规格字符串值不能包含控制字符,包括换行符。

  • 下表显示字符串属性值的最大长度。

    表13.5创造空间参考系统属性长度

    属性最大长度(字符)
    NAME八十
    DEFINITION四千零九十六
    ORGANIZATION二百五十六
    DESCRIPTION二千零四十八

下面是一个例子CREATE SPATIAL REFERENCE SYSTEM声明。这个定义价值被重新格式化到多行的可读性。(该声明是合法的,价值却必须在一行上。)

CREATE SPATIAL REFERENCE SYSTEM 4120
NAME 'Greek'
ORGANIZATION 'EPSG' IDENTIFIED BY 4120
DEFINITION
  'GEOGCS["Greek",DATUM["Greek",SPHEROID["Bessel 1841",
  6377397.155,299.1528128,AUTHORITY["EPSG","7004"]],
  AUTHORITY["EPSG","6120"]],PRIMEM["Greenwich",0,
  AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943278,
  AUTHORITY["EPSG","9122"]],AXIS["Lat",NORTH],AXIS["Lon",EAST],
  AUTHORITY["EPSG","4120"]]';

SRS定义的语法是基于定义的语法OpenGIS规范:坐标转换服务1、修订,OGC 01-009,2001年1月12日,第7.2节。本规范是可用的http://www.opengeospatial.org /标准/ CT

MySQL将这些规范的修改:

  • 只有<horz cs>生产规则实施(即地理和预计的SRSS)。

  • 有一个可选的、非标准<authority>条款<parameter>。这使得有可能识别投影参数的权威而不是名字。

  • newlines SRS的定义可能不包含。

13.1.18创建表的语法

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
  | [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (key_part,...)
      [index_option] ...
  | {INDEX|KEY} [index_name] [index_type] (key_part,...)
      [index_option] ...
  | [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY]
      [index_name] [index_type] (key_part,...)
      [index_option] ...
  | {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (key_part,...)
      [index_option] ...
  | [CONSTRAINT [symbol]] FOREIGN KEY
      [index_name] (key_part,...) reference_definition
  | CHECK (expr)

column_definition:
    data_type [NOT NULL | NULL] [DEFAULT {literal | (expr)} ]
      [AUTO_INCREMENT] [UNIQUE [KEY]] [[PRIMARY] KEY]
      [COMMENT 'string']
      [COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}]
      [reference_definition]
  | data_type [GENERATED ALWAYS] AS (expression)
      [VIRTUAL | STORED] [NOT NULL | NULL]
      [UNIQUE [KEY]] [[PRIMARY] KEY]
      [COMMENT 'string']

data_type:
    (see Chapter 11, Data Types)

key_part: {col_name [(length)] | (expr)} [ASC | DESC]

index_type:
    USING {BTREE | HASH}

index_option:
    KEY_BLOCK_SIZE [=] value
  | index_type
  | WITH PARSER parser_name
  | COMMENT 'string'
  | {VISIBLE | INVISIBLE}

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
  | 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存储引擎。如果表中存在发生错误,如果没有默认的数据库,如果数据库不存在。

对于一个表的物理表示形式的信息,参见第13.1.18.2,“文件创建创建表”

CREATE TABLE声明,包括所有的规格表选项存储在MySQL创建表时。有关更多信息,参见第13.1.18.1,“创建表的语句保留”

有几个方面CREATE TABLE声明,本节中的以下主题下的描述:

表名

  • tbl_name

    表名可以被指定为db_name.tbl_name在一个特定的数据库中创建表。这部作品无论是否有一个默认的数据库,假设数据库存在。如果你使用带引号的标识符,名字分别引用的数据库和表。例如,写` mydb ` ` `存储。,不`mydb.mytbl`

    允许的表名称的规则了9.2节,“架构对象名称”

  • IF NOT EXISTS

    防止错误发生的如果表存在。然而,没有验证现有的表结构相同的结果CREATE TABLE声明

临时表

你可以使用TEMPORARY当创建关键字在桌子上。在临时表只在当前会话中可见,并自动删除会话时关闭。有关更多信息,参见第13.1.18.3,“创建临时表的语法”

克隆或复制的表

列的数据类型和属性

有一个硬限制每桌4096列,但有效的最大可能对一个给定的表越来越取决于讨论的因素第c.10.4,“限制表的列数和行的大小”

  • data_type

    data_type代表一个列定义的数据类型。一个完整的描述可用于指定列的数据类型的语法,以及每种类型的属性的信息,参见11章,数据类型

    • 一些属性不适用于所有的数据类型。AUTO_INCREMENT只适用于整型和浮点型。MySQL 8.0.13之前,默认不适用于BLOBTEXT几何,和JSON类型

    • 字符数据类型(CHARVARCHARTEXT)可以包括字符集COLLATE属性为列指定的字符集和整理。详情见10章,字符集Unicode排序规则,CHARSET是同义词字符集。。。。。。。例子:

      CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);
      

      MySQL 8对长度规格在字符列的定义。长度BINARYVARBINARY在字节

    • CHARVARCHARBINARY,和VARBINARY列,索引可以创建只使用主角的列值,使用col_namelength语法指定索引的前缀长度。BLOBTEXT列也可以被索引,但前缀长度必须被给予。前缀长度给出了字符的二进制字符串类型和字节的二进制字符串类型。那是,索引项包括第一length人物每一列的值CHARVARCHAR,和TEXT列,和第一length每个字节的列值BINARYVARBINARY,和BLOB专栏索引只是一个前缀的列值,这样可以使索引文件小得多。关于前缀索引的更多信息,参见第13.1.14,“创建索引的语法”

      只有InnoDBMyISAM存储引擎支持索引BLOBTEXT列。例如:

      创建测试表(blob_col blob,指数(blob_col(10)));

      如果指定的索引前缀超过最大列数据类型的大小,CREATE TABLE处理指标如下:

      • 对于非唯一索引,或者出现错误(如果严格的SQL模式启用),或索引的长度减少躺在最大列数据类型的大小,产生一个警告(如果严格的SQL模式不启用)。

      • 一个独特的指标,发生错误,无论SQL模式因为减少索引的长度可能使重复的条目不符合指定的唯一性要求插入。

    • JSON列不能被索引。你可以解决这个限制,通过创建一个在生成的列从提取物的标量值指数JSON专栏看到索引生成的列提供一个JSON列索引对于一个具体的例子

  • NOT NULL | NULL

    如果没有NULL也没有不为空指定列的作为虽然NULL被指定的

    在MySQL 8中,只有InnoDBMyISAM,和MEMORY存储引擎支持索引的列可以有无效的价值观。在其他情况下,你必须声明索引列NOT NULL或者是一个错误的结果。

  • DEFAULT

    指定列的默认值。有关默认值处理的更多信息,包括案列定义包括不明确DEFAULT值,见11.7节,“数据类型的默认值”

    如果NO_ZERO_DATENO_ZERO_IN_DATESQL模式启用和日期值默认是不正确的显示模式,CREATE TABLE产生一个警告:如果严格的SQL模式不启用,如果启用严格模式错误。例如,用NO_ZERO_IN_DATE启用,默认的日期2010-00-00 C1警告你

  • AUTO_INCREMENT

    一个整数或浮点列可以有额外的属性AUTO_INCREMENT。当你插入一个值无效的(推荐)或0为索引汽车列,列设置为下一个序列值。这通常是value+1,在那里value是最大的value for the column currently in the table。汽车序列的开始1

    检索AUTO_INCREMENT插入一行后的值,使用LAST_INSERT_ID()SQL函数或mysql_insert_id()C API函数。看到12.14节,“信息功能”,和第27.7.7.38,“mysql_insert_id()”

    如果NO_AUTO_VALUE_ON_ZEROSQL模式被启用,您可以存储进入AUTO_INCREMENT没有生成新的序列值。看到第5.1.10,”服务器的SQL模式”

    只能有一个AUTO_INCREMENT柱表,它必须被索引,它不能有一个默认价值。一个AUTO_INCREMENT塔的正常工作,如果它只包含正面的价值观。插入一个负数是插入一个非常大的正数。这样做是为了避免精度问题当数包裹从正到负,也确保你不小心把一个AUTO_INCREMENT列包含

    MyISAM表,您可以指定一个汽车在多个关键次柱柱。看到第3,“用auto_increment”

    使MySQL与ODBC兼容的应用,你可以找到AUTO_INCREMENT最后插入的行的查询值:

    SELECT * FROMtbl_name哪里auto_col是空的

    此方法要求sql_auto_is_null变量没有设置为0。看到第5.1.7,服务器“系统变量”

    有关InnoDB汽车,看到第15.8.1.5,”auto_increment InnoDB”处理。有关AUTO_INCREMENT和MySQL复制,看第17.4.1.1,“复制和auto_increment”

  • COMMENT

    一个列的评论可以指定的COMMENT选项,1024个字符。评论显示的SHOW CREATE TABLESHOW FULL COLUMNS声明.

  • COLUMN_FORMAT

    MySQL集群用来确定列的存储格式。这个选项目前已经在使用存储引擎的表列以外没有影响NDB。在MySQL 5.0后来,column_format是银色的

  • GENERATED ALWAYS

    用于指定生成的列的表达。有关生成的列,看到第13.1.18.8,“创建表和生成的列”

    存储生成的列可以被索引InnoDB支持二级指标虚拟生成的列。看到第13.1.18.9,“二级指标和生成的列”

索引和外键

几个关键词适用于创建索引和外键。对于一般的背景除了下面的说明,见第13.1.14,“创建索引的语法”,和第13.1.18.6,“使用外键约束”

  • CONSTRAINT symbol

    如果CONSTRAINT symbol给出的条款,symbol值,如果使用,在数据库中必须是唯一的。一个重复的symbol在一个错误的结果。如果没有给出的条款,或symbol不包括以下约束关键词,该约束的名称自动创建。

  • PRIMARY KEY

    唯一索引的所有键列必须定义为NOT NULL。如果没有显式声明为不为空他们说,MySQL也(默默)。一个表只能有一个PRIMARY KEY。一个名字primary key总是PRIMARY因此,它不能作为任何其他类型的索引的名称。

    如果你没有一个PRIMARY KEY和应用要求主键你的表,MySQL返回第一UNIQUE指数没有无效的列为PRIMARY KEY

    进入InnoDB表,保持primary key短减少辅助索引存储开销。每一次索引项包含相应的行的主键列复制。(见第15.8.2.1,“聚集和二级指标”。)

    在创建一个表,PRIMARY KEY是放在第一位,其次是所有独特指标,然后非唯一索引。这有助于MySQL优化器的优先指标的使用也更快速的检测重复UNIQUE钥匙

    PRIMARY KEY可以多列索引。但是,您不能创建多列索引使用主键在一列规范的关键属性。这样做不仅标志着单柱为主要。你必须使用一个单独的PRIMARY KEY(key_part, ...)条款.

    如果一个表有一个PRIMARY KEY唯一不空指数,由一个单一的列有一个整数类型,您可以使用_rowid参考索引列中SELECT报表,如唯一索引

    在MySQL中,name of aPRIMARY KEY首要。其他指标,如果你不指定一个名称,索引分配相同的名称作为第一个索引列,一个可选的后缀(_2_3...)使它独特的。你可以看到一个表使用索引名称显示指数tbl_name。看到第13.7.6.22,显示指数的语法”

  • KEY | INDEX

    KEY通常是一个同义词指数。关键属性PRIMARY KEY还可以指定只钥匙当给定的列定义。这是实现与其他数据库系统的兼容性。

  • UNIQUE

    UNIQUE索引创建一个约束,索引中的所有值都必须是不同的。如果你想添加一个键值匹配现有行的新列时发生错误。所有的引擎,一个独特索引允许多个NULL这可以包含列的值无效的。如果你指定一列前缀值UNIQUE索引列值的前缀长度内必须是唯一的。

    如果一个表有一个PRIMARY KEY唯一不空指数,由一个单一的列有一个整数类型,您可以使用_rowid参考索引列中SELECT报表,如唯一索引

  • FULLTEXT

    FULLTEXT指数是一种特殊类型的用于全文搜索指数。只有InnoDBMyISAM存储引擎支持全文指标。他们可以创建只从CHARVARCHAR,和TEXT专栏索引总是发生在整个柱;柱前缀索引不支持任何被忽略如果指定前缀长度。看到12.9节,“全文搜索功能”,细节操作。一WITH PARSER子句可以指定为index_option联想到一个解析器插件与指标值如果全文索引和搜索操作,需要特殊处理。本条款只适用于全文指标InnoDBMyISAM支持全文解析插件。看到全文解析插件第28.2.4.4,“写满文本解析器插件”更多信息

  • SPATIAL

    您可以创建SPATIAL对空间数据类型指标。空间类型的支持只InnoDBMyISAM表和索引的列必须声明为不为空。看到11.5节,“数据类型”

  • FOREIGN KEY

    MySQL支持外键,这让你交叉引用相关数据在表和外键约束,这有助于保持这种传播的数据一致。定义和选项的信息,参见reference_definition,和reference_option

    Partictionable tablesInnoDB存储引擎不支持外键。看到22.6节,“分区”的约束和限制为更多的信息

  • CHECK

    这个CHECK条款解析但所有存储引擎忽略。看到第1.8.2.3,“外键”的区别

  • key_part

    • key_part规范可以结束ASCDESC指定索引值存储在升序或降序。默认情况下,如果没有了为提升说明符。

    • 前缀定义的length属性,可以达到767字节长度InnoDB表使用REDUNDANT粉盒行格式。前缀长度限制为3072字节InnoDB表使用动态COMPRESSED行格式。为MyISAMlength limit is the tables,1000字节的前缀。

      前缀限制以字节为单位。然而,前缀长度指标规格CREATE TABLEALTER TABLE,和CREATE INDEX语句被解释为非二进制字符串类型的字符数(CHARVARCHARTEXT)和二进制字符串类型的字节数(BINARYVARBINARYBLOB)。考虑到这一点时指定前缀长度为非二进制字符串列使用多字节字符集。

  • index_type

    某些存储引擎允许你指定一个索引类型创建索引时。对于语法index_type说明符使用type_name

    例子:

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

    首选的位置USING是索引列列表后。它可以在列列表给出,但使用该位置的选择支持已被废弃,将在未来的MySQL版本中删除。

  • index_option

    index_option值指定索引选项

    • KEY_BLOCK_SIZE

      MyISAM桌子,key_block_size还可以指定字节大小使用索引键块。价值作为一个提示;不同的尺寸可以在必要时使用。一KEY_BLOCK_SIZE一个索引定义中指定的值将重写表级key_block_size价值

      关于表的信息KEY_BLOCK_SIZE属性,看表选项

    • WITH PARSER

      这个WITH PARSER选项只能用于全文指标。它将解析器插件与索引全文索引和搜索操作,如果需要特殊处理。InnoDBMyISAM支持全文插件解析器。如果你有一个MyISAM一个相关的全文解析插件表,您可以转换表InnoDB使用ALTER TABLE

    • COMMENT

      在MySQL 8中,指数的定义可以包含最多1024个字符,一个可选的评论。

      你可以设置InnoDBmerge_threshold一个人的价值指数index_option评论条款.看到第15.6.12,“配置合并阈值的索引页”

    关于允许的更多信息index_option值,见第13.1.14,“创建索引的语法”。有关索引的更多信息,参见第8.3.1,“MySQL如何使用索引”

  • reference_definition

    reference_definition语法的细节和例子,看第13.1.18.6,“使用外键约束”。具体信息中的外键InnoDB,看到第15.8.1.6,“InnoDB和外键约束”

    InnoDB表支持外键约束检查。所引用的表的列必须显式命名。两在删除ON UPDATE对外键的行为。更详细的信息和例子,看第13.1.18.6,“使用外键约束”。具体信息中的外键InnoDB,看到第15.8.1.6,“InnoDB和外键约束”

    其他的存储引擎,MySQL服务器解析并忽略FOREIGN KEY推荐信语法CREATE TABLE声明.看到第1.8.2.3,“外键”的区别

    重要

    熟悉ANSI/ISO SQL标准的用户,请注意,任何存储引擎,包括InnoDBenforces recognizes or,The比赛用于引用完整性约束定义条款。使用一个显式的MATCH条款没有规定的效果,也使在删除ON UPDATE条款不容忽视。由于这些原因,指定比赛should be回避。

    这个MATCH子句在SQL标准的控制无效的在复合值(多栏)外键处理比较时,主键。InnoDB基本上实现了所定义的语义搭配简单,它允许外键是全部或部分NULL。在这种情况下,在(子表)行包含这样一个外键允许插入,和不匹配的引用的任何行(母)表。可以使用触发器实现其他语义。

    此外,MySQL需要引用的列被索引的性能。然而,InnoDB不执行任何要求,引用的列被声明独特NOT NULL。外键引用唯一的钥匙或钥匙包含处理无效的价值观是不明确的操作等UPDATE级联删除。建议你使用外键引用唯一的钥匙都是UNIQUE(或首要)和NOT NULL

    MySQL的分析而忽视了内联REFERENCES规格(如SQL标准定义)在引用定义为列规范的一部分。MySQL的接受推荐信只有当指定为一个单独的部分条款FOREIGN KEY规格

  • reference_option

    的信息RESTRICT级联SET NULL没有行动,和SET DEFAULT选项,看第13.1.18.6,“使用外键约束”

表选项

表选项来优化表的行为。在大多数情况下,你不需要指定任何人。这些选项适用于所有存储引擎除非另有说明。选项不适用于一个给定的存储引擎可以接受和记住作为表定义的一部分。以后如果你用这样的选项,然后ALTER TABLE将该表使用不同的存储引擎。

  • ENGINE

    指定表的存储引擎,使用下表中显示的名称。引擎名称可以加引号或引用。引用名称'DEFAULT'被忽视

    存储引擎描述
    InnoDB交易安全的表行锁定和外键。新表的默认存储引擎。看到15章,InnoDB存储引擎,并在特定的15.1节,“会”简介如果你有经验,但新的MySQLInnoDB
    MyISAM二进制的便携式存储引擎,主要用于只读或读过多的工作量。看到16.2节,“MyISAM存储引擎”
    MEMORY这种存储引擎的数据只存储在内存中。看到第16,“存储引擎”
    CSV表店排在逗号分隔值格式。看到16.4节,“CSV存储引擎”
    ARCHIVE归档存储引擎。看到16.5节,“ARCHIVE存储引擎”
    EXAMPLE例发动机。看到16.9节,“实例存储引擎”
    FEDERATED存储引擎访问远程表。看到16.8节,“联邦存储引擎”
    HEAP这是一个同义词MEMORY
    MERGE集合MyISAM用于一张桌子的桌子。也知道MRG _ MyISAM。看到16.7节,“MERGE存储引擎”

    默认情况下,如果一个存储引擎是指定的,不可用,则语句失败与错误。您可以通过删除重写此行为NO_ENGINE_SUBSTITUTION从服务器的SQL模式(见第5.1.10,”服务器的SQL模式”)使MySQL允许默认存储引擎而不是指定的发动机替代。通常在这种情况下,这是InnoDB,这是为默认值default_storage_engine系统变量。当no_engine_substitution被禁用,如果存储引擎规格不兑现时警告。

  • AUTO_INCREMENT

    最初的AUTO_INCREMENT为表值。在MySQL 8,本工程为MyISAMMEMORYInnoDB,和ARCHIVE表设置第一个汽车增量价值引擎不支持汽车表格,插入,插入笨蛋在创建表与一个值低于期望值的行,然后删除伪行。

    发动机的支持AUTO_INCREMENT表选项CREATE TABLE报表,您也可以使用修改表tbl_nameAUTO_INCREMENT =N重置汽车价值。该值不能低于当前列中的最大值。

  • AVG_ROW_LENGTH

    你的表的平均行长度近似。你需要把这只为可变大小的行大表。

    当你创建一个MyISAM表,MySQL使用的产品max_rowsAVG_ROW_LENGTH选项来决定产生的表有多大。如果你不指定选项,最大尺寸MyISAM数据和索引文件是256tb默认。(如果你的操作系统不支持大,表的大小由文件大小限制,约束文件)如果你想要保留下来的指针大小使指数更小,更快,你真的不需要大的文件,你可以降低默认的指针的大小设置myisam_data_pointer_size系统变量。(See第5.1.7,服务器“系统变量”。)如果你想要所有的表能够成长上面的默认限制,愿意有你的表慢,稍微比必要的更大,你可以通过设置这个变量增加默认指针的大小。将值设置为7到65536tb许可表的大小。

  • [DEFAULT] CHARACTER SET

    指定默认字符集为表CHARSET是同义词字符集。如果字符集名称DEFAULT,数据库的字符集是用。

  • CHECKSUM

    设置为1如果你想MySQL维护所有行现场校验(即校验和MySQL自动更新为表的变化)。这使得表慢一点更新,但也使得它更容易找到损坏的表。这个CHECKSUM TABLE报表的校验。(MyISAM唯一的。)

  • [DEFAULT] COLLATE

    对桌子的偏差上的偏差。

  • COMMENT

    对一个表的评论,最多2048个字符长。

    你可以设置InnoDBmerge_threshold值表使用table_option评论条款.看到第15.6.12,“配置合并阈值的索引页”

  • COMPRESSION

    使用页面级压缩的压缩算法InnoDB表支持的值包括zlibLZ4,和。这个COMPRESSION属性介绍透明页面压缩功能。网页压缩只能支持InnoDB表驻留在文件表表空间,并只可在Linux和Windows平台支持稀疏文件和冲孔。有关更多信息,参见第15.9.2,“InnoDB页面压缩”

  • CONNECTION

    对于一个连接字符串FEDERATED

    笔记

    老版本的MySQL的使用COMMENT联接链路选项

  • DATA DIRECTORY索引目录

    InnoDB,的DATA DIRECTORY='directory&#39;选项允许你创建InnoDB每个表的表空间在MySQL数据目录下的文件。在您指定的目录,MySQL创建一个目录对应的数据库名称,并在一个.ibd去桌子上。的innodb_file_per_table配置选项必须能够使用数据目录选项InnoDB。必须指定完整的路径。看到第15.7.5”创建文件,每个表的表空间在数据目录”更多信息

    当创建MyISAM表格,你可以使用DATA DIRECTORY='directory&#39;的条款,INDEX DIRECTORY='directory&#39;条款,或两者。他们指定的地方放一个MyISAM表的数据文件和索引文件,分别。不像InnoDB表,MySQL不创建对应的数据库名称,当创建一个目录MyISAM表一DATA DIRECTORY索引目录选项文件的目录中指定了。

    你必须有FILE特权使用数据目录INDEX DIRECTORY表选项

    重要

    表级DATA DIRECTORY索引目录options are for partitioned的忽视。(# 32091 BUG)

    这些选项仅在您不使用--skip-symbolic-links选项你的操作系统还必须有一个工作线程安全realpath()呼叫。看到第8.12.2.2,“使用MyISAM表在UNIX”符号链接,更完整的信息

    如果一个MyISAM表创建无数据目录期权的.MYD文件在数据库目录中创建。默认情况下,如果MyISAM发现一个现有的.MYD在这种情况下,它将改写该文件。这同样适用于。我创建无表格文件INDEX DIRECTORY选项为了抑制这种行为,以启动服务器--keep_files_on_create在案例的选择MyISAM不会覆盖现有的文件并返回一个错误而。

    如果一个MyISAM表创建一个数据目录INDEX DIRECTORY选择一个现有的MVD.MYI文件被发现,MyISAM总是返回一个错误。它不会覆盖在指定目录下的文件。

    重要

    你不能使用路径名包含MySQL数据目录DATA DIRECTORY索引目录。这包括分区表和个人表分区。(见虫# 32167。)

  • DELAY_KEY_WRITE

    设置为1如果你想延迟关键更新的表到表关闭。看到的描述delay_key_write系统变量第5.1.7,服务器“系统变量”。(MyISAM唯一的。)

  • ENCRYPTION

    设置ENCRYPTION选项“Y”使一个页面级的数据加密InnoDB创建表文件表表空间。复选框选项值是不敏感的。theENCRYPTION选择了与InnoDB表空间加密功能;看第15.7.11,“InnoDB表空间加密”。这个keyring_file插件必须装用加密选项

  • INSERT_METHOD

    如果你想插入数据MERGE表格,你必须指定insert_method表的行应插入INSERT_METHOD是一个选项很有用合并表。使用价值FIRST最后要插入到第一个或最后一个表,或价值NO为防止刀片。看到16.7节,“MERGE存储引擎”

  • KEY_BLOCK_SIZE

    MyISAM桌子,key_block_size还可以指定字节大小使用索引键块。价值作为一个提示;不同的尺寸可以在必要时使用。一KEY_BLOCK_SIZE一个索引定义中指定的值将重写表级key_block_size价值

    InnoDB桌子,key_block_size选择指定网页大小(KB)的使用压缩的InnoDB表这个key_block_size价值作为一个提示;不同的大小可以用InnoDB如果有必要的话key_block_size只能小于或等于innodb_page_size价值。值为0表示默认压缩页面的大小,这是一半的innodb_page_size值。他dependinginnodb_page_size,可能key_block_size价值观包括0,1,2,4,8,16。看到第15.9.1,“InnoDB表压缩”更多信息

    Oracle建议使innodb_strict_mode当指定key_block_sizeInnoDB表什么时候innodb_strict_mode启用时,指定一个无效的key_block_size返回值的误差。如果innodb_strict_mode是禁用的,无效的key_block_size在预警值的结果,和KEY_BLOCK_SIZE忽略选项

    这个Create_options针对柱SHOW TABLE STATUS目前的报告key_block_size由表使用,也SHOW CREATE TABLE

    InnoDB只支持key_block_size在表级

    KEY_BLOCK_SIZE是不是与32K和64K的支持innodb_page_size价值观InnoDB表压缩不支持这些页面大小。

    InnoDB不支持key_block_size当选择创建临时表

  • MAX_ROWS

    行你计划存储在表的最大数目。这不是一个硬性限制,而是暗示存储引擎的表必须能够存储至少这许多行。

    最大MAX_ROWS价值是4294967295;较大的值被截断,此限。

  • MIN_ROWS

    行你计划存储在表中的最小数量。这个MEMORY存储引擎使用此选项是关于内存的使用提示。

  • PACK_KEYS

    生效只有MyISAM表如果你想有较小的索引设置为1。这通常会使更新慢、读取速度更快。设置选项为禁用所有包装的钥匙。设置为默认告诉存储引擎只带长CHARVARCHARBINARY,或VARBINARY专栏

    如果你不使用PACK_KEYS,默认是包的字符串,而不是数字。如果你使用PACK_KEYS=1数字包装,以及

    当包装的二进制数字键,MySQL使用前缀压缩:

    • 每一个关键需要一个额外的字节来指示下一个关键多少字节的密钥是相同的。

    • 该行的指针存储在高字节一阶后直接的关键,提高压缩。

    这意味着,如果你有连续两行许多相等的键,所有以下相同的键通常只需要两个字节(包括行的指针)。这是比较普通的情况下,下面的键以storage_size_for_key + pointer_size(这里的指针的大小通常是4)。相反,如果你有同样多的数字你从前缀压缩效益显著。如果所有的键都是完全不同的,你用一个字节以上的钥匙,如果钥匙不是关键,可以无效的价值观。(在这种情况下,包装的密钥长度是存储在同一个字节是用来标记如果钥匙NULL。)

  • PASSWORD

    这个选项是无用的

  • ROW_FORMAT

    定义物理格式的行存储。

    当执行一个CREATE TABLE声明严格模式禁用,如果您指定的行格式不是由存储引擎,用于表支持,该表是使用存储引擎的默认行格式创建。该表的实际行的格式是在报道Row_format创建_选项针对柱SHOW TABLE STATUSSHOW CREATE TABLE同时报告表的实际行格式。

    行格式的选择取决于使用的表的存储引擎。

    InnoDB

    MyISAMcan be the tables选项值,固定的DYNAMIC对于静态或可变长度的行格式。MyISAMPack套式COMPRESSED。看到第16.2.3,“MyISAM表的存储格式”

  • STATS_AUTO_RECALC

    指定是否自动重新计算持续的统计对于一个InnoDB表。the value默认导致持续统计表是由设置innodb_stats_auto_recalc配置选项。价值原因是时重新计算统计表中的数据改变了百分之十。的价值0防止此表的自动重新计算;使用此设置问题ANALYZE TABLE表重新计算统计后的表格作出实质性的变化。关于持久性统计功能的更多信息,参见第15.6.11.1”配置,持续优化统计参数

  • STATS_PERSISTENT

    指定是否启用持续的统计对于一个InnoDB表。the value默认导致持续统计表是由设置innodb_stats_persistent配置选项。价值使表持续的统计,而价值0关闭此功能。使持续统计通过后创建表ALTER TABLE声明的问题ANALYZE TABLE表计算统计,加载后有代表性的数据到表中。关于持久性统计功能的更多信息,参见第15.6.11.1”配置,持续优化统计参数

  • STATS_SAMPLE_PAGES

    样本在估计基数和其他统计索引列的索引页面的数量,如计算ANALYZE TABLE。有关更多信息,参见第15.6.11.1”配置,持续优化统计参数

  • TABLESPACE

    这个TABLESPACE选项可以用来在一个现有的一般表空间创建一个表,每个表的表空间文件,或系统表空间。

    创建表tbl_name... TABLESPACE [=]tablespace_name

    对于一般的表空间的信息,参见第15.7.10”一般,InnoDB表空间”

    这个tablespace_name是一个标识符区分大小写。它可能被引用或非上市。正斜杠字符(/)是不允许的。的名字开始_ InnoDB是专为特殊用途

    这个TABLESPACE选项可以用来指定InnoDB表分区和子分区到一般的表空间每个表的表空间,一个单独的文件,或者系统表空间。所有分区都必须属于相同的存储引擎。

    一个表空间指定表级成为新的分区和子分区的默认表空间。默认的表空间可以通过在分区或子分区指定一个表空间的覆盖水平CREATE TABLEALTER TABLE声明。下面的示例显示表空间定义在表级和等级的划分。

    mysql> CREATE TABLE t1 ( a INT NOT NULL, PRIMARY KEY (a))    -> ENGINE=InnoDB TABLESPACE ts1                              -> PARTITION BY RANGE (a) PARTITIONS 3 (    -> PARTITION P1 VALUES LESS THAN (2),    -> PARTITION P2 VALUES LESS THAN (4) TABLESPACE ts2,    -> PARTITION P3 VALUES LESS THAN (6) TABLESPACE ts3);

    有关更多信息TABLESPACE选择和分配,看第15.7.10”一般,InnoDB表空间”

    在系统中创建的表一表,指定innodb_systemAs the stating name .

    创建表tbl_name... TABLESPACE [=] innodb_system

    使用TABLESPACE [=] innodb_system选项,你可以放置一个表在SYSTEM表空间的任何压缩行格式的innodb_file_per_table设置例如,您可以添加一个表ROW_FORMAT=DYNAMIC对系统表空间使用TABLESPACE [=] innodb_system选项

    创建表空间的每个表文件表,指定innodb_file_per_tableAs the stating name .

    创建表tbl_name... TABLESPACE [=] innodb_file_per_table
    笔记

    如果innodb_file_per_table是激活的,你不需要指定TABLESPACE=innodb_file_per_table创建一个InnoDBPaitable Tabesace .InnoDB表每表表空间的默认文件时创建的innodb_file_per_table启用

    这个DATA DIRECTORY条款允许CREATE TABLE ... TABLESPACE=innodb_file_per_table但是并不支持使用结合TABLESPACE选项

    这个TABLESPACE选择支持ALTER TABLEALTER TABLE ... REORGANIZE PARTITION报表,可移动表和分区从一个空间到另一个,分别。有关更多信息,参见第15.7.10”一般,InnoDB表空间”

  • UNION

    用于访问集合相同MyISAM表一。这只能与合并表看到16.7节,“MERGE存储引擎”

    你必须有SELECTUPDATE,和DELETE你的表映射到一个特权合并

    笔记

    以前,所有的表都必须在同一数据库为MERGE表本身。这一限制不再适用。

创建分区表

partition_options可以用来控制分区表的创建CREATE TABLE

并不是所有的选项显示在语法partition_options在本节开始的可用于所有类型的划分。以下为具体到每个类型信息的个体类型请看列表,看看22章,分区,关于工作的更完整的信息,并使用MySQL分区,以及额外的实例创建表及其他有关报表MySQL分区。

分区可以被修改,合并,添加到表,并从表。关于MySQL语句来完成这些任务的基本信息,看第13.1.8,“ALTER TABLE语法”。更详细的说明和例子,看22.3节,“分区管理”

  • PARTITION BY

    如果用一个partition_options条款开始分区。本条款包含函数用于确定分区;函数返回一个整型值的范围从1到num,在那里num是分区的数量。(最大数量的用户定义的分区表可能包含的子分区的数目是1024;本节讨论后,包括在这个极限。)

    笔记

    表达(expr)用于分区条款不能引用任何列不在表被创建;这样的引用是不允许的,导致语句失败与错误。(错误# 29444)

  • HASH(expr)

    哈希表的一个或多个列创建放置和定位行的关键。expr使用一个或多个表中的列的表达式。这可以是任何有效的MySQL的表达(包括MySQL函数)产生一个整数。例如,这些都是有效的CREATE TABLE声明中使用散列分区法

    CREATE TABLE t1 (col1 INT, col2 CHAR(5))
        PARTITION BY HASH(col1);
    
    CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME)
        PARTITION BY HASH ( YEAR(col3) );
    

    你可以不使用VALUES LESS THAN价值观保险条款PARTITION BY HASH

    PARTITION BY HASH《大学remainder辨别expr除以分区的数量(即弹性模量)。例如,更多的信息,参见第22.2.4,“哈希分区”

    这个LINEAR关键词需要一个稍微不同的算法。在这种情况下,该分区的行存储数量计算为一个或多个逻辑的结果AND运营讨论线性散列的例子,看第22.2.4.1,线性散列分区”

  • KEY(column_list)

    这是类似于HASH,除了MySQL提供的哈希函数以保证即使数据分布。这个column_list参数是一个简单的列表的1个或更多的表列(最大值:16)。这个例子显示了一个简单的表的分区键,四分区:

    创建表的TK(col1 int,char(5),col2 col3日期)分区键(COL3)分区4;

    表的分区键,你可以采用线性分区利用LINEAR关键词这具有相同的效果与表分区的搞砸。那就是,分区号发现使用&运营商比模量(见第22.2.4.1,线性散列分区”,和第22.2.5,“重点分配”,详情)。这个例子使用线性划分重点分布数据之间的5个分区:

    CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE)
        PARTITION BY LINEAR KEY(col3)
        PARTITIONS 5;
    

    这个ALGORITHM={1|2}选择支持[子]分区[线性]键ALGORITHM=1导致服务器使用相同的密钥散列函数作为MySQL 5.1;ALGORITHM=2意味着服务器采用密钥散列函数实现默认的新应用KEY分区表在MySQL 5.5及以后。(分区表创建的密钥散列函数采用MySQL 5.5以后不能用MySQL 5.1服务器。使用)没有指定选项具有相同的效果,使用ALGORITHM=2。该选项用于主要使用在升级或降级[LINEAR] KEY分区表的MySQL 5.1及以后的版本之间,或创建表分区钥匙LINEAR KEY在MySQL 5.5或更高版本的服务器可在MySQL服务器5.1。有关更多信息,参见第13.1.8.1,“修改表分区操作”

    mysqldump在MySQL 5.7(后来)写这个选项被版本化的评论,这样:

    CREATE TABLE t1 (a INT)
    /*!50100 PARTITION BY KEY */ /*!50611 ALGORITHM = 1 */ /*!50100 ()
          PARTITIONS 3 */
    

    这会导致MySQL 5.6.10以及更早版本的服务器忽略选项,否则这些版本造成的语法错误。如果你计划负荷在MySQL 5.7的服务器在您使用表分区或subpartitioned转储KEY一个MySQL服务器版本5.6 5.6.11之前,一定要咨询升级到MySQL 5.6变化的影响在此之前。(发现的信息也适用于如果你加载一个倾倒含KEY分区或subpartitioned表由一个MySQL 5.7-actually 5.6.11或晚到MySQL服务器5.5.30或更早的服务器。)

    在MySQL 5.6.11后来,ALGORITHM=1在必要的时候显示输出SHOW CREATE TABLE使用相同的版本注释mysqldumpALGORITHM=2总是忽略显示创建表输出,即使该选项指定创建原始表时。

    你可以不使用VALUES LESS THAN价值观保险条款PARTITION BY KEY

  • RANGE(expr)

    在这种情况下,expr显示值的范围,使用一套值小于运营商。使用范围分区时,必须至少定义一个分区使用VALUES LESS THAN。你不能使用价值观与范围划分

    笔记

    for表partitioned byRANGE值小于必须使用整数常量值或计算结果为一个整数的表达式。在MySQL 5.0,可以克服这个限制的表中定义使用PARTITION BY RANGE COLUMNS,在本节后面介绍

    假设你有一个表,您希望分区列上包括年值,按以下方案。

    分区数:年的范围:
    1990 and earlier
    1991到1994
    1995到1998
    1999到2002
    2003到2005
    2006后来

    表实施这样的分区方案是可以实现的CREATE TABLE表所示:

    创建表T1(year_col int,int some_data)按范围分区(分区year_col)(P0值小于(1991年),分区P1值小于(1995年),分区P2的值小于(1999年),分区P3值小于(2002年),分区P4值小于(2006年),分区P5值小于最大值);

    PARTITION ... VALUES LESS THAN ...报表以连续的方式工作。值小于最大作品说明残存物否则,超过规定的最大值的值。

    VALUES LESS THAN条款顺序,在类似的方式案例一部分switch ... case块(如发现在许多编程语言如C,java,PHP)。那就是,条款必须安排在这样一种方式,在每个指定的上限值小于大于前一个,用一个引用MAXVALUE最后所有的列表

  • RANGE COLUMNS(column_list)

    这种变体RANGE有利于分区修剪使用范围条件对多个列的查询(即,有条件如WHERE a = 1 AND b < 10WHERE a = 1 AND b = 10 AND c < 10)。这使您可以指定多个列中的值的列的列表中专栏条款和每一组列的值PARTITION ... VALUES LESS THAN (value_list)分区定义条款。(在最简单的情况下,这套由单个列。),可供参考的最大列数column_listvalue_list是16

    这个column_list用于专栏条款可能包含列名称;列表中的每一列必须是下列之一的MySQL数据类型:整数类型;字符串类型;和时间或日期列类型。柱的使用BLOB文本SET枚举BIT,或空间数据类型是不允许的;柱使用浮点数类型也不允许。你也不可能在使用功能或算术表达式专栏条款.

    这个VALUES LESS THAN用于分区定义条款必须指定每列显示在一个文本值columns()条款;即,用于每个值的列表VALUES LESS THAN条款必须包含相同数量的值都列在列专栏条款.尝试使用更多或更少的价值VALUES LESS THAN条款比在专栏条款导致语句失败与错误在分区列列表的使用不一致…。你不能使用NULL任何值出现在值小于。它可以使用MAXVALUE不止一次,对于一个给定的列以外的第一,如本例所示:

    创建表的RC(一个int不空,不空的b int)范围列分区(A,B)(分区P0值小于(10,5),分区P1值小于(20,10),分区P2的值小于(50次),分区P3值小于(65次),分区P4值小于(最大值,最大值));

    每个值用于VALUES LESS THAN值列表必须匹配相应的列的类型完全没有转换了。例如,你不能使用字符串“1”一个值相匹配的列,使用整数类型(必须使用数字1相反),也可以使用数字一个值相匹配的列,使用一个字符串类型(在这种情况下,你必须使用一个引用字符串:'1'

    有关更多信息,参见第22.2.1,”范围划分”,和22.4节,“分区修剪”

  • LIST(expr)

    这是有用的当分配分区的基础上,以有限的一组可能的值的表列,如州或国家代码。在这种情况下,所有行属于某个国家或国家可以分配给一个分区,或者一个分区可以保留为一组特定的国家或国家。这是类似的RANGE,但只有价值观可用于指定每个分区的允许值。

    VALUES IN是用一个列表中的值相匹配。例如,您可以创建一个分区方案如下:

    create table Client _公司(id、name varchar(35)城市分区表(partition(ID)在R0值(1,5,9,13,17,21),R1的值的分区(2,6,10,14,18,22),在分区的R2值(3,7,11,15,19,23),分配在R3的值(4,8,12,16,20,24));

    使用列表分区时,必须至少定义一个分区使用VALUES IN。你不能使用值小于PARTITION BY LIST

    笔记

    for表partitioned byLIST,使用值列表价值观必须由整数的值只。在MySQL 8中,你可以克服这个限制使用的分区LIST COLUMNS,这是描述本节后面

  • LIST COLUMNS(column_list)

    这种变体LIST有利于分区修剪使用比较多个列的查询条件(即,有条件如WHERE a = 5 AND b = 5WHERE a = 1 AND b = 10 AND c = 5)。它使您能够指定多个列中的值的列的列表中专栏条款和每一组列的值PARTITION ... VALUES IN (value_list)分区定义条款

    关于使用管理列表中列的数据类型的规则LIST COLUMNS(column_list)和值列表中使用值(value_list和那些使用的列的列表中的相同范围列(column_list和值列表中使用值小于(value_list,分别,除价值观条款,MAXVALUE是不被允许的,你可以使用无效的

    有价值的用于列表之间的重要区别之一VALUES IN由表列分区而当它是用PARTITION BY LIST。当使用由表列分区在每一个元素,VALUES IN条款必须配置列值;每一组值的数量必须为所使用的列数相同COLUMNS条款,这些值的数据类型必须与相应的列(在相同的顺序出现)。在最简单的情况下,该装置由单柱。这可以用在最大列数column_list在构成要素value_list是16

    通过以下定义表CREATE TABLE语句提供了一个例子,一个表的使用表列分配:

    CREATE TABLE lc (
        a INT NULL,
        b INT NULL
    )
    PARTITION BY LIST COLUMNS(a,b) (
        PARTITION p0 VALUES IN( (0,0), (NULL,NULL) ),
        PARTITION p1 VALUES IN( (0,1), (0,2), (0,3), (1,1), (1,2) ),
        PARTITION p2 VALUES IN( (1,0), (2,0), (2,1), (3,0), (3,1) ),
        PARTITION p3 VALUES IN( (1,3), (2,2), (2,3), (3,2), (3,3) )
    );
    
  • PARTITIONS num

    分区的数量可以被指定一个PARTITIONS num条款,在num是分区的数量。如果这一条款任何PARTITION使用条款,num必须等于任何分区,用总人数分区条款.

    笔记

    你是否使用PARTITIONS在创建一个表分区的条款范围LIST,你还必须包括至少一个分区值表中的定义条款(见下文)。

  • SUBPARTITION BY

    一个分区可以被分为若干个子。这可以通过使用可选的显示SUBPARTITION BY条款.分区可以通过搞砸KEY。这些可能是线性的。这些工作在相同的方式如前所述的等价划分类型。(这是不可能的集群化LIST范围。)

    子分区的数量可以表明使用SUBPARTITIONS关键词后跟一个整数

  • 用严格的检查价值PARTITIONS子分区条款的应用和该值必须遵守以下规则:

    • the value必须是积极的,非零的整数。

    • 允许没有前导零

    • 该值必须是整数,而不能表达。例如,PARTITIONS 0.2E+01是不被允许的,即使0.2e 01评价2。。。。。。。(错误# 15890)

  • partition_definition

    每个分区可以单独定义的使用partition_definition条款.个别部分弥补这一条款如下:

    • PARTITION partition_name

      指定的分区逻辑名称

    • VALUES

      范围分区,每个分区必须包括VALUES LESS THAN条款;列表分区,您必须指定一个价值观每个分区子句。这是用来确定哪些行被存储在该分区。看到分区类型的讨论22章,分区for examples,表。

    • [STORAGE] ENGINE

      MySQL的接受[STORAGE] ENGINE工作选择分区SUBPARTITION。目前,该选项可以用来设置所有的分区或所有子分区的存储引擎的唯一途径,并试图在同一个表分区和子分区设置不同的存储引擎会引起的误差错误1469(hy000):在这个版本的MySQL不允许操作者在分区的混合

    • COMMENT

      一个可选的COMMENT条款可以用来指定一个字符串描述分区。例子:

      COMMENT = 'Data for the years previous to 1999'

      一个分区注释的最大长度为1024个字符。

    • DATA DIRECTORY索引目录

      DATA DIRECTORY索引目录可用于显示目录,分别为该分区的数据和索引被存储。两data_dirindex_dir必须绝对系统路径名

      你必须有FILE特权使用数据目录INDEX DIRECTORY分区的选择

      例子:

      CREATE TABLE th (id INT, name VARCHAR(30), adate DATE)
      PARTITION BY LIST(YEAR(adate))
      (
        PARTITION p1999 VALUES IN (1995, 1999, 2003)
          DATA DIRECTORY = '/var/appdata/95/data'
          INDEX DIRECTORY = '/var/appdata/95/idx',
        PARTITION p2000 VALUES IN (1996, 2000, 2004)
          DATA DIRECTORY = '/var/appdata/96/data'
          INDEX DIRECTORY = '/var/appdata/96/idx',
        PARTITION p2001 VALUES IN (1997, 2001, 2005)
          DATA DIRECTORY = '/var/appdata/97/data'
          INDEX DIRECTORY = '/var/appdata/97/idx',
        PARTITION p2002 VALUES IN (1998, 2002, 2006)
          DATA DIRECTORY = '/var/appdata/98/data'
          INDEX DIRECTORY = '/var/appdata/98/idx'
      );
      

      DATA DIRECTORY索引目录表现在相同的方式在CREATE TABLE声明的table_option条款作为MyISAM

      一个数据目录和索引目录可以指定每个分区。如果没有指定,数据和索引的表中的数据库目录的默认存储。

      这个DATA DIRECTORY索引目录选项用于创建分区表如果忽视NO_DIR_IN_CREATE在影响

    • MAX_ROWSmin_rows

      可用于指定,分别被存储在分区的最大值和最小值的行数。的值max_number_of_rowsmin_number_of_rows必须是正整数。与表级选项具有相同的名称,这些只充当建议到服务器并不是硬限制。

    • TABLESPACE

      可用于分配的InnoDB表分区和子分区到一般的表空间每个表的表空间,一个单独的文件,或者系统表空间。所有分区都必须属于相同的存储引擎。有关更多信息,参见第15.7.10”一般,InnoDB表空间”

  • subpartition_definition

    分区的定义可以包含一个或多个subpartition_definition条款.这些包括在最低限度的子分区name,在那里name为子分区标识符。除了更换了分区关键词与SUBPARTITION,为子分区的语法定义是相同的,一个分区的定义。

    分区必须做的HASH钥匙,可以做的只有RANGE列表分区。看到第22.2.6,“subpartitioning”

通过生成的列分区

通过生成的列划分是允许的。例如:

CREATE TABLE t1 (
  s1 INT,
  s2 INT AS (EXP(s1)) STORED
)
PARTITION BY LIST (s2) (
  PARTITION p1 VALUES IN (1)
);

分区看到生成的列为常规栏目,使上也不允许分割功能的局限性的解决方法(见第22.6.3,分区限制有关的功能”)。前面的示例演示了这个技术:EXP()不能直接用在分区条款,但生成的列定义使用EXP()是允许的

第13.1.18.1 create table statement re卸

CREATE TABLE声明,包括所有的规格表选项存储在MySQL创建表时。该信息被保留,如果你改变存储引擎,使用排序规则或其他设置ALTER TABLE声明,原表选项指定的保留。这允许你改变之间InnoDBMyISAM表类型虽然由两引擎支持行的格式是不同的。

由于原始语句的文本被保留,但由于某些价值和期权可能会默默地重新配置的方式,主动表定义(可通过DESCRIBE或与SHOW TABLE STATUS)和表创建的字符串(可以通过SHOW CREATE TABLE不同的价值观会报告)。

InnoDB桌子,SHOW CREATE TABLE创建_选项列报SHOW TABLE STATUS显示实际row_formatKEY_BLOCK_SIZE通过使用属性表。在以前的MySQL版本,报道最初指定这些属性的值。

13.1.18.2文件创建表的创建

对于一个InnoDB在每个表空间或表空间文件创建的表,表中的数据和相关的索引存储在一个IBD文件在数据库目录。当一个InnoDB表是在SYSTEM表空间的创建、表的数据和索引存储在ibdata *文件我代表了烟草公司。theinnodb_file_per_table选项控制是否are created in表给每台tablespaces or the system表空间,默认的。the表空间选项可以用来放置一个表中每个表的表空间,文件一般表空间,或SYSTEM表空间,不管的innodb_file_per_table设置

MyISAM表,存储引擎创建的数据和索引文件。因此,每个MyISAMtbl_name,有两个磁盘文件

文件目的
tbl_name.MYD数据文件
tbl_name.MYI索引文件

第十六章,选择存储引擎描述文件,每个存储引擎创建的代表表。如果一个表名包含特殊字符,为表文件名称包含编码版本的特征描述第9.2.3,“映射标识符文件名”

13.1.18.3创建临时表的语法

你可以使用TEMPORARY当创建关键字在桌子上。在临时表只在当前会话中可见,并自动删除会话时关闭。这意味着两个不同的会话可以使用同一个临时表的名称不与对方或与现有的非冲突—TEMPORARY同名的表。(现有的表隐到临时表被删除。)

InnoDB不支持压缩的临时表。什么时候innodb_strict_mode启用(默认),CREATE TEMPORARY TABLE返回一个错误如果ROW_FORMAT=COMPRESSEDKEY_BLOCK_SIZE指定。如果innodb_strict_mode是残疾人,发出警告和临时表是使用非压缩行格式创建。InnoDB临时表在共享临时表空间中创建,ibtmp1。这个innodb_file_per-table选项不影响创作InnoDB临时表

CREATE TABLE使一个隐式提交,除非用临时关键词看到13.3.3部分,”声明,因为一个隐含的承诺”

TEMPORARY表格与数据库的一个非常松散的关系(模式)。删除数据库不会自动放弃任何临时在数据库中创建表。另外,你可以创建一个TEMPORARY在一个不存在的数据库表,如果你限定表名和数据库名在创建表声明。在这种情况下,表的所有后续的引用必须符合数据库名称。

创建一个临时表,你必须CREATE TEMPORARY TABLES特权。在会话创建临时表,服务器上执行任何进一步的权限检查。创建会话可以在桌子上进行任何操作,如DROP TABLEINSERTUPDATE,或SELECT

这种行为的一个含义是,一个会话可以操纵其临时表即使当前用户没有权限创建它们。假设当前用户没有CREATE TEMPORARY TABLES特权,但可以执行一个定义上下文存储过程执行的权限,用户谁有CREATE TEMPORARY TABLES创建一个临时表。程序执行时,该会话使用的自定义权限。手术后的回报,有效的权限恢复到当前用户,仍然可以看到临时表并对其进行任何操作。

你不能使用CREATE TEMPORY TABLE ... LIKE创建基于一个表驻留在定义一个空表MySQL表空间,InnoDB系统表空间(InnoDB _系统),或一般的表空间。对于这样一个表的表空间的定义包括TABLESPACE属性定义的表所在的表空间,而前述的表空间不支持临时表。创建一个基于这样一个表定义临时表,而不是使用此语法:

创建临时表new_tblSELECT * FROMorig_tbl限制为0;

13.1.18.4创建表…像语法

使用CREATE TABLE ... LIKE创建基于一个表的定义一个空表,包括任何列属性和原表中定义的指标:

创建表new_tbl喜欢orig_tbl

复制使用的表的存储格式相同版本的原始表的创建。这个SELECT特权是原始表的要求

LIKE只对基表的视图,不

重要

你不能执行CREATE TABLE创建表…喜欢LOCK TABLES声明是有效的

CREATE TABLE ... LIKE做相同的检查CREATE TABLE。这意味着,如果当前的SQL模式不同于效果模式时的原始表的创建、表的定义可能会考虑和声明的新模式无效会失败。

CREATE TABLE ... LIKE目标表生成,保留从原来的表的列信息。

CREATE TABLE ... LIKE,目标表保留默认值从原始表中的表达。

CREATE TABLE ... LIKE不保留任何数据目录INDEX DIRECTORY表选项是原表中指定的,或任何外键定义。

如果原来的表是TEMPORARY表,创建表…喜欢不保留TEMPORARY。创建一个临时目标表,使用CREATE TEMPORARY TABLE ... LIKE

创建的表mysql表空间的InnoDB系统表空间(innodb_system的(或通用),包括表空间在表中定义的属性,它定义在表所在的表空间。由于暂时回归,CREATE TABLE ... LIKE保存表空间属性定义表空间中创建表姑的innodb_file_per_table设置为了避免表空间属性创建基于这样一个表定义一个空表时,使用此语法代替:

CREATE TABLE new_tbl SELECT * FROM orig_tbl LIMIT 0;        

13.1.18.5创建表…选择语法

你可以创建一个表,从另一个加入SELECT在最后陈述CREATE TABLE声明:

创建表new_tbl[为]选择*orig_tbl

MySQL创建新列中的所有元素SELECT。。。。。。。例如:

MySQL的&#62;CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,-&#62;PRIMARY KEY (a), KEY(b))-&#62;ENGINE=MyISAM SELECT b,c FROM test2;

这将创建一个MyISAM三列的表,b,和C。这个ENGINE选项部分的CREATE TABLE声明中,不应使用以下SELECT;这将导致一个语法错误。同其他是真的CREATE TABLE选项如字符集

注意,从列SELECT声明在桌子的右边,不重叠到它。看看下面的例子:

MySQL的&#62;SELECT * FROM foo;我| | n - 1 | |——MySQL &#62;CREATE TABLE bar (m INT) SELECT n FROM foo;查询行,1行的影响(0.02秒)记录:1份:0警告:0mysql &#62;SELECT * FROM bar;------ --- | M | N | ------ --- |空| 1 | ------ --- 1行集(0秒)

表中的每一行foo,一行插入酒吧与价值观foo并为新列的默认值

在一个表中产生CREATE TABLE ... SELECT只有在指定的列,CREATE TABLE第一部分是。列在两个部分,或只在叫SELECT部分来之后。数据类型SELECT列可以被在指定的列CREATE TABLE部分

如果出现任何错误复制数据到表中时,它会自动下降,没有创造。

你可以先SELECT忽略REPLACE指示如何处理行重复的独特的核心价值观。与忽略复制现有的排,排在一个独特的核心价值被丢弃。与REPLACE新的取代,行具有相同的唯一的键值的行。如果没有忽略也没有REPLACE指定重复的独特的核心价值观,在一个错误的结果。有关更多信息,参见在忽略关键词和严格的SQL模式比较

由于在底层的排序SELECT语句总是不能确定,创建表…忽略选择CREATE TABLE ... REPLACE SELECT声明标记为不安全的基于语句的复制。这些陈述产生在错误日志中的警告时,使用声明模式和写入使用基于行的格式时,使用二进制日志混合的模式。参见第17.2.1.1,”优势和基础,基于行的复制”语句的缺点

CREATE TABLE ... SELECT不会自动为你创建任何索引。这样做是有意使语句尽可能灵活。如果你想在创建表的索引,你应该指定这些之前SELECT声明:

MySQL的&#62;CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;

CREATE TABLE ... SELECT,目标表不保留关于是否在选择表中的列生成的列信息。这个SELECT该声明不能赋值给生成的目标表中的列。

CREATE TABLE ... SELECT目标表不表达,保留默认值从原始表。

一些转换数据类型可能发生。例如,在AUTO_INCREMENT属性不保留,和VARCHAR列可以成为CHAR专栏培训的属性无效的(或NOT NULL),这些列有他们,字符集COLLATION评论,和DEFAULT条款.

当创建一个表CREATE TABLE ... SELECT,使查询别名任何函数调用或表达肯定。如果你不这样做,那创造声明可能会失败或不良的列名的结果。

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;

你也可以显式地指定在创建的表的列的数据类型:

CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;

CREATE TABLE ... SELECT,如果如果不存在给出了目标表存在,没有插入到目标表,并声明没有登录。

确保二进制日志可用于重新创建原始表,MySQL不允许并发插入时CREATE TABLE ... SELECT

你不能使用FOR UPDATE的一部分SELECT如在一份声明中CREATE TABLE new_table SELECT ... FROM old_table ...。如果你试图这样做,该语句将失败。

13.1.18.6使用外键约束

MySQL支持外键,这让你交叉引用相关数据在表中,并外资的关键约束,这有助于保持这种分散的数据一致。在一个外键约束定义的基本语法CREATE TABLEALTER TABLE语句看起来像这样:

【约束[symbol] [重点]外商index_name](key_part引用,…)tbl_namekey_part[删除,…)reference_option[更新]reference_option]reference_option:限制|级联|空集|没有行动|默认设置

index_name代表一个外键ID.index_name值,如果已经有一个明确定义的指数在子表的外键,可以忽略。否则,MySQL隐式地创建外键索引,根据以下规则命名:

  • 如果定义的CONSTRAINTsymbol冰的使用价值。否则,外键index_name使用价值

  • 如果没有一个CONSTRAINTsymbol外键index_name定义外键索引名称使用的引用外键列的名称生成。

这个FOREIGN KEYindex_name值在数据库中必须是唯一的。

外键定义须符合以下条件:

  • 外键关系涉及父表认为中央的数据值,并子表具有相同的价值指向它的父。这个FOREIGN KEY在子表中指定的条款。父表和子表必须使用相同的存储引擎。他们不能临时

    在MySQL 8中,一个外键约束的创作要求REFERENCES特权的parent table。

  • 在外键对应的列和引用的关键必须有相同的数据类型。的大小和符号整数类型必须相同。字符串类型的长度不一定是相同的。多进制(字符)字符串列的字符集和整理必须相同。

  • 什么时候foreign_key_checks启用,这是默认设置,允许在表中包括一个用于外键约束字符串列的不是字符集转换。解决方法是描述第13.1.8,“ALTER TABLE语法”

  • MySQL需要对外键索引和引用键,外键检查可以快速的和不需要的表扫描。在引用表中,必须有一个索引,外键列列为第一在同一顺序的列。这样的索引创建引用表自动如果它不存在。该指标可能被丢弃后,如果你创建一个索引,可以用来执行外键约束。index_name,如果是用来描述以前。

  • InnoDB允许一个外键引用的任何列或一组列。然而,在所引用的表,必须有一个索引引用的列列为第一在同一顺序的列

  • 不支持外键列的前缀索引。这样的后果之一是,BLOBTEXT列不能包含外键的列的索引,必须包括一个前缀长度。

  • 如果CONSTRAINT symbol给出的条款,symbol值,如果使用,在数据库中必须是唯一的。一个重复的symbol将导致错误,类似于:错误1022(2300):不能写;重复键在表“# SQL 464_1”。如果没有给出的条款,或symbol不包括以下约束关键词,该约束的名称自动创建。

  • InnoDB目前不支持外键与用户定义的分区表。这包括父表和子表。

其他方面FOREIGN KEY约束使用本节中的以下主题下的描述:

引用操作

本节介绍了如何帮助保证外键参照完整性

存储引擎支持外键,MySQL拒绝任何INSERTUPDATE操作,试图创建一个外键值在子表中没有匹配的候选关键字的值在父表。

当一个UPDATEDELETE手术对父表,子表中匹配的行的键的值,结果取决于引用操作指定使用ON UPDATE在删除几个小节的FOREIGN KEY条款.MySQL支持五个选项将要采取的行动,在这里列出:

  • CASCADE:从父表中更新或删除的行,并自动删除或更新子表中匹配的行。两级联删除ON UPDATE CASCADE支持。两表之间,没有定义几个级联更新的条款,在父表和子表中同一列。

    如果一个FOREIGN KEY条款是在外键关系表的定义,使表的家长和孩子,一个级联更新ON DELETE CASCADE一个定义小节外键条款必须被定义为其他为了级联操作成功。如果一个ON UPDATE CASCADE级联删除小节是一个FOREIGN KEY条款,级联操作失败与错误。

    笔记

    级联外键动作不激活触发器。

  • SET NULL:删除或从父表中更新行,并设置外键列在子表无效的。两ON DELETE SET NULL在更新设置空条款的支持

    如果你指定一个SET NULL行动,确保你没有宣布列在孩子表NOT NULL

  • RESTRICT:拒绝删除或更新操作的父表。指定限制(或NO ACTION)是相同的省略在删除ON UPDATE条款.

  • NO ACTION从标准的SQL关键字。在MySQL数据库中,相当于限制。MySQL服务器拒绝删除或更新操作的父表中是否有相关的引用表中的外键值。一些数据库系统已经把支票和NO ACTION是一个延迟检查。在MySQL中,外键约束是立即进行检查,所以没有行动是一样的RESTRICT

  • SET DEFAULT:这个动作是由MySQL解析器的认可,但InnoDB不含表定义删除默认设置ON UPDATE SET DEFAULT条款.

对于一个ON DELETE在更新这是没有指定,默认的行动总是RESTRICT

MySQL支持一列和另一个表中的外键引用之间。(一列不能有一个外键引用本身。)在这种情况下,子表的记录真的是同一个表中的相关记录。

在一个存储列不能使用生成的外键约束ON UPDATE CASCADE删除设置空ON UPDATE SET NULL删除默认设置,或ON UPDATE SET DEFAULT

外键约束无法引用虚拟生成的列。

InnoDB外键关系和生成的列的限制,看第15.8.1.6,“InnoDB和外键约束”

国外关键条款实例

这里是一个简单的例子,涉及parent儿童通过一个单一的列表的外键:

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;

一个更复杂的例子,product_order表的外键的其他两个表。一个外键引用的两列索引产品表。the other references in the单柱指数customer

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。关于外键这个语句的语法如下所示:

修改表tbl_name[ [添加约束symbol] [重点]外商index_name](key_part引用,…)tbl_namekey_part[删除,…)reference_option[更新]reference_option]

外键可以自足的(指同一个表)。当你添加一个外键约束的表使用ALTER TABLE记得第一次来创建所需的指标。

研讨外商的钥匙

你也可以使用ALTER TABLE下降的外键,利用这里显示的语法:

修改表tbl_name删除外键fk_symbol

如果FOREIGN KEY条款包括约束当你创建外键的名字,你可以参考这个名字掉外键。否则,该fk_symbol价值是内部产生当外键创建。找出符号价值当你想放弃一个外键,使用SHOW CREATE TABLE语句,如下所示:

MySQL的&#62;SHOW CREATE TABLE ibtest11c\G*************************** 1. row ***************************       Table: ibtest11cCreate Table: CREATE TABLE `ibtest11c` (  `A` int(11) NOT NULL auto_increment,  `D` int(11) NOT NULL default '0',  `B` varchar(200) NOT NULL default '',  `C` varchar(175) default NULL,  PRIMARY KEY  (`A`,`D`,`B`),  KEY `B` (`B`,`C`),  KEY `C` (`C`),  CONSTRAINT `0_38775` FOREIGN KEY (`A`, `D`)REFERENCES `ibtest11a` (`A`, `D`)ON DELETE CASCADE ON UPDATE CASCADE,  CONSTRAINT `0_38776` FOREIGN KEY (`B`, `C`)REFERENCES `ibtest11a` (`B`, `C`)ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=INNODB CHARSET=utf8mb41 row in set (0.01 sec)mysql>ALTER TABLE ibtest11c DROP FOREIGN KEY `0_38775`;

添加在同一滴一个外键ALTER TABLE声明支持ALTER TABLE ... ALGORITHM=INPLACE但不支持ALTER TABLE ... ALGORITHM=COPY

在MySQL 8中,服务器禁止更改外键列有可能造成参照完整性的损失。一种解决方法是使用ALTER TABLE ... DROP FOREIGN KEY更改列定义之前ALTER TABLE ... ADD FOREIGN KEY后来

外键和其他MySQL语句

在表和列的标识符FOREIGN KEY ... REFERENCES ...子句可以引用在引号(`)。另外,双引号("如果可以用)ANSI_QUOTESSQL模式启用。的设置lower_case_table_names系统变量也考虑

您可以查看子表的外键定义的输出部分SHOW CREATE TABLE声明:

显示创建表tbl_name

你也可以获得关于外键信息查询INFORMATION_SCHEMA.KEY_COLUMN_USAGE

你可以找到有关外键使用InnoDB表中的INNODB_FOREIGNINNODB_FOREIGN_COLS表,也在information_schema数据库

mysqldump生成转储文件中表的正确定义,包括子表的外键。

为了使它更容易重新有外键关系表转储文件,mysqldump自动包括在转储输出语句集foreign_key_checks0。这就避免了问题的表必须重新在一个特定的顺序在转储是重装上阵。也可以手动设置此变量:

MySQL的&#62;SET foreign_key_checks = 0;MySQL的&#62;SOURCE dump_file_name;MySQL的&#62;SET foreign_key_checks = 1;

这使您可以导入表的任何命令如果转储文件包含表的外键,不正确的命令。这也加速了进口操作。设置foreign_key_checks0也可以忽略外键约束中是有用的LOAD DATAALTER TABLE操作。然而,即使foreign_key_checks = 0,MySQL不允许外键约束在一列引用不匹配的列类型的创作。另外,如果一个表的外键约束,ALTER TABLE不能用于修改表使用另一个存储引擎。改变存储引擎,你必须放弃任何外键约束的第一。

你不能的问题DROP TABLE对于一个表,被外键约束,除非你做SET foreign_key_checks = 0。当你删除一个表,这是用来创建表的语句定义的任何约束也下降。

如果你创建一个表,掉了,它必须有一个符合外键约束引用它的定义。它必须有正确的列的名称和类型,它必须对所引用的关键指标,如前所述。如果这些都不满意,MySQL返回错误1005,指的是在150的错误消息的错误,这意味着一个外键约束不正确形成。同样,如果一个ALTER TABLE因出现错误150,这意味着一个外键的定义是错误的形成改变的表。

InnoDB表,你可以得到最新的详细解释InnoDB在MySQL服务器对外键错误,检查输出SHOW ENGINE INNODB STATUS

MySQL扩展元数据锁,是必要的,表的外键约束关系。扩展元数据锁防止冲突的DDL和DML同时对相关表执行操作。这种特征也使得更新外键的元数据时,父表的修改。在早期的MySQL版本,外键的元数据,这是由孩子表拥有,无法更新安全。

如果一个表被明确LOCK TABLES,任何通过外键约束相关表的打开和锁定的含蓄。国外重点抽查,共享只读锁(LOCK TABLES READ)采取相关表。级联更新,无共享的写锁(LOCK TABLES WRITE)是在相关表中所涉及的操作。

外键与ANSI/ISO SQL标准

熟悉ANSI/ISO SQL标准的用户,请注意,任何存储引擎,包括InnoDBrecognizes,或enforces酒店比赛用于引用完整性约束定义条款。使用一个显式的MATCH条款没有规定的效果,也使在删除ON UPDATE条款不容忽视。由于这些原因,指定比赛should be回避。

这个MATCH子句在SQL标准的控制无效的在复合值(多栏)外键处理比较时,主键。MySQL的基本实现定义的语义MATCH SIMPLE,它允许外键是全部或部分无效的。在这种情况下,在(子表)行包含这样一个外键允许插入,和不匹配的引用的任何行(母)表。可以使用触发器实现其他语义。

此外,MySQL需要引用的列被索引性能的原因。然而,系统没有强制要求,引用的列是UNIQUE或被宣布不为空。外键引用唯一的钥匙或钥匙包含处理NULL价值观是不明确的操作等UPDATE级联删除。建议你使用外键,仅供参考UNIQUE(包括首要)和NOT NULL钥匙

此外,MySQL将忽略内联REFERENCES规格(如SQL标准定义)在引用定义为列规范的一部分。MySQL的接受推荐信只有当指定为一个单独的部分条款FOREIGN KEY规格对于那些不支持外键存储引擎(如MyISAM),MySQL服务器解析并忽略外键规格。

外键的元数据

这个INFORMATION_SCHEMA.KEY_COLUMN_USAGE表标识的键列的约束。元数据的具体InnoDB外键是发现在INNODB_SYS_FOREIGNINNODB_SYS_FOREIGN_COLS

外键错误

在外键错误事件涉及InnoDB表(通常误差150 MySQL服务器),有关最新信息InnoDB外键的误差可以通过检查SHOW ENGINE INNODB STATUS输出

警告

如果用户对所有父表表级权限,ER_NO_REFERENCED_ROW_2ER_ROW_IS_REFERENCED_2错误消息外键操作暴露对父表的信息。如果用户没有为所有父表有表级权限,更通用的错误信息显示(ER_NO_REFERENCED_ROWER_ROW_IS_REFERENCED

例外的是,用于存储程序规定执行DEFINER特权用户对权限进行评估是在程序的用户定义者条款,不调用用户。如果用户已表级别的父表的权限,仍然显示父表的信息。在这种情况下,它是存储程序的创造者的责任包括适当的条件处理程序的隐藏信息。

13.1.18.7沉默列规范的变化

在一些情况下,MySQL默默改变柱规格从那些在CREATE TABLEALTER TABLE声明。这可能是一种数据类型的变化,与数据类型相关的属性,或一个索引规范。

所有的改变都是受65535字节内部的行大小限制,这可能会导致一些尝试在数据类型的更改失败。看到第c.10.4,“限制表的列数和行的大小”

  • 这是一列PRIMARY KEY是由不为空即使不说的方式

  • 自动删除空格ENUMSET成员的值在创建表时

  • MySQL的SQL数据库的地图供应商的使用MySQL类型某些数据类型。看到第11,“使用数据类型从其他数据库引擎”

  • 如果你有一个USING子句指定一个索引类型,不允许对一个给定的存储引擎,但还有另一个指数型,发动机可以使用不影响查询结果,该引擎使用可用的类型。

  • 如果严格的SQL模式未启用,一VARCHAR柱长度规格大于65535转换为TEXT,和一个VARBINARY柱长度规格大于65535转换为BLOB。否则,错误发生在either of these cases。

  • 指定CHARACTER SET binary一个字符数据类型属性导致列被创建为相应的二进制数据类型:CHAR成为BINARYVARCHAR成为VARBINARY,和TEXT成为BLOB。对于ENUMSET数据类型,这不会发生;他们创建申报。假设你指定一个表使用这个定义:

    创建表(C1 varchar(10)字符集的文本字符集的二进制二进制,C2、C3型(A,B,C)字符集的二进制);

    由此产生的表定义:

    CREATE TABLE t
    (
      c1 VARBINARY(10),
      c2 BLOB,
      c3 ENUM('a','b','c') CHARACTER SET binary
    );
    

看MySQL使用的一种数据类型不是一个你指定的问题DESCRIBESHOW CREATE TABLE在创建或更改表的声明。

其他数据类型的变化可以如果你压缩一个表使用发生MyISAMPack。看到第16.2.3.3,压缩特性表”

13.1.18.8创建表和生成的列

CREATE TABLE支持生成的列的规范。一个生成的列的值是从一个表达式计算包括在列定义。

下面的例子显示了一个表店的直角三角形的边的长度在sideasideB列,并计算斜边的长度sidec(对其他两边的平方和的平方根):

创建表的三角形(思达双,sideB双,sideC双(sqrt(思达*思达sideB * sideB)));插入三角形(思达,sideB)值(1,1),(3,4),(8);

从表中选择产生这样的结果:

mysql> SELECT * FROM triangle;
+-------+-------+--------------------+
| sidea | sideb | sidec              |
+-------+-------+--------------------+
|     1 |     1 | 1.4142135623730951 |
|     3 |     4 |                  5 |
|     6 |     8 |                 10 |
+-------+-------+--------------------+

任何应用程序中使用triangle表访问斜边值没有指定,计算它们的表达。

生成的列定义语法:

col_name data_type [GENERATED ALWAYS] AS (expression)
  [VIRTUAL | STORED] [NOT NULL | NULL]
  [UNIQUE [KEY]] [[PRIMARY] KEY]
  [COMMENT 'string']

AS (expression)指示该列的产生和定义用于计算列的值的表达式。作为可能是之前GENERATED ALWAYS为了使生成的列更明确的性质。的结构,允许或禁止的表达进行了讨论。

这个VIRTUAL存储关键词说明列的值存储,具有柱使用的影响:

  • VIRTUAL:列值不存储,但进行阅读后立即行时,任何之前触发器。一个虚拟的列不需要存储。

    InnoDB支持二级指标对虚拟列。看到第13.1.18.9,“二级指标和生成的列”

  • STORED:列值进行存储行时,插入或更新。存储列需要的存储空间和可以被索引。

默认值是VIRTUAL如果任何一个指定的关键字。

它允许混合VIRTUAL存储在一个表中的列

其他属性可以给予指示列建立索引或可NULL,或提供意见

生成的列的表达式必须遵守以下规则。发生错误,如果表达式包含无效的构建。

  • 文字、确定性的内置功能,并允许运营商。如果一个函数是确定性的,在表中给出的相同的数据,多次调用产生相同的结果,独立于所连接的用户。功能定义实例失败:CONNECTION_ID()CURRENT_USER()NOW()

  • 子查询、参数、变量、存储功能,和用户定义的函数都是不允许的。

  • 一个生成的列定义可以参考其他生成的列,但只有那些在表定义早些时候发生的。一个生成的列定义可以参考任何基地(无再生中继)列在表中是否定义之前或之后发生的。

  • 这个AUTO_INCREMENT属性不能用于生成的列定义。

  • 一个AUTO_INCREMENT列不能作为生成的列定义一个基柱。

  • 如果表达式计算导致截断或提供不正确的输入到一个功能的CREATE TABLE语句终止一个错误和DDL操作被拒绝。

如果表达式的值的数据类型与声明的列类型,隐式强制声明的类型按照通常的MySQL的类型转换规则。看到第二节,“表达评价类型转换”

笔记

如果表达式的任何组件依赖于SQL模式,不同的结果可能出现的不同用途,除非在表的SQL模式是相同的使用。

CREATE TABLE ... LIKE目标表生成,保留从原来的表的列信息。

CREATE TABLE ... SELECT,目标表不保留关于是否在选择表中的列生成的列信息。这个SELECT该声明不能赋值给生成的目标表中的列。

通过生成的列划分是允许的。看到创建分区表

在一个存储列不能使用生成的外键约束ON UPDATE CASCADE删除设置空ON UPDATE SET NULL删除默认设置,或ON UPDATE SET DEFAULT

外键约束无法引用虚拟生成的列。

InnoDB外键关系和生成的列的限制,看第15.8.1.6,“InnoDB和外键约束”

触发器不能使用NEW.col_name或使用旧版col_name是指生成的列

INSERTREPLACE,和UPDATE如果生成的列,插入,替换,或更新的明确,唯一被允许的值默认

一个生成的列在视图是可更新的因为它可以给它。但是,如果这样的更新列明确,唯一被允许的值DEFAULT

生成的列有几个使用案例,如这些:

  • 虚拟生成的列可以作为一种方法来简化和统一查询。一个复杂的条件可以被定义为一个生成的列,称为从多个查询表来确保他们都使用完全相同的条件。

  • 存储生成的列可以作为一种物化缓存复杂条件,计算上飞高。

  • 生成的列可以模拟功能指标:使用生成的列定义一个函数表达式和指标。这能与不能直接索引类型列的工作是有用的,如JSON柱;看索引生成的列提供一个JSON列索引如果您发现有错误,请尽管发表评论!

    存储生成的列,此方法的缺点是,值存储的两倍;一旦作为生成的列的值,一旦在指数。

  • 如果生成的列建立索引时,优化器认为查询表达式匹配的列定义和使用索引列为合适的查询执行过程中,即使一个查询不是指柱直接通过名称。详情见第8.3.11,“优化器使用生成的列索引”

例子:

假设一个表t1包含第一_ namelast_name列,应用程序经常使用表达式构建姓名这样:

选择concat(first_name,&#39; &#39;,last_name)作为full_name从T1;

为了避免书写表达的是创建一个视图的一种方式v1打开(放)T1这简化了应用程序,使他们能够选择full_name直接使用表达式:

创建视图v1 asselect *,concat(first_name,&#39; &#39;,last_name)作为full_name从T1;选择full_name从V1;

一个生成的列也允许应用程序选择full_name直接而不需要定义一个视图:

创建表T1(first_name varchar(10),last_name varchar(10),full_name varchar(255)为(concat(first_name,&#39; &#39;,last_name)));选择full_name从T1;

13.1.18.9次要指标和生成的列

InnoDB支持二级指标虚拟生成的列。不支持其他类型指数。次要指标上定义一个虚拟列有时被称为虚拟索引

次要指标可以在一个或多个虚拟列或结合虚拟列和专栏或存储生成的列创建。二级指标包括虚拟列可以定义为UNIQUE

当一个次要指标是虚拟生成的列创建,生成的列的值出现在指数的记录。如果指数是覆盖指标(一个包括所有列的查询检索),生成的列的值进行物化价值的索引结构来代替计算在飞

还有写成本考虑使用由于实现虚拟列值时进行二级指标记录在计算虚拟柱时,次要指标INSERTUPDATE运营即使再写成本,虚列二级指标可能比生成存储列,这是物化的聚集索引中,导致更大的表需要更多的磁盘空间和内存。如果一个次级指标不在一个虚拟的列定义,有额外的费用为:作为虚拟列的值必须计算每一次列行检查。

一个索引的虚拟列值MVCC登录以避免不必要的列值时产生回滚或吹扫操作期间的重新计算。记录的值的数据长度是有限的767字节的索引键的限制COMPACT冗余行格式,和3072字节DYNAMIC压缩的行格式

添加或删除一个次级指标对虚拟列就地操作。

索引生成的列提供一个JSON列索引

请注意,JSON列不能直接索引。创建一个索引,索引列间接地,你可以定义一个生成的列中提取应索引信息,然后创建一个生成的列的索引,如图所示:

MySQL的&#62;CREATE TABLE jemp (-&#62;c JSON,-&#62;g INT GENERATED ALWAYS AS (c->"$.id")),-&#62;INDEX i (g)-&#62;);查询行,0行受影响(0.28秒)MySQL &#62;INSERT INTO jemp (c) VALUES&#62;('{"id": "1", "name": "Fred"}'), ('{"id": "2", "name": "Wilma"}'),&#62;('{"id": "3", "name": "Barney"}'), ('{"id": "4", "name": "Betty"}');查询好,四行受影响(0.04秒)记录:四重复:0警告:0mysql &#62;SELECT c->>"$.name" AS name&#62;FROM jemp WHERE g > 2;-------- |名字| -------- | Barney | |贝蒂| -------- 2行集(0秒)MySQL &#62;EXPLAIN SELECT c->>"$.name" AS name&#62;FROM jemp WHERE g > 2\G*************************** 1。行***************************编号:1 select_type:简单表:jemp分区:null类型:rangepossible_keys:我:我key_len:5编号:零排:2过滤:额外100:用其中1行集,1报警(0秒)MySQL &#62;SHOW WARNINGS\G*************************** 1。行***************************水平:注意代码:1003message:/ * * /选择选择# json_unquote(json_extract(`测试`。` jemp `。` C `,“美元。名字))作为`名字`从`测试`。` jemp `哪里(`测试`。` jemp ` ` G。` &#62;二)一行在集(0.001秒)

(我们已经把输出从这个例子中的最后一句话适合观赏区。)

当你使用EXPLAIN在一个SELECT或其他SQL语句包含一个或多个表达式的使用-&#62;->>运营商,这些表达式翻译成对应使用json_extract()和(如果需要)JSON_UNQUOTE()相反,如图所示的输出SHOW WARNINGS紧随这解释声明:

mysql> EXPLAIN SELECT c->>"$.name"
     > FROM jemp WHERE g > 2 ORDER BY c->"$.name"\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: jemp
   partitions: NULL
         type: range
possible_keys: i
          key: i
      key_len: 5
          ref: NULL
         rows: 2
     filtered: 100.00
        Extra: Using where; Using filesort
1 row in set, 1 warning (0.00 sec)

mysql> SHOW WARNINGS\G
*************************** 1. row ***************************
  Level: Note
   Code: 1003
Message: /* select#1 */ select json_unquote(json_extract(`test`.`jemp`.`c`,'$.name')) AS
`c->>"$.name"` from `test`.`jemp` where (`test`.`jemp`.`g` > 2) order by
json_extract(`test`.`jemp`.`c`,'$.name')
1 row in set (0.00 sec)

看到的描述->->>算子,以及那些的JSON_EXTRACT()JSON_UNQUOTE()功能,提供更多的信息和例子。

这种技术也可以用来提供指标间接引用列的其他不能直接索引类型,如GEOMETRY专栏

肌酸片合成器

CREATE TABLESPACE tablespace_name
    ADD DATAFILE 'file_name'
    [FILE_BLOCK_SIZE = value]
        [ENGINE [=] engine_name]

这句话是用来创建一个InnoDB表空间。一个InnoDB表空间的创建使用CREATE TABLESPACE被称为一般的表空间

一般的表空间是一个共享空间,类似于系统表空间。它可以保存多个表,并支持所有的表行的格式。一般表空间,也可以在一个相对位置或独立的MySQL数据目录中创建。

在创建一个InnoDBtablespace将军,您可以使用CREATE TABLE tbl_name ... TABLESPACE [=] tablespace_nameALTER TABLE tbl_name TABLESPACE [=] tablespace_nameTo add tables to the Tabesace .

有关更多信息,参见第15.7.10”一般,InnoDB表空间”

笔记

CREATE TABLESPACE支持InnoDB。在以前的版本,CREATE TABLESPACE仅支持NDB,这是MySQL NDB簇存储引擎。

选项

  • ADD DATAFILEdefines:the name of the表空间的数据文件。在指定日期文件must be with the创建表空间声明和数据文件名必须有一个.ibd扩展一个InnoDB一般表空间只支持单个数据文件。

    将数据文件中的MySQL数据目录以外的位置(DATADIR),包括一个绝对路径或相对路径的MySQL数据目录。如果你不指定路径,一般表空间是在MySQL数据目录中创建。

    避免与隐式创建的每个表的表空间文件冲突,MySQL数据目录下创建子目录中的一个通用的表空间是不支持的。另外,当创建一个表空间的MySQL数据目录外,目录必须存在并且必须知道InnoDB创建表空间之前。让一个未知的目录称为InnoDB,目录添加到innodb_directories参数的值innodb_directories是一个只读的启动选项。需要重新启动服务器配置。

    这个file_name,包括路径(可选),必须引用单或双引号。文件名(不包括鸡传染性法氏囊病扩展)和目录名的长度必须在至少一个字节。长度为零的文件名和目录不支持的名字。

  • FILE_BLOCK_SIZE:定义表空间的数据文件的块大小。如果不指定此选项,file_block_size默认值为innodb_page_size。这个file_block_size设置是如果你将使用表空间来存储压缩仅需InnoDBTableROW_FORMAT=COMPRESSED)。在这种情况下,你必须定义表空间FILE_BLOCK_SIZEWhen creating the Tabesace .

    如果FILE_BLOCK_SIZE是平等的innodb_page_size,表空间只包含表与未压缩格式(行粉盒REDUNDANT,和动态Lrow Forum)。同一桌COMPRESSED行格式有不同的物理页面大小比未压缩的表。因此,压缩表不能共存于同一空间的压缩的表。

    对于含有压缩表通用表,FILE_BLOCK_SIZE必须指定,并file_block_size值必须是一个有效的压缩页面的大小的关系innodb_page_size价值。另外,该压缩表的物理页面大小(key_block_size)必须等于FILE_BLOCK_SIZE/1024。例如,如果innodb_page_size=16K,和FILE_BLOCK_SIZE=8K,的KEY_BLOCK_SIZE该表必须是8。有关更多信息,参见第15.7.10”一般,InnoDB表空间”

  • ENGINE:定义所使用的表空间存储引擎的地方engine_name是存储引擎的名称。目前,只有InnoDB存储引擎支持ENGINE = InnoDB必须定义的一部分创建表空间声明或InnoDB必须定义为默认存储引擎(default_storage_engine=InnoDB

笔记

  • tablespace_name是一个标识符区分大小写的表空间。它可能被引用或非上市。正斜杠字符(/)是不允许的。的名字开始innodb_不允许或是保留的特殊用途。

  • 临时表空间创建一般不支持。

  • 一般不支持临时表的表空间。

  • 这个TABLESPACE选项可用于CREATE TABLEALTER TABLE分配InnoDB表分区和子分区到一般的表空间每个表的表空间,一个单独的文件,或者系统表空间。所有分区都必须属于相同的存储引擎。有关更多信息,参见第15.7.10”一般,InnoDB表空间”

  • 一般表空间支持添加表的任何行格式使用CREATE TABLE ... TABLESPACEinnodb_file_per_table不需要启用

  • innodb_strict_mode不适用于一般的表空间。表空间管理制度严格执行独立innodb_strict_mode。如果创建表空间参数不正确或不兼容,操作失败的innodb_strict_mode设置当一个表添加到一个表空间使用CREATE TABLE ... TABLESPACEALTER TABLE ... TABLESPACEinnodb_strict_mode被忽略,但声明进行评估,如innodb_strict_mode启用

  • 使用DROP TABLESPACE除去一般的表空间。所有表格必须从一般的表空间使用DROP TABLEPrior to dropping the Tabesace .

  • 一个表的所有部件添加到一个表空间驻留在一般的表空间,包括索引和BLOB网页

  • 类似的系统表空间,截断或删除表存储在表空间创建的自由空间一般在一般的表空间IBD数据文件这只能用于新InnoDB数据空间不回操作系统是每个表的表空间文件发布。

  • 一般的表空间是不与任何数据库或架构相关。

  • ALTER TABLE ... DISCARD TABLESPACEALTER TABLE ...IMPORT TABLESPACE不属于一个总的表空间表支持。

  • 服务器使用表空间级的元数据表引用一般DDL锁。通过比较,服务器使用表级元数据引用表的表空间文件DDL锁。

  • 一个生成的或现有的表空间不能被改变到一个一般的表空间。

  • 这是一般的表空间的名称和每个表的表空间名称文件之间没有冲突。这个/性格,这是在每个表空间的名称的文件,一般是不允许表空间的名字。

实例

本示例演示如何创建一个通用的表空间添加不同格式压缩的表行三。

mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1 ROW_FORMAT=REDUNDANT;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t2 (c1 INT PRIMARY KEY) TABLESPACE ts1 ROW_FORMAT=COMPACT;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE t3 (c1 INT PRIMARY KEY) TABLESPACE ts1 ROW_FORMAT=DYNAMIC;
Query OK, 0 rows affected (0.00 sec)

此示例演示如何创建一个通用表和添加压缩表。这个例子假设默认innodb_page_size大学16kfile_block_size对来自要求压缩表有KEY_BLOCK_SIZE8

mysql> CREATE TABLESPACE `ts2` ADD DATAFILE 'ts2.ibd' FILE_BLOCK_SIZE = 8192 Engine=InnoDB;Query OK, 0 rows affected (0.01 sec)mysql> CREATE TABLE t4 (c1 INT PRIMARY KEY) TABLESPACE ts2 ROW_FORMAT=COMPRESSEDKEY_BLOCK_SIZE=8;Query OK, 0 rows affected (0.00 sec)

13.1.20创建触发器的语法

CREATE
    [DEFINER = { user | CURRENT_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

这个语句创建了一个新的触发器。触发器是命名与表相关的数据库对象,并激活时,一个特定的事件发生时的表。触发成为命名表关联tbl_name,这必须是一个永久表。你不能用一副触发临时表或视图

在架构命名空间的名字意味着所有存在的触发器,触发器必须在一个模式都有唯一的名字。在不同架构的触发器可以有相同的名字。

本节介绍CREATE TRIGGER语法。额外的讨论,见第23.3.1,“Trigger Syntax的例子”

CREATE TRIGGER要求TRIGGER与触发相关的表的权限。声明还要求SET_USER_IDSUPER特权,取决于定义者价值,在本节后面介绍。如果启用了二进制日志,CREATE TRIGGER可能需要SUPER特权,如23.7节,“二进制日志存储程序”

这个DEFINER条款确定用于检查访问权限在触发时安全的前提下,在本节后面介绍。

trigger_time是触发时间。它可以之前AFTER表明触发激活每一行被修改之前或之后。

基本列值检查发生触发激活之前,你不能使用BEFORE触发值转换为适合列类型的有效值。

trigger_event显示操作激活触发类。这些trigger_event值是允许的:

这个trigger_event并不代表一个文字类型的SQL语句激活触发甚至代表着一种表操作。例如,一个INSERT触发激活不仅INSERT声明还LOAD DATA因为陈述语句将行插入表。

这一潜在的混乱的例子是INSERT INTO ... ON DUPLICATE KEY UPDATE ...语法:(一)在之前插入触发激活每一行,然后可以通过一个AFTER INSERT触发或两者更新前AFTER UPDATE触发器,取决于是否有一个排的钥匙。

笔记

级联外键动作不激活触发器。

可以定义多个触发器的一个给定的表具有相同的触发事件和动作时间。例如,你可以有两BEFORE UPDATE一个表的触发器。默认情况下,触发器具有相同的触发事件和动作时间激活它们的创建顺序。影响触发命令,指定一个trigger_order条款说明跟随PRECEDES的名称和现有的触发器,也有相同的触发事件和动作时间。与跟随,新的触发激活现有触发后。与PRECEDES,新的触发激活之前已有触发器。

trigger_body是语句执行时触发激活。执行多个语句,使用BEGIN ... END复合语句构造。这也可以让你使用,在存储程序允许相同的语句。看到第13.6.1,”开始…端复合语句语法”。有些语句不允许在触发器;看第1,“限制存储的程序”

在触发体,你可以参考主题中的表列(与触发相关的表)通过使用别名OLDOLD.col_name是指在更新或删除一列现有行。col_name指的是一个新的行的列插入或更新现有的行后。

触发器不能使用NEW.col_name或使用旧版col_name是指生成的列。有关生成的列的信息,参见第13.1.18.8,“创建表和生成的列”

MySQL存储sql_mode系统变量的设置在一个触发器的创建,并始终执行触发身体与此设置生效,无论当前服务器的SQL模式触发时开始执行

这个DEFINER子句指定要使用的访问权限检查触发激活的时候,MySQL账户。如果一个user值,它应该是一个指定的MySQL账户&#39;user_name“@”host_name&#39;CURRENT_USER,或CURRENT_USER()。默认的定义者价值是用户执行CREATE TRIGGER声明。这是作为指定相同的DEFINER = CURRENT_USER明确地.

如果您指定的DEFINERClause,These rules found the Valid定义者用户价值:

  • 如果你没有SET_USER_IDSUPER特权,唯一被允许的user价值是你自己的帐户,指定从字面上或用CURRENT_USER。不能设置定义到其他帐户。

  • 如果你有SET_USER_IDSUPER特权,你可以指定任何语法有效的帐户名。如果帐户不存在,将生成一条警告。

  • 虽然它是可以用一个不存在的创建触发器DEFINER帐户,这不是一个好主意,这样的触发是直到帐户激活确实存在。否则,相对于特权检查的行为是未定义的。

MySQL以DEFINER进入用户账户检查时触发特权如下:

  • CREATE TRIGGER时间,谁的问题语句的用户必须具有TRIGGER特权

  • 在触发时间、权限检查DEFINER用户该用户必须有这些特权:

    • 这个TRIGGER在科目表的特权

    • 这个SELECT为主题的表特权如果发生表列参考使用旧版col_namecol_name在触发体

    • 这个UPDATE为主题的表特权如果表列的目标建立新的col_name=value在触发体作业

    • 任何其他特权通常是语句触发器执行的要求。

关于触发安全性的更多信息,参见23.6节,“访问控制用于存储程序和视图”

在触发器中的身体,CURRENT_USER()函数返回用于触发激活时检查权限的帐户。这是定义者用户,没有用户的行为导致触发器被激活。有关用户审计的触发信息,看第6.3.13,“基于SQL MySQL账户活动审计”

如果你使用LOCK TABLES锁定一个表,触发器,触发器中使用表锁定,如第13.3.6.2,“锁表和触发器”

用于触发使用额外的讨论,见第23.3.1,“Trigger Syntax的例子”

13.1.21创建视图的语法

CREATE
    [OR REPLACE]
    [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
    [DEFINER = { user | CURRENT_USER }]
    [SQL SECURITY { DEFINER | INVOKER }]
    VIEW view_name [(column_list)]
    AS select_statement
    [WITH [CASCADED | LOCAL] CHECK OPTION]

这个CREATE VIEW语句创建新的视图,或替换现有的观点如果或更换条款了。如果视图不存在,CREATE OR REPLACE VIEW是一样的CREATE VIEW。如果视图是否存在,CREATE OR REPLACE VIEW取代它

关于视图的使用限制的信息,参见第5,“限制的观点”

这个select_statement是一个SELECT声明提供了视图的定义。(选择选择,实际上,的使用SELECT的声明。)select_statement可以选择从基本表或其他视图。

视图的定义是冷冻在创建时,不由对基础表的定义,随后的变化的影响。例如,如果一个视图的定义是SELECT *在桌子上,新列添加到表中后不成为视图的一部分,和列从表中删除将导致一个错误的选择的观点。

这个ALGORITHM条款影响到MySQL过程观。这个定义者SQL SECURITY子句指定安全上下文可用于检查访问权限时,在视图的调用。这个检查选项条款可以用来约束插入或更新视图所引用的表中的行。这些条款在本节后面介绍。

这个CREATE VIEW声明要求CREATE VIEW为视图的特权,并为每个列选定的一些特权SELECT声明。用于其他列SELECT声明,你必须有SELECTPrivigleyif the或更换子句,也必须DROP为视图特权CREATE VIEW可能还需要SET_USER_IDSUPER特权,取决于定义者价值,在本节后面介绍。

当一个视图被引用,权限检查发生在本节后面介绍。

一种观点是属于一个数据库。默认情况下,一个新的视图是默认的数据库创建。创建视图明确给定数据库中,使用db_name.view_name语法与数据库名称限定视图名称:

创建视图的测试。V为SELECT * FROM t;

在不合格的表或视图的名称SELECT声明还解释相对于默认数据库。一个视图可以引用其他数据库表或视图中的表或视图的资格与相应的数据库名称。

在数据库、表和视图共享同一命名空间,所以基表和视图的名称不能相同。

检索的列SELECT语句可以简单的引用表中的列或表达式,使用函数,常数值,运营商,等等。

一个视图必须没有重复,有独特的列名称,就像一个基表。默认情况下,该列的名称检索SELECT声明用于视图列的名字。定义的视图列明确的名称,指定可选column_list条款一列逗号分隔的标识符。名称数量column_list必须作为检索的列数相同SELECT声明

一个视图可以从多种创建SELECT声明.它可以指基表或其他视图。它可以使用联接,UNION和子查询。theSELECT甚至不需要参考任何表:

创建视图v_today(今天)作为选择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 |
+------+-------+-------+

视图定义受以下限制:

  • 这个SELECT语句不能引用系统变量和用户定义的变量。

  • 在存储程序的SELECT语句不能引用程序的参数或局部变量。

  • 这个SELECT语句不能引用声明参数。

  • 任何表或视图中所提到的定义必须存在。如果在视图被创建,一个表或视图的定义指的是在下降,使用错误的结果。检查对这类问题的视图定义,使用CHECK TABLE声明

  • 定义不能指TEMPORARY表,你不能创建一个临时意见

  • 你不能用一个视图关联的触发。

  • 在列名别名SELECT声明反对64字符列的最大长度检查(不是最大长度为特征的别名)。

ORDER BY在一个视图中定义的允许的,但它是如果从一个视图使用一个语句,都有自己的选择你忽略顺序

在定义其他选项或条款,他们加入到声明引用视图的选项或条款,但效果是不确定的。例如,如果一个视图定义包含LIMIT条款,你选择使用一个语句,有自己的观点极限条款,它是未定义的限制适用。这一原则也同样适用于选项如ALL不同的,或SQL_SMALL_RESULT遵循SELECT关键词,和条款如FOR UPDATE分享LOCK IN SHARE MODE,和程序

结果从一个观点可能是如果你改变查询处理环境改变系统变量的影响:

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)

这个DEFINERSQL安全条款确定MySQL时使用的帐户检查权限访问视图在语句执行时引用的观点。有效SQL SECURITY特征值定义者(默认的),INVOKER。这表明所需的权限必须由谁定义或调用查看用户举行,分别。

如果一个user给出值为定义者条款,它应该是一个指定的MySQL账户'user_name'@'host_name'CURRENT_USER,或CURRENT_USER()。默认的定义者价值是用户执行CREATE VIEW声明。This is the same as specifyingDEFINER = CURRENT_USER明确地.

如果DEFINER子句,这些规则确定有效定义者用户价值:

  • 如果你没有SET_USER_IDSUPERPrivigley,The only Validuser价值是你自己的帐户,指定从字面上或用CURRENT_USER。不能设置定义到其他帐户。

  • 如果你有SET_USER_IDSUPER特权,你可以指定任何语法有效的帐户名。如果帐户不存在,将生成一条警告。

  • 虽然它是可以用一个不存在的创建一个视图DEFINER账户,发生错误引用视图时如果SQL安全DEFINER但定义帐户不存在

有关视图安全性的更多信息,参见23.6节,“访问控制用于存储程序和视图”

在一个视图的定义,CURRENT_USER返回视图的定义者默认值。定义的视图SQL SECURITY INVOKER特征,CURRENT_USER返回视图的调用帐户。有关用户审核意见的信息,参见第6.3.13,“基于SQL MySQL账户活动审计”

在存储程序的定义与SQL SECURITY DEFINER特征,CURRENT_USER常规的回报定义者价值。这也影响到在这样一个常规定义的视图,如果视图定义包含一个DEFINER价值CURRENT_USER

MySQL检查视图特权这样:

  • 在视图定义时,视图的创建者必须要用顶层对象的视图的访问权限。例如,如果视图的定义是指表列,创作者必须在定义选择列表中的每个列一些特权,和SELECT每一列定义中使用的其他特权。如果定义是指存储功能,只需要调用权限功能可以检查。在函数调用时所需的权限可以检查只有在执行:对于不同的调用,不同的执行路径的功能可能会被。

  • 用户谁引用一种观点必须有合适的权限访问它(SELECT选择它,INSERT插入它,等等。)

  • 当一个视图被引用的视图访问的对象权限的反对观点的权限检查DEFINER帐户或调用,这取决于SQL安全特点是DEFINER调用,分别

  • 如果参考视图使存储功能的执行权限检查,在函数执行的语句取决于功能SQL SECURITY特点是定义者INVOKER。如果安全特性定义者,功能运行的特权DEFINER账户如果其特征调用,功能运行的观点确定的特权SQL SECURITY特征

例如:一个视图可以依靠存储功能,这功能可以调用其他存储过程。例如,以下视图调用存储函数f()

CREATE VIEW v AS SELECT * FROM t WHERE t.id = f(t.name);

假设f()包含一个声明,像这样的:

如果名称为空则称p1();别人叫p2();如果;

执行语句所需的权限之内f()需要检查的时候f()执行。这可能意味着特权的需要p1()p2()根据不同的执行路径中,f()。这些特权必须在运行时检查,和用户必须拥有的权限是由SQL安全观点的价值v和功能f()

这个DEFINERSQL安全条款的观点是标准的SQL扩展。在标准的SQL,视图是使用规则SQL SECURITY DEFINER。标准说,视图的定义,作为视图模式的所有者一样,获取适用的特权的观点(例如,SELECT),可以给予。MySQL有没有一个模式概念主人,所以MySQL添加条款确定的定义。这个DEFINER条款是一个扩展的意图是有什么标准;即,一个永久的记录,谁定义的视图。这就是为什么默认定义者价值观的创造者的帐户。

可选ALGORITHM子句是一个mysql扩展标准的SQL。它影响到MySQL的过程观。算法以三值:MERGE诱人的,或UNDEFINED。有关更多信息,参见第23.5.2,”视图处理算法,以及第8.2.2.3,“优化派生表、视图的引用,和公用表表达式”

一些视图是可更新的。那就是,你可以使用它们的报表等UPDATEDELETE,或INSERT更新基础表的内容。一个视图是可更新的,必须有一个一对一的关系排在视图和基础表中的行。也有一些其他的结构,使视图nonupdatable。

一个生成的列在视图是可更新的因为它可以给它。但是,如果这样的更新列明确,唯一被允许的值DEFAULT。有关生成的列的信息,参见第13.1.18.8,“创建表和生成的列”

这个WITH CHECK OPTION条款可以考虑可更新视图以防止插入或更新的行除了那些哪里子句中select_statement是真的

在一个WITH CHECK OPTION可更新视图的条款,当地CASCADED关键词确定测试范围视图时,在另一个视图的定义。这个当地关键词限制CHECK OPTION只有视图定义级联使检查视图被评价为好。当没有关键字,默认是CASCADED

为更多的信息关于可更新的视图和WITH CHECK OPTION条款,看第23.5.3,”Updatable和可插入的意见”,和第23.5.4,“检查选项条款”的观点

13.1.22删除数据库的语法

DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

DROP DATABASE滴数据库中所有表和删除数据库。是非常注意这句话!使用DROP DATABASE,你需要的DROP对数据库的权限DROP SCHEMA是同义词DROP DATABASE

重要

当一个数据库删除,权限的数据库是专门为自动删除。他们必须删除手动。看到第13.7.1.6,”格兰特语法”

IF EXISTS是用来防止错误的发生如果数据库不存在。

如果默认数据库删除,默认的数据库设置(的DATABASE()函数返回无效的

如果你使用DROP DATABASE在象征性地与数据库的链接,并删除原始数据库。

DROP DATABASE返回表的取数

这个DROP DATABASE从给定的数据库目录中的文件和目录,MySQL本身可能在正常操作期间创建删除语句。这包括所有的文件显示在以下列表中的扩展:

  • .BAK

  • .DAT

  • .HSH

  • .MRG

  • .MYD

  • .MYI

  • .cfg

  • .db

  • .ibd

  • .ndb

如果其他文件或目录保持在数据库目录后MySQL删除那些刚刚上市,数据库目录不能被删除。在这种情况下,您必须删除任何剩余的文件或目录手动和问题DROP DATABASE再次声明

删除数据库不删除任何TEMPORARY在数据库中创建表临时表格会自动删除创建它们的会话结束时。看到第13.1.18.3,“创建临时表的语法”

你也可以减少数据库mysqladmin。看到4.5.2“,”mysqladmin客户管理MySQL服务器”

排气合成器

DROP EVENT [IF EXISTS] event_name

这一声明滴命名事件event_name。事件立即停止活动,并完全从服务器上删除。

如果事件不存在误差错误1517(hy000):未知事件event_name&#39;结果您可以重写此导致语句生成而不是使用不存在的事件的一个警告如果存在

这句话需要EVENT特权模式,事件被删除。

13.1.24降功能语法

这个DROP FUNCTION语句用于删除存储函数和用户自定义函数(UDF):

13.1.25删除索引的语法

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“指数下降index_name从表tbl_name。这句话是映射到ALTER TABLE语句删除索引。看到第13.1.8,“ALTER TABLE语法”

把主键、索引名称总是PRIMARY,必须指定为引用的标识符,因为首要是一个保留字:

DROP INDEX `PRIMARY` ON t;

ALGORITHM锁具条款可能会影响表复制的方法,虽然其指标正在修改读写并发水平表。他们有同样的含义ALTER TABLE声明。有关更多信息,参见第13.1.8,“ALTER TABLE语法”

13.1.26下降过程和降功能语法

DROP {PROCEDURE | FUNCTION} [IF EXISTS] sp_name

这项声明是用于删除存储过程或函数。即指定程序从服务器上删除。你必须有ALTER ROUTINE特权的例行公事。(如果自动_ SP _特权系统变量是启用的,这个特权,EXECUTE被自动授予常规的创造者在常规创建来自造物主下降时,常规的下降。看到第23.2.2,“存储程序和MySQL的特权”。)

这个IF EXISTS是一个mysql扩展条款。它可以防止错误的发生如果过程或函数不存在。警告产生,可以被视为与SHOW WARNINGS

DROP FUNCTION也用于删除用户定义函数(见第13.7.4.2,“降功能语法”

13.1.27滴Server语法

DROP SERVER [ IF EXISTS ] server_name

滴命名服务器的服务器定义server_name。在相应的行mysql.servers表被删除。这一声明要求SUPER特权

一个表删除服务器不影响任何FEDERATED表,用此连接的信息时,他们创造了。看到第13.1.16,“创建服务器语法”

DROP SERVER一个隐含的承诺的原因。看到13.3.3部分,”声明,因为一个隐含的承诺”

DROP SERVER不写入二进制日志,不管日志格式,使用。

13.1.28下降空间参考系统的语法

DROP SPATIAL REFERENCE SYSTEM
    [IF EXISTS]
    srid

srid: 32-bit unsigned integer

这个语句删除空间参考系统(SRS)从数据字典中的定义。它要求SUPER特权

例子:

DROP SPATIAL REFERENCE SYSTEM 4120;

如果没有SRS定义与SRID值存在,发生错误,除非IF EXISTS指定。在这种情况下,发生了警告,而不是一个错误。

如果方案的价值是由现有的表中的一些列使用,发生了一个错误。例如:

mysql> DROP SPATIAL REFERENCE SYSTEM 4326;
ERROR 3716 (SR005): Can't modify SRID 4326. There is at
least one column depending on it.

确定列使用抗血清,用这个查询:

SELECT * FROM INFORMATION_SCHEMA.ST_GEOMETRY_COLUMNS WHERE SRS_ID=4326;

SRID值必须在32位无符号整数的范围,这些限制:

  • SRID 0是一个有效的扩散但不能使用DROP SPATIAL REFERENCE SYSTEM

  • 如果该值是一个保留SRID范围发生了警告。保留的范围[ 0, 32767 ](保留由EPSG),[ 60000000, 69999999 ](保留由EPSG),和[ 2000000000, 2147483647 ](保留MySQL)。每股收益增长率为欧洲石油调查组

  • 用户不应在保留SRIDs SRSS范围。如果系统安装了SRSS的下降,SRS定义可以创建MySQL升级。

13.1.29下拉表的语法

DROP [TEMPORARY] TABLE [IF EXISTS]
    tbl_name [, tbl_name] ...
    [RESTRICT | CASCADE]

DROP TABLE删除一个或多个表。你必须有DROP每个表的权限

小心这种说法!它消除了表定义和表中的所有数据。对于分区表,它将永久删除表定义,所有分区所有数据存储在这些分区。它也消除了相关的分区定义表。

DROP TABLE使一个隐式提交,除非用临时关键词看到13.3.3部分,”声明,因为一个隐含的承诺”

重要

当一个表被删除,权限的具体表自动删除。他们必须删除手动。看到第13.7.1.6,”格兰特语法”

如果在参数列表中指定的任何表不存在,则语句失败与错误指示不存在的表的名字是无法下降,并且不进行任何更改。

使用IF EXISTS为了防止错误的发生不存在的表。而不是一个错误,一个笔记是一个不存在的表生成;这些笔记可以显示SHOW WARNINGS。看到第13.7.6.40,“显示警告语法”

IF EXISTS也可以滴在不寻常的情况下,有一个入口在数据字典中没有表的存储引擎管理的表是有用的。(例如,如果服务器发生异常退出后从存储引擎去除表但是数据字典条目。去除之前)

这个TEMPORARY关键词有以下作用:

  • 声明仅下降TEMPORARY

  • 声明并不会导致一个隐式提交。

  • 没有访问权限检查。一TEMPORARY表是可见的只有创建它的会话,所以没有必要检查。

使用TEMPORARY是确保你不小心掉不好的方式—临时

这个RESTRICT级联关键词做什么。他们被允许做移植到其他数据库系统更容易。

DROP TABLE不支持所有的innodb_force_recovery设置看到第15.20.2,迫使InnoDB恢复”

13.1.30删除表空间语法

DROP TABLESPACE tablespace_name
   [ENGINE [=] engine_name]

这个语句是用来降低InnoDB一般表空间的创建使用CREATE TABLESPACE语法。(这第13.1.19,“创建表的语法”

所有表格必须退出之前,一个表空间DROP TABLESPACE运营如果空间不是空的,删除表空间返回一个错误

tablespace_name是一个敏感的标识符在MySQL。

ENGINE:定义使用表空间的存储引擎,在engine_name是存储引擎的名称。目前,只有InnoDB存储引擎支持

笔记

这个ENGINE条款已过时,将在未来的版本中删除。表空间存储引擎是由数据字典,使引擎条款已经过时

笔记

  • 一般InnoDB表空间是不会自动删除在表空间上表被删除。表空间必须删除显式使用删除表空间tablespace_name

  • DROP DATABASE操作可降,属于一个总的表表但不能下降的空间,即使操作滴所有属于表表。表空间必须删除显式使用删除表空间tablespace_name

  • 类似的系统表空间,截断或删除表存储在表空间创建的自由空间一般在一般的表空间IBD数据文件这只能用于新InnoDB数据空间不回操作系统是每个表的表空间文件发布。

例子

这个例子演示了如何删除InnoDBTabesace将军Tabesace将军TS1是一个表创建。在删除表空间、表必须下降。

mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts10 Engine=InnoDB;
Query OK, 0 rows affected (0.02 sec)

mysql> DROP TABLE t1;
Query OK, 0 rows affected (0.01 sec)

mysql> DROP TABLESPACE ts1;
Query OK, 0 rows affected (0.01 sec)

13.1.31删除触发器语法

DROP TRIGGER [IF EXISTS] [schema_name.]trigger_name

这一声明滴触发。图式(数据库)的名称是可选的。如果架构略,触发的默认模式了。DROP TRIGGER要求TRIGGER与触发相关的表的权限。

使用IF EXISTS防止错误发生的一个触发器不存在。一笔记产生一个不存在的触发时使用IF EXISTS。看到第13.7.6.40,“显示警告语法”

一个表的触发器也如果你把表掉。

13.1.32删除视图的语法

DROP VIEW [IF EXISTS]
    view_name [, view_name] ...
    [RESTRICT | CASCADE]

DROP VIEW删除一个或多个视图。你必须有DROP每个视图的权限

如果有任何意见,在参数列表中指定的不存在,则语句失败与错误指示的名字,不存在的观点很难下降,并且不进行任何更改。

笔记

在MySQL 5.7早,DROP VIEW如果有任何意见,在参数列表中指定不存在返回一个错误,但也下降,表观存在。由于在MySQL 8中行为的变化,部分完成DROP VIEW在MySQL 5.7主失败时,复制到MySQL 8从操作。为了避免这种失败的情况下,使用如果存在语法DROP VIEW语句来防止错误发生的视图不存在。有关更多信息,参见第13.1.1,“原子数据定义语句的支持”

这个IF EXISTS条款防止错误发生的视图不存在。当这个条款,一笔记是一个不存在的视图生成。看到第13.7.6.40,“显示警告语法”

RESTRICT级联,如果,解析和忽视

13.1.33重命名表语法

RENAME TABLE
    tbl_name TO new_tbl_name
    [, tbl_name2 TO new_tbl_name2] ...

RENAME TABLE重命名一个或多个表。你必须有ALTERDROP对原表的权限,并CREATEINSERTprivileges为纽约的表。

例如,重命名表名old_tablenew_table使用此语句:

RENAME TABLE old_table TO new_table;

这种说法是相当于如下ALTER TABLE声明:

修改表old_table重命名new_table;

RENAME TABLE,不像ALTER TABLE重命名多个表,可以在一个语句:

重命名表old_table1到new_table1,old_table2到new_table2,old_table3到new_table3;

重命名操作左到右。因此,交换两个表的名称,这样做(假设与中介名称的表tmp_table已经不存在了):

重命名表old_table到tmp_table,new_table到old_table,tmp_table到new_table;

在MySQL 8.0.13,您可以重命名表锁一LOCK TABLES声明,只要他们锁定了锁或是重命名的产品WRITE锁定表的多表前面的步骤重命名操作。例如,这是允许的:

锁表old_table1写;重命名表old_table1到new_table1,new_table1到new_table2;

这是不允许的:

LOCK TABLE old_table1 READ;
RENAME TABLE old_table1 TO new_table1,
             new_table1 TO new_table2;

MySQL 8.0.13之前,执行RENAME TABLE,必须没有表锁锁定表

随着交易表锁定的条件下,重命名操作是原子;没有其他会话可以访问任何桌子,重命名是进步。

如果出现任何错误时RENAME TABLE,该语句将失败并且不进行任何更改。

你可以使用RENAME TABLE将表从一个数据库到另一个:

重命名表current_db.tbl_nameother_db.tbl_name;

用这种方法把表从一个数据库中的影响不同的一个重命名数据库(MySQL操作,没有单一的语句),除了原有的数据库仍然存在,尽管并不表。

喜欢RENAME TABLE修改表…重命名也可以用来移动到一个不同的数据库表。无论使用说明,如果重命名操作将表数据库位于不同的文件系统,结果的成功是特定于平台的,依赖于底层的操作系统调用用来移动表格文件。

如果表的触发器,重命名的表到一个不同的数据库失败在错误的模式触发ER_TRG_IN_WRONG_SCHEMA)错误

重命名TEMPORARY桌子,重命名表不工作。使用ALTER TABLE相反

RENAME TABLE作品的看法,但观点不能被重命名为一个不同的数据库。

任何特权授予专门为更名为表或视图不迁移到新的名字。他们必须手动更改。

RENAME TABLE改变内部生成的外键约束的名称和定义的外键约束名称包含字符串tbl_name_ ibfk _以反映新的表名InnoDB将外键约束名称包含字符串tbl_name_ ibfk _为自创的名字

外键约束的名称,点重命名的表会自动更新,除非有冲突,在这种情况下,语句失败与错误。如果重命名约束名称已经存在发生冲突。在这种情况下,必须放弃,重新为他们正常创建外键。

13.1.34截断表语法

TRUNCATE [TABLE] tbl_name

TRUNCATE TABLE清空表完全。它要求DROP的特权。logically,TRUNCATE TABLE是一个类似DELETE语句删除所有行,或一个序列DROP TABLECREATE TABLE声明.

实现高性能,TRUNCATE TABLE绕过删除数据的DML方法。因此,它不会引起在删除引发火灾,不能进行InnoDB亲子外键关系表,它不能回滚的像一个DML操作。然而,TRUNCATETABLE在表中使用存储引擎原子DDL操作是完全提交或回滚如果服务器在运行过程中死机。有关更多信息,参见第13.1.1,“原子数据定义语句的支持”

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

  • 截断操作删除并重新创建表,比删除行之一,特别是对于大型的表。

  • 截断操作造成隐式提交,所以不能回滚。看到13.3.3部分,”声明,因为一个隐含的承诺”

  • 截断操作不能如果会话持有积极的表锁行。

  • TRUNCATE TABLE失败的一个InnoDB表或NDB如果有任何外键从其他表引用表的约束。在同一表中的列之间的外键约束允许。

  • 截断操作不返回已删除的行数有意义的价值。通常的结果是0行受影响,这应该被解释为没有信息

  • 只要表定义是有效的,该表可以重新创建一个空表TRUNCATE TABLE,即使数据或索引文件已损坏。

  • 任何AUTO_INCREMENT值重置为其初始值。即使是真的MyISAMInnoDB,通常不使用序列值

  • 当使用分区表,TRUNCATE TABLE保存分区;即,数据和索引文件删除并重新创建,而分区定义不受影响。

  • 这个TRUNCATE TABLE声明不调用在删除触发器

  • 在truncating损坏InnoDB表支持

TRUNCATE TABLE一桌桌,关闭了所有的程序HANDLER OPEN

TRUNCATE TABLE处理二进制日志和复制的目的DROP TABLE然后CREATE TABLE-那是,而不是作为DDL DML。这是因为,当使用InnoDB和其他事务性存储引擎的事务隔离级别不允许声明基于测井(READ COMMITTEDREAD UNCOMMITTED),声明未被记录和复制时使用声明MIXED记录模式。(错误# 36763)然而,它仍然是用于复制奴隶使用InnoDB在先前描述的方式

在MySQL 5.7,早些时候,在一个系统中有一个大的缓冲池innodb_adaptive_hash_index启用,一TRUNCATETABLE操作可能导致系统性能暂时下降由于LRU扫描发生删除表的自适应哈希索引条目时(bug # 68184)。的映射TRUNCATE TABLEDROP TABLECREATE TABLE在MySQL 8避免问题的LRU扫描。

TRUNCATE TABLE可以使用性能模式的汇总表,但效果是重置摘要列0无效的,不删除行。看到第25.11.15,绩效模式汇总表”

13.2 . Data Managing statements

13.2.1调用语法

CALL sp_name([parameter[,...]])
CALL sp_name[()]

这个CALL语句调用存储过程,定义之前CREATE PROCEDURE

存储过程调用没有参数可以不用括号。这是,CALL p()打电话给P是等价的

CALL可以通过返回值使用参数声明为其调用者INOUT参数.在程序运行时,客户端程序也可以获得受影响的行在日常执行的最后声明:在SQL级,叫ROW_COUNT()功能;从C API呼叫。mysql_affected_rows()功能

返回值从一个程序使用OUTINOUT参数,通过用户变量传递参数,然后检查该变量的值在程序返回。(如果你调用程序在另一个存储过程或函数,也可以通过常规的参数或局部变量作为常规ININOUT一个参数。)INOUT初始化参数,其值在传递给程序。下面的过程有一个参数设置为当前服务器版本的程序,和一个INOUT该程序加一从它的当前值:

CREATE PROCEDURE p (OUT ver_param VARCHAR(25), INOUT incr_param INT)BEGIN  # Set value of OUT parameter  SELECT VERSION() INTO ver_param;  # Increment value of INOUT parameter  SET incr_param = incr_param + 1;END;

调用程序之前,初始化变量被传递的INOUT参数.调用程序后,两个变量的值将被设置或修改:

MySQL的&#62;SET @increment = 10;MySQL的&#62;CALL p(@version, @increment);MySQL的&#62;SELECT @version, @increment;———————————————————————————————————————

在制备CALL报表使用PREPAREEXECUTE,占位符可以用于进入参数,OUT,和INOUT参数.这些类型的参数,可以使用如下:

mysql> SET @increment = 10;
mysql> PREPARE s FROM 'CALL p(?, ?)';
mysql> EXECUTE s USING @version, @increment;
mysql> SELECT @version, @increment;
+--------------------+------------+
| @version           | @increment |
+--------------------+------------+
| 8.0.3-rc-debug-log |         11 |
+--------------------+------------+

写C程序使用CALLSQL语句执行存储产生的结果集的程序,client_multi_results国旗必须启用。这是因为每个CALL返回一个结果显示呼叫状态,除了可能在程序执行的语句返回的结果集。client_multi_results也必须启用如果CALL用于执行任何存储过程包含的准备好的语句。它不能确定时,这样的程序加载这些陈述是否会产生的结果集,因此必须假设他们会。

CLIENT_MULTI_RESULTS可以使你打电话时mysql_real_connect(),直接通过client_multi_results标志本身,或隐式地通过CLIENT_MULTI_STATEMENTS(这也使client_multi_resultsCLIENT_MULTI_RESULTS默认情况下启用

处理的结果CALL语句执行使用mysql_query()mysql_real_query(),使用循环调用mysql_next_result()以确定是否有更多的结果。例如,看第27.7.19,“C API多语句执行的支持”

C程序可以使用事先准备好的声明接口来执行CALL声明和访问INOUT参数.这是一个处理的结果了CALL使用循环调用语句mysql_stmt_next_result()以确定是否有更多的结果。例如,看第27.7.21,“C API编写的调用语句的支持”。语言,提供一个MySQL的接口可以使用准备CALL报表直接检索INOUT过程参数

改变对象的元数据被存储的程序进行检测,使受影响的报表程序时自动重新下执行。有关更多信息,参见8.10.3节,“缓存的准备好的语句和存储的程序”

13.2.2删除语法

DELETE是一个DML语句删除行的表。

DELETE语句可以从一个WITH条款定义公用表表达式内访问DELETE。看到第13.2.13,“语法(公用表表达式)”

单表的语法

DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [WHERE where_condition]
    [ORDER BY ...]
    [LIMIT row_count]

这个DELETE语句删除行tbl_name返回删除的行数。检查已删除的行数,称为ROW_COUNT()功能描述12.14节,“信息功能”

主要条款

the conditions in the optionalWHERE从句识别哪些行删除。没有哪里条款,所有的行被删除。

where_condition是为真的每一行被删除的表达式。它被指定为描述第13.2.10,选择“语法”

如果ORDER BY条款规定,行是指定的顺序删除。这个极限地方上的条款可以被删除的行数限制。这些条款适用于单个表中删除,但不删除多台。

多个表的语法

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    tbl_name[.*] [, tbl_name[.*]] ...
    FROM table_references
    [WHERE where_condition]

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    FROM tbl_name[.*] [, tbl_name[.*]] ...
    USING table_references
    [WHERE where_condition]

特权

你所需要的DELETE特权在桌上从中删除行。你需要的仅仅是SELECT任何列是只读权限,如命名的哪里条款.

性能

当你不需要知道被删除的行数,该TRUNCATE TABLE声明是一个更快的方式比一个空表DELETE声明没有哪里条款.不像DELETETRUNCATE TABLE不能用在交易或如果你桌上的锁。看到第13.1.34”truncate table语法”第13.3.6,“锁表和解锁表语法”

速度删除操作也可以通过影响因素探讨第8.2.5.3,“优化删除语句”

确保一个给定的DELETE语句不需要太多时间,MySQL特定的极限row_count条款DELETE指定要删除的最大行数。如果要删除的行数大于极限,重复删除声明到受影响的行数小于LIMIT价值

子查询

您不能删除从表中选择来自同一个表中查询。

分区表

DELETE支持显式分区选择使用分区选项列表,以逗号分隔的一个或多个分区和子分区的名称(或两者)从中选择行被删除。分区不包含在列表中被忽略。给定一个分区表t一个分区命名P0,执行语句DELETE FROM t PARTITION (p0)桌上放有同样效果的执行ALTER TABLE t TRUNCATE PARTITION (p0);在这两种情况下,在分区中的所有行P0下降

PARTITION可随着哪里条件,在这种情况下,条件是只有在上市分区行测试。例如,DELETE FROM t PARTITION (p0) WHERE c < 5删除行只从分区P0for which the weather conditionc < 5是真的;在其它分区的行不检查,从而不受影响删除

这个PARTITION选项也可以被用在多个表删除声明.你可以使用到这样的一个选项,每桌命名的FROM选项

更多的信息和例子,看第22,“分区选择”

自动递增列

如果你删除含有一个最大值的行AUTO_INCREMENT列的值不重复使用一个MyISAMInnoDB表如果你删除表中的所有行删除tbl_name(不一哪里在条款)autocommit序列模式,开始在所有存储引擎除了InnoDBMyISAM。也有一些例外情况的行为InnoDB表格、讨论第15.8.1.5,”auto_increment InnoDB”处理

MyISAM表,您可以指定一个汽车在多个关键次柱柱。在这种情况下,值删除从顶部的序列重复使用甚至发生MyISAM表看到第3,“用auto_increment”

改性剂

这个DELETE声明支持下列修饰符:

  • 如果你指定LOW_PRIORITY,该服务器延迟执行DELETE直到没有其他客户端读取表。这仅影响存储引擎只使用表级锁(如MyISAMMEMORY,和合并

  • MyISAM表,如果你使用改性剂,存储引擎不合并索引叶中删除,这可能会加快一些删除操作。

  • 这个IGNORE改性剂使MySQL忽略错误删除行的过程中。(错误分析阶段是通常的方式。加工)忽略由于使用是错误的忽略返回的警告。有关更多信息,参见在忽略关键词和严格的SQL模式比较

秩序的缺失

如果DELETE声明包括顺序条款,行的子句指定的顺序删除。这主要是与有用LIMIT。例如,下面的语句找到匹配行的哪里条款,它们进行排序timestamp_column,并删除第一个(最新):

DELETE FROM somelog WHERE user = 'jcole'ORDER BY timestamp_column LIMIT 1;

ORDER BY也有助于删除需要避免违反参照完整性的一个命令行。

InnoDB表

如果你是从一个大的表格删除多行,你可能会超过一个锁表的大小InnoDB表为了避免这个问题,或者只是为了减少表被锁定的时候,以下策略(不使用DELETE在所有的)可能会有所帮助:

  1. 选择行要删除到一个空的表具有相同的结构,原来的表:

    INSERT INTO t_copy SELECT * FROM t WHERE ... ;
    
  2. 使用RENAME TABLE自动移动原始表的方式进行,将复制到原来的名字:

    重命名表T t_old,t_copy T;
  3. 放弃了原来的表:

    DROP TABLE t_old;
    

没有其他会话可以访问参与而表RENAME TABLE执行,所以重命名操作不受并发问题。看到第13.1.33,“重命名表语法”

MyISAM表

进入MyISAM表,删除的行保存在一个链表和随后的INSERT业务复用旧行的位置。回收未使用的空间,减少文件的大小,使用OPTIMIZE TABLE声明或myisamchkTulity to return tables .OPTIMIZE TABLE更容易使用,但myisamchk快。看到第13.7.3.4,“优化表语法”,和4.6.4“,”myisamchk- MyISAM表维护工具”

这个QUICK改性剂的影响是否索引叶合并删除操作。删除快速是最有用的应用程序已被删除的行的索引值的行插入以后类似的指数值代替。在这种情况下,被删除的值左孔被重用。

DELETE QUICK是不是有用的时候删除值导致填充索引块生成一系列的指标值为新插入的再次发生。在这种情况下,使用可能导致浪费的空间仍然未索引。这里是这种情况的一个例子:

  1. 创建一个表,包含一个索引AUTO_INCREMENT专栏

  2. 插入多行插入表中。每个插入的结果在一个索引值被添加到索引的高端。

  3. 删除一个行块在低端的柱范围内使用DELETE QUICK

在这种情况下,索引块与删除的索引值成为填充相关但不与其他指标合并块由于使用QUICK。他们仍然充满新插入时发生,因为新的行不在删除范围指标值。此外,他们仍然充满的即使你以后使用DELETE没有,除非一些被删除的索引值发生在位于索引块内或相邻的填充块。回收未使用的索引空间的情况下,使用OPTIMIZE TABLE

如果你要从表中删除多行,可以更快的使用DELETE QUICK然后OPTIMIZE TABLE。这种重建索引而不是执行许多索引块合并操作。

多表删除

你可以在一个指定多个表DELETE语句由一个或多个表取决于条件删除行哪里条款.你不能使用ORDER BY极限在一个多表DELETE。这个table_references子句列出参与联接的表,如第13.2.10.2,加入“语法”

对于第一个表的语法,只有匹配行从表列前FROM条款被删除。第二个表的语法,只有匹配的行列在表条款(前USING被删除的条款)。效果:你可以同时从多个表的行删除,仅用于搜索附加表:

DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3WHERE t1.id=t2.id AND t2.id=t3.id;

DELETE FROM t1, t2 USING t1 INNER JOIN t2 INNER JOIN t3
WHERE t1.id=t2.id AND t2.id=t3.id;

这些语句中使用的所有三个表当搜索行删除,但删除从表匹配的行t1T2

前面的示例使用INNER JOIN,但多表DELETE语句可以使用其他类型的连接允许SELECT报表,如左连接。例如,删除行中存在t1没有比赛T2,使用LEFT JOIN

DELETE t1 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;

这个语法允许.*之后的每一个tbl_name为了兼容访问

如果您使用多个表DELETE声明中涉及InnoDB其中有外键约束的表,MySQL的优化器可能会以不同于他们的父/子关系过程表。在这种情况下,该语句失败并回滚。相反,你应该删除一个表和依靠ON DELETE的能力,InnoDB为使其他表进行相应的修改。

笔记

如果你声明一个表的别名,您必须使用别名时参照表:

DELETE t1 FROM test AS t1, test2 WHERE ...

在多个表的别名DELETEshould be only in the declaredtable_references该语句的一部分。另外,别名引用是允许的但没有别名声明。

对的:

DELETE a1, a2 FROM t1 AS a1 INNER JOIN t2 AS a2
WHERE a1.id=a2.id;

DELETE FROM a1, a2 USING t1 AS a1 INNER JOIN t2 AS a2
WHERE a1.id=a2.id;

不正确的:

DELETE t1 AS a1, t2 AS a2 FROM t1 INNER JOIN t2
WHERE a1.id=a2.id;

DELETE FROM t1 AS a1, t2 AS a2 USING t1 INNER JOIN t2
WHERE a1.id=a2.id;

13.2.3的语法

DO expr [, expr] ...

DO执行表达式,但不返回任何结果。在大多数方面,DO是速记选择expr,…,但优点是速度稍快,当你不在乎结果。

DO主要适用的有副作用的函数,如RELEASE_LOCK()

这个例子:SELECT语句的停顿,但也会产生一个结果集:

MySQL的&#62;SELECT SLEEP(5);---------- |睡眠(5)| ---------- | 0 | ---------- 1行集(5.02秒)

DO,另一方面,停顿而不产生一个结果集。:

MySQL的&#62;DO SLEEP(5);查询行,0行受影响(4.99秒)

这可能是有用的,例如在存储函数或触发器,禁止生产的结果的陈述。

DO只执行表达式。它不能用在所有的情况下,选择可以使用。例如,DO id FROM t1无效,因为它引用的表。

13.2.4样本处理表

HANDLER tbl_name OPEN [ [AS] alias]

HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
    [ WHERE where_condition ] [LIMIT ... ]

HANDLER tbl_name CLOSE

这个HANDLER语句提供了直接访问表的存储引擎接口。它是可用的InnoDBMyISAM

这个HANDLER ... OPEN语句打开一个表,方便后续使用处理程序…阅读声明.这个表对象不会被其他会话共享和不关闭直到会议电话HANDLER ... CLOSE或者会话终止

如果你打开表使用一个别名,与其他的开放进一步参考表HANDLER报表必须使用别名而不是表名。如果你不使用一个别名,但打开表使用表名称的数据库名称合格,再引用必须使用合格的表名称。例如,一台打开使用mydb.mytable进一步的资料,必须使用mytable

第一HANDLER ... READ取一行的索引语法指定满足给定值和哪里条件是满足。如果你有多个列的索引,指定索引列值用逗号分隔的列表。指定在索引的所有列的值,或指定一个索引的最左前缀值列。假设一个指数my_idx包括三个栏目col_acol_b,和col_c,这个顺序。这个HANDLER语句可以指定索引中的所有三列的值,或在最左前缀的列。例如:

HANDLER ... READ my_idx = (col_a_val,col_b_val,col_c_val) ...HANDLER ... READ my_idx = (col_a_val,col_b_val) ...HANDLER ... READ my_idx = (col_a_val) ...

采用HANDLER接口的引用表的主键,使用引用的标识符`PRIMARY`

处理程序tbl_name读小学` `…

第二HANDLER ... READ语法获取一列从表中的索引顺序匹配哪里条件

第三HANDLER ... READ语法一列从表中提取天然排顺序匹配哪里条件它的速度比HANDLER tbl_name READ index_name一个全表扫描时所需的。自然行顺序的行存储在顺序MyISAM表格数据文件。这句话的作品InnoDB桌子上,但没有这样的概念,因为没有单独的数据文件。

没有一个LIMIT条款,所有形式的处理程序…阅读如果有可用的接单排。返回一个特定的行数,包括LIMIT条款.它具有相同的语法为SELECT声明。看到第13.2.10,选择“语法”

HANDLER ... CLOSE关闭一个表,就开了处理程序…开放

有几个方面的使用HANDLER而不是正常的接口SELECT声明:

  • HANDLER速度比SELECT

    • 指定的存储引擎处理对象分配给HANDLER ... OPEN。对象为后续处理程序这张报表;它不需要重新初始化的每一个。

    • 分析涉及较少

    • 没有优化或查询的开销。

    • 处理器的接口没有提供的数据相一致(例如,脏读是允许的),所以存储引擎可以使用优化SELECT不normally许可。

  • HANDLER使它更容易港口到MySQL的应用程序使用一个低级别的ISAM-像接口(见)15.19节,“InnoDB Memcached插件”选择一个适应使用key-value存储模式的应用方式。)

  • HANDLER使您能够以很难遍历数据库(甚至不可能)完成的SELECT。这个处理程序接口是一种更自然的方式查看数据与应用程序的数据库提供了一个交互式用户界面时。

HANDLER是一个有点低级语句。例如,它不提供一致性。这是,处理程序…开放把桌子上的快照,并锁的表。这意味这后HANDLER ... OPEN声明发出后,表中的数据可以被修改(由当前会话或其他会议),这些修改可能仅部分可见处理程序…下一个HANDLER ... PREV扫描

一个开放的处理程序可以关闭并标记为重新开放,在这种情况下,处理程序失去其在表中的位置。这是当以下情况属实:

  • 任何会话执行FLUSH TABLES或DDL语句的处理程序表。

  • 会话的处理程序是公开执行非—HANDLER语句中使用表

TRUNCATE TABLE一桌桌,关闭了所有的程序HANDLER OPEN

如果一个表了FLUSH TABLES tbl_name WITH READ LOCK打开时处理程序处理程序是隐式的,满脸通红,失去了它的位置。

13.2.5进口表的语法

IMPORT TABLE FROM sdi_file [, sdi_file] ...

这个IMPORT TABLE声明进口MyISAM基于信息表中.sdi(序列化的字典信息)元数据文件。IMPORT TABLE要求FILE权限读取SDI和表的内容文件,和CREATE为表被创建的权限

表可以导出从一个服务器使用mysqldump写一个SQL语句的文件导入到另一个服务器使用MySQL处理转储文件IMPORT TABLE提供了一种更快的替代使用未经加工的表格文件

可以导入,文件提供的表格内容必须放在适当的架构目录导入服务器,和.sdi文件必须位于一个目录访问服务器。例如,在SDI文件可以放在目录的secure_file_priv系统变量,或(如果secure_file_priv是空的)服务器数据目录下的目录。

下面的示例说明如何出口MyISAM表命名员工managersHR一个服务器模式和导入hr另一个服务器架构。该示例使用这些假设(在你自己的系统,执行类似的操作,适当修改路径名称):

  • 用于导出服务器,export_basedir代表其基本目录和数据目录,export_basedir/日期

  • 对于导入服务器,import_basedir代表其基本目录和数据目录,import_basedir/日期

  • 表格文件导出导出服务器进/tmp/export目录,这个目录是安全的(不可访问其他用户)。

  • 导入服务器使用/tmp/mysql-files由于目录命名的secure_file_priv系统变量

从导出服务器导出表,使用这个程序:

  1. 通过执行此语句锁定表让他们无法修改导出过程中确保一致的快照:

    mysql> FLUSH TABLES hr.employees, hr.managers WITH READ LOCK;
    

    而锁是在效果上,表仍然可以使用,但只有读的权限。

  2. 在文件系统层,复制.sdi从表的内容文件HR架构目录的安全出口目录:

    • 这个.sdi文件位于HR架构目录,但不可能有完全相同的基名称的表名称。例如,在.sdi文件的员工managers表可能被命名为员工_ 125.sdimanagers_238.sdi

    • 对于一个MyISAM表的内容文件的MVD数据文件.MYI索引文件

    鉴于这些文件名,复制命令看起来像这样:

    shell> cd export_basedir/data/hr
    shell> cp employees_125.sdi /tmp/export
    shell> cp managers_238.sdi /tmp/export
    shell> cp employees.{MYD,MYI} /tmp/export
    shell> cp managers.{MYD,MYI} /tmp/export
    
  3. 打开表:

    mysql> UNLOCK TABLES;
    

进口表导入服务器,使用此程序:

  1. 进口模式必须存在。如果有必要,执行该语句创建它:

    mysql> CREATE SCHEMA hr;
    
  2. 在文件系统层,复制.sdi文件导入服务器secure_file_priv目录,/甲氧苄啶/ MySQL文件。另外,复制表的内容文件的hr架构目录:

    内核&#62;cd /tmp/export内核&#62;cp employees_125.sdi /tmp/mysql-files内核&#62;cp managers_238.sdi /tmp/mysql-files内核&#62;cp employees.{MYD,MYI} import_basedir/data/hr内核&#62;cp managers.{MYD,MYI} import_basedir/data/hr
  3. 进口表执行IMPORT TABLE声明的名字SDI文件

    mysql> IMPORT TABLE FROM
           '/tmp/mysql-files/employees.sdi',
           '/tmp/mysql-files/managers.sdi';
    

这个.sdi文件不需要被放置在导入服务器目录命名的secure_file_priv系统变量如果变量是空的;它可以在任何目录访问的服务器,包括进口表架构目录。如果SDI文件放置在该目录中,然而,它可能被改写;导入操作将创建一个新的.sdi为表文件,这将覆盖旧的SDI文件如果操作使用新的文件相同的文件名。

每个sdi_file值必须是一个字符串,名字SDI一个表或文件是一个模式匹配.sdi文件如果字符串是一个模式,任何领先的目录路径和SDI文件名的后缀必须是字面上的。模式特征只有在文件名的基名称部分允许:

  • ?匹配任何单个字符

  • *匹配任何字符序列,包括任何字符

使用模式,以前的IMPORT TABLE声明可能是这样写的(假设/甲氧苄啶/ MySQL文件目录不包含其他.sdi模式匹配的文件):

进口表/甲氧苄啶/ MySQL文件/ * SDI”;

解释的位置.sdi文件的路径名,服务器使用相同的规则IMPORT TABLE由于服务器端的规则LOAD DATA(即非—当地规则)。这第13.2.7、“LOAD DATA INFILE语法”,尤其要注意使用相对路径名的规则解释。

IMPORT TABLE没有如果SDI或表文件无法找到。导入后的表,服务器试图打开它的报告警告,任何发现的问题。尝试修复纠正任何报告的问题,使用REPAIR TABLE

IMPORT TABLE不写入二进制日志

限制的贡献与局限

IMPORT TABLE仅适用于非—临时MyISAM表它不适用于事务性存储引擎创建的表,表的创建CREATE TEMPORARY TABLE,或观点

表的数据和索引文件必须放在架构目录的进口服务器导入操作之前,除非表导出服务器上定义的使用DATA DIRECTORY索引目录表选项。在这种情况下,修改导入程序使用这些方案在执行之前IMPORT TABLE声明:

  • 把数据和索引文件到同一目录在导入服务器主机上的出口服务器主机,并在导入服务器架构目录创建符号链接的文件。

  • 把数据和索引文件到导入服务器主机目录不同,导出服务器上的主机,并在导入服务器架构目录创建符号链接的文件。此外,修改.sdi文件以反映不同的文件位置。

  • 把数据和索引文件的架构目录在导入服务器主机,并修改.sdi文件删除的数据和目录索引表选项。

任何可存储在IDS collation.sdi文件必须是相同的排序规则对出口和进口的服务器。

一个表的信息触发不序列化为表.sdi文件,所以触发器不通过进口手术恢复。

一些编辑的.sdi文件允许之前执行IMPORT TABLE声明,而其他人有问题,甚至可能导致进口操作失败:

  • 改变数据目录和索引目录表选项是必需的:如果数据和索引文件的位置不同的导出和导入服务器。

  • 改变模式名称需要导入表到导入服务器不同的架构比导出服务器上。

  • 改变架构和表名称可能需要适应不同的文件系统的情况下灵敏度语义之间的出口和进口的服务器或差异lower_case_table_names设置改变中的表名SDI文件可能需要重命名的表文件以及。

  • 在某些情况下,允许更改列定义。改变数据类型可能导致问题。

13.2.6插入语法

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    {VALUES | VALUE} (value_list) [, (value_list)] ...
    [ON DUPLICATE KEY UPDATE assignment_list]

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    SET assignment_list
    [ON DUPLICATE KEY UPDATE assignment_list]

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    SELECT ...
    [ON DUPLICATE KEY UPDATE assignment_list]

value:
    {expr | DEFAULT}

value_list:
    value [, value] ...

assignment:
    col_name = value

assignment_list:
    assignment [, assignment] ...

INSERT到现有的表中插入新行。这个INSERT ... VALUESINSERT ... SET基于显式指定值的语句插入行的形式。这个INSERT ... SELECT从另一个表或表选择表格插入行。INSERT一个在重复的密钥更新条款使现有的行被更新,如果某一行被插入会导致在一个重复的值UNIQUE指数或主键

有关更多信息INSERT ... SELECTINSERT ... ON DUPLICATE KEY UPDATE,看到第13.2.6.1,插入…选择“语法”,和第13.2.6.2,插入…在重复的密钥更新语法”

在MySQL 8的DELAYED关键词是接受但忽略的服务器。因为这个原因,看到第13.2.6.3,“延迟插入语法”

插入表格要求INSERT特权的表。如果在重复的密钥更新条款的使用和复制钥匙的原因UPDATE要执行相反,声明要求UPDATE特权将被更新的列。为列,读取但不能修改你需要的仅仅是SELECT特权(如引用的列在一个右手边col_name=expr分配在一个在重复的密钥更新条款)

当插入一个分区表,你可以控制它的分区和子分区接受新的行。这个PARTITION选项列表的逗号分隔的一个或多个分区和子分区的名称(或两者)的表。如果有任何的行是由一个给定的插入INSERT声明不匹配,其中一个分区的上市,INSERT语句失败与错误发现一行不匹配给定的分区设置。更多的信息和例子,看第22,“分区选择”

你可以使用REPLACE而不是INSERT覆盖旧行REPLACE是对手INSERT IGNORE在新的行,包含独特的核心价值,重复旧行治疗:新行替换旧行而不是被丢弃。看到第13.2.9,”代替语法”

tbl_name是表,行应插入。指定的声明提供了如下的列值:

  • 提供一个逗号分隔的列名称后括号中列出的表名。在这种情况下,每个命名列的值必须由VALUES列表或SELECT声明

  • 如果你不指定列表的列名称INSERT ... VALUESINSERT ... SELECT,为表中的所有列的值必须是由价值观列表或SELECT声明。如果你不知道表中列的顺序,使用描述tbl_name找出

  • SET子句指示明确列的名字,连同价值分配每一个。

列的值可以在几个方面考虑:

  • 如果严格的SQL模式不启用任何列没有明确给出一个值设置为其默认值(显式或隐式)。例如,如果你指定的列的列表,不在表中的所有列的名称,命名的列设置为它们的默认值。默认值分配的描述11.7节,“数据类型的默认值”。参见第而,“约束无效数据”

    如果严格的SQL模式开启,一INSERT如果不指定每列没有默认值的显式值语句产生一个错误。看到第5.1.10,”服务器的SQL模式”

  • 如果两列清单和VALUES列表是空的,INSERT创建每列设置为其默认值的行:

    插入tbl_name(一)values();

    如果没有启用严格模式,MySQL使用的任何列,没有明确定义的默认的隐式的默认值。如果严格模式已启用,如果任何列没有默认值时发生错误。

  • 使用关键字DEFAULT设定一个明确列为默认值。这使得它更容易写INSERT语句,赋值给几乎所有的列,因为它可以使你避免写不完整价值观列表,不包括在表中的每一列的值。否则,您必须提供列名对应的每个值的列表VALUES列表

  • 如果生成的柱插入明确,唯一被允许的值DEFAULT。有关生成的列的信息,参见第13.1.18.8,“创建表和生成的列”

  • 在表达式中,可以使用DEFAULT(col_name)产生的列的默认值col_name

  • 一个表达式的类型转换expr这提供了一个列的值,如果表达式的数据类型的列的数据类型不匹配的发生。一个给定的值的转换可以导致不同的插入值取决于柱型。例如,插入字符串“1999.0e 2”为一个INTFLOATDECIMAL(10,6),或YEAR列插入的值一千九百九十九19.9921十九点九九二一零零,或1999很好The value sttored in theINTYEAR一千九百九十九因为转换为数字的字符串看起来只是在尽可能多的字符串的起始部分可能被认为是一种有效的整数或一年。对于FLOATDECIMAL柱,转换为数字的字符串将整个字符串有效数值。

  • 一个表达式expr可以参考任何一列,设置在值列表前面。例如,你可以这样做,因为值COL2是指col1,以前被分配的:

    插入tbl_name(COL1,COL2)值(15、2×2);

    但以下是不合法的,因为价值col1是指COL2被分配后,col1

    插入tbl_name(COL1,COL2)值(COL2 * 2,15);

    发生异常的列包含AUTO_INCREMENT价值观。因为汽车价值观是价值分配后产生的,任何涉及AUTO_INCREMENT在分配列返回

INSERT语句中使用价值观语法可以插入多行。要做到这一点,包括逗号分隔列值的多个列表,封闭在括号内,以逗号分隔的列表。例子:

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);

每个值列表必须包含的值将被插入行。因为它包含一个列表9值以下声明是无效的,而不是3表3值每:

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3,4,5,6,7,8,9);

VALUE是同义词价值观在这样的背景下。既不意味着对值列表的数量的话,也没有关于价值每数列表。或者可以用是否有一个单一的值的列表或多个列表,每个列表的值,不论数量。

受影响的行的值为INSERT可以通过使用ROW_COUNT()SQL函数或mysql_affected_rows()C API函数。看到12.14节,“信息功能”,和第27.7.7.1,“mysql_affected_rows()”

如果你使用一个INSERT ... VALUES具有多个值的列表或表INSERT ... SELECT,该语句将返回该格式的信息串:

唱片N1重复:N2警告:N3

如果你使用C API的信息字符串,可以通过调用mysql_info()功能。看到第27.7.7.36,MySQL _信息()”

Records表示由语句处理的行数。(这是不一定的行数,因为实际上插入重复可以为零。)Duplicates指示行不能插入因为他们会重复存在的唯一索引值的个数。警告表明试图插入列的值,在某些方面有问题的数量。警告可以在下列条件下发生的:

  • 插入NULL成列,已申报不为空。多行INSERT陈述或INSERT INTO ... SELECT报表的列设置为列的数据类型的隐式的默认值。这是对于数值类型,空字符串('')为字符串类型,和日期和时间值的类型INSERT INTO ... SELECT报表的处理方式相同,多行插入因为服务器不检查的结果SELECT看它是否返回一个单排。(单排INSERT没有警告无效的插入NOT NULL专栏相反,该语句将失败与错误。)

  • 设置一个数字列的值的列的范围之外。价值是夹到接近终点的范围。

  • 指定一个值,如'10.34 a'一个数字列。后面的数字文本剥离和插剩下的数字部分。如果字符串值没有领先的数字部分,栏目设置

  • 插入一个字符串到字符串列(CHARVARCHARTEXT,或BLOB),超过该列的最大长度。价值是截断的列的最大长度。

  • 插入一个值为日期或时间列的数据类型是非法的。栏目设置为适当的值为零的类型。

  • INSERT例子包括自_ incremet列值,见第3,“用auto_increment”

    如果INSERT将行插入到表中,有一个汽车柱,你能找到的值用于柱用LAST_INSERT_ID()SQL函数或mysql_insert_id()C API函数

    笔记

    这两个函数的行为并不总是相同的。的行为INSERT有关报表汽车柱的进一步讨论12.14节,“信息功能”,和第27.7.7.38,“mysql_insert_id()”

这个INSERT声明支持下列修饰符:

  • 如果你使用LOW_PRIORITY修改,执行INSERT被延迟直到没有其他客户端读取表。这包括其他的客户,而现有客户开始阅读是阅读,而插入low_priority语句等待。这是可能的,因此,对客户的问题INSERT LOW_PRIORITY声明要等待很长的时间。

    LOW_PRIORITY只影响存储引擎只使用表级锁(如MyISAMMEMORY,和合并

    笔记

    LOW_PRIORITY一般不应使用MyISAM因为这样做将禁用并行插入表。看到第8.11.3,并发插入”

  • 如果你指定HIGH_PRIORITY,它覆盖的影响--low-priority-updates如果服务器启动选项,选项。这也导致并发插入不能使用。看到第8.11.3,并发插入”

    HIGH_PRIORITY只影响存储引擎只使用表级锁(如MyISAMMEMORY,和合并

  • 如果你使用IGNORE改性剂,发生的错误,在执行INSERT语句被忽略。例如,没有忽略,连续重复已有的UNIQUE指数或主键表中的值导致重复键错误和语句中止。与IGNORE,行丢弃,没有错误发生。忽略错误而产生的警告。

    IGNORE在插入一个类似的效果,为分区表没有匹配一个给定值的分区被发现。没有忽略,这样的INSERT语句中止错误。什么时候INSERT IGNORE使用时,插入操作失败,默默的为含有价值无与伦比的行,但插入行相配合。例如,看22.2.2节,“列表分区”

    这将引发错误终止声明如果数据转换IGNORE没有指定。与忽略,无效值调整到最接近的值和插入;警告产生但声明不放弃。你能确定的mysql_info()C API函数实际上是多少行插入表。

    有关更多信息,参见在忽略关键词和严格的SQL模式比较

  • 如果你指定ON DUPLICATE KEY UPDATE,并插入一行,将导致在一个重复的值独特指数或PRIMARY KEY,一个UPDATE旧行的发生。受影响的行的值是1如果每行的行插入新的一行,2如果现有的行被更新,0如果一个现有的行设置为其当前值。如果您指定的client_found_rows国旗的mysql_real_connect()When Connecting to C API函数mysqld,受影响的行的值为1(而不是0)如果一个现有的行设置为其当前值。看到第13.2.6.2,插入…在重复的密钥更新语法”

  • INSERT DELAYED在MySQL 5.6否决,并计划最终清除。在MySQL 8的延迟改性剂被忽视。使用INSERT(无延迟)代替。看到第13.2.6.3,“延迟插入语法”

一个INSERT影响分区表使用的存储引擎,如语句MyISAM使用表级锁的分区,实际上是插入行。(存储引擎等InnoDB使用行级锁,没有锁定的分区发生。)的更多信息,参见分区和锁定

13.2.6.1插入…选择语法

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    SELECT ...
    [ON DUPLICATE KEY UPDATE assignment_list]

value:
    {expr | DEFAULT}

assignment:
    col_name = value

assignment_list:
    assignment [, assignment] ...

INSERT ... SELECT,你可以快速插入多行插入到表中的一个结果SELECT声明,这可以从一个或多个表中选择。例如:

插入tbl_temp2(fld_id)选择从哪里tbl_temp1.fld_order_id tbl_temp1 tbl_temp1.fld_order_id &#62; 100;

for the following条件……INSERT ... SELECT声明:

  • 指定IGNORE忽略行,会造成重复重点违法行为。

  • 的目标表INSERT声明可以出现在的条款SELECT查询的一部分。然而,你不能插入一个表格,选择来自同一个表中查询。

    当选择和插入同一个表,MySQL创建持有从行内部临时表SELECT然后插入到目标表中的行。但是,您不能使用插入T…选择从T什么时候t是一个临时表,因为TEMPORARY表不能被称为同一语句在两次。看到第8.4.4,“MySQL”使用内部临时表,和第b.5.6.2,“临时表”问题

  • AUTO_INCREMENT列如往常一样工作

  • 确保二进制日志可用于重新创建原始表,MySQL不允许并发插入INSERT ... SELECT报表(见第8.11.3,并发插入”

  • 为了避免歧义字段引用的问题时SELECTINSERT引用同一个表,提供了一个独特的别名为每个表中使用SELECT部分和限定列名在部分别名。

你可以明确选择的分区或子分区(或两者)的源或目标表(或两者)都要使用一个PARTITION选择表格的名称。当分区在与源表名称SELECT声明的部分,行从分区或子分区的分区列表中指定唯一的选择。什么时候分区使用目标表的名称为INSERT声明的部分,它必须能够将入选的分区或子分区在分区列表中指定以下选项的所有行。否则,该插入…选择语句失败。更多的信息和例子,看第22,“分区选择”

INSERT ... SELECT报表,看第13.2.6.2,插入…在重复的密钥更新语法”为条件下的条件SELECT列可以被称为一个在重复的密钥更新条款.

的顺序SELECT声明没有顺序子句返回的行是不确定的。这意味着,使用复制的时候,有没有保证,这样的SELECT在相同的顺序返回行的主人与奴隶之间的不一致,从而导致他们。为了防止这种情况发生,总是写插入…选择声明是被重复使用ORDER BY条款,对主人和奴隶一样的命令行。参见第17.4.1.18,“复制和限制”

由于这个问题,INSERT ... SELECT ON DUPLICATE KEY UPDATEINSERT IGNORE ... SELECT声明标记为不安全的基于语句的复制。这些陈述产生在错误日志中的警告时,使用声明模式和写入使用基于行的格式时,使用二进制日志混合的模式。(错误# 11758262,错误# 50439)

参见第17.2.1.1,”优势和基础,基于行的复制”语句的缺点

一个INSERT ... SELECT声明影响分区表使用的存储引擎,如MyISAM使用表级锁的所有分区的目标表;然而,只有那些分区,实际上是从源表的读锁。(这不使用存储引擎如表发生InnoDB使用行级锁。)的更多信息,参见分区和锁定

13.2.6.2插入…在重复的密钥更新语法

如果你指定一个ON DUPLICATE KEY UPDATE条款和一排被插入会导致在一个重复的值独特指数或PRIMARY KEY,一个UPDATE旧行的发生。例如,如果柱声明为UNIQUE和蕴含的价值,下面两个语句也有类似的效果:

INSERT INTO t1 (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=c+1;

UPDATE t1 SET c=c+1 WHERE a=1;

(效果是不相同的InnoDB表在哪里是一个自动递增列。一个自动递增列,一INSERT声明中增加自动递增价值更新不。)

如果柱b也是独特的,INSERT这是一样的UPDATE语句:

UPDATE t1 SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;

如果a=1 OR b=2配几行,只行被更新。一般来说,你应该避免使用ON DUPLICATE KEY UPDATE对具有多个唯一索引的表款。

ON DUPLICATE KEY UPDATE受影响的行的值,每行1如果行插入为一个新的行,2如果现有的行被更新,0如果一个现有的行设置为其当前值。如果您指定的client_found_rows国旗的mysql_real_connect()Capital when Conflicting tomysqld,受影响的行的值为1(而不是0)如果一个现有的行设置为其当前值。

如果一个表包含一个AUTO_INCREMENTINSERT ... ON DUPLICATE KEY UPDATE插入或更新的行,LAST_INSERT_ID()函数返回汽车价值

这个ON DUPLICATE KEY UPDATE子句可以包含多个列的作业,以逗号分隔。

在赋值表达式中ON DUPLICATE KEY UPDATE条款,您可以使用VALUES(col_name)功能是指从列值INSERT部分的INSERT ... ON DUPLICATE KEY UPDATE声明。换句话说,VALUES(col_name)在重复的密钥更新条款是指价值col_name将插入,没有重复键发生冲突。此功能是特别有用的多行插入。这个VALUES()函数只有在有意义的在重复的密钥更新条款或INSERT语句并返回无效的另有。实例:

INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6)
  ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);

这句话是下面两个语句相同:

INSERT INTO t1 (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE c=3;
INSERT INTO t1 (a,b,c) VALUES (4,5,6)
  ON DUPLICATE KEY UPDATE c=9;

INSERT ... SELECT报表,这些规则就可以接受的形式选择查询表达式,你可以参考一ON DUPLICATE KEY UPDATE条款:

  • 引用列在一个表的查询,这可能是一个派生表。

  • 从多个表的连接查询的列引用。

  • 引用列DISTINCT查询

  • 其他表中的列引用,只要SELECT不使用。一个副作用是,你必须有唯一的名称引用。

从列引用UNION不支持。要解决此限制,改写UNION作为一个派生表,其行可被视为一个单一的表结果集。例如,该语句产生一个错误:

INSERT INTO t1 (a, b)  SELECT c, d FROM t2  UNION  SELECT e, f FROM t3ON DUPLICATE KEY UPDATE b = b + c;

相反,用一个等效的语句改写UNION作为一个派生表:

INSERT INTO t1 (a, b)SELECT * FROM  (SELECT c, d FROM t2   UNION   SELECT e, f FROM t3) AS dtON DUPLICATE KEY UPDATE b = b + c;

重写查询作为一个派生表的技术也使引用的列GROUP BY查询

因为结果INSERT ... SELECT陈述取决于行的排序SELECT这个命令不能总是得到保证,可以登录时INSERT ... SELECT ON DUPLICATE KEY UPDATE对于不同的主从报表。因此,INSERT ... SELECT ON DUPLICATE KEY UPDATE声明标记为不安全的基于语句的复制。这些陈述产生在错误日志中的警告时,使用声明模式和写入使用基于行的格式时,使用二进制日志混合的模式。一个INSERT ... ON DUPLICATE KEY UPDATE声明对一个表有一个以上的唯一或主键也标记为不安全。(错误# 11765650,错误# 58637)

参见第17.2.1.1,”优势和基础,基于行的复制”语句的缺点

一个INSERT ... ON DUPLICATE KEY UPDATE使用存储引擎,如分区表MyISAM使用表级锁的任何分区表中的分区键列的更新。(这不使用存储引擎如表发生InnoDB使用行级锁。)的更多信息,参见分区和锁定

13.2.6.3延迟插入语法

INSERT DELAYED ...

这个DELAYED选择的INSERT声明是一个mysql扩展标准的SQL。MySQL的在以前的版本中,它可以用于某些类型(如表MyISAM当一个客户端)使用搜索INSERT DELAYED同时,从服务器获取一个好的,和排排队要插入表时没有使用任何其他线程。

DELAYED插入替换在MySQL 5.6否决。在MySQL 5.0,延迟不支持。服务器认识而忽视DELAYED关键词,把手插入一个非插入,并生成一个er_warn_legacy_syntax_converted警告(插入延迟不再支持。声明转换为插入页:1的DELAYED关键词计划在未来的版本中去除。

13.2.7 LOAD DATA INFILE语法

LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
    [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [CHARACTER SET charset_name]
    [{FIELDS | COLUMNS}
        [TERMINATED BY 'string']
        [[OPTIONALLY] ENCLOSED BY 'char']
        [ESCAPED BY 'char']
    ]
    [LINES
        [STARTING BY 'string']
        [TERMINATED BY 'string']
    ]
    [IGNORE number {LINES | ROWS}]
    [(col_name_or_user_var
        [, col_name_or_user_var] ...)]
    [SET col_name={expr | DEFAULT},
        [, col_name={expr | DEFAULT}] ...]

这个LOAD DATA INFILE声明全文行从文本文件到表中以很高的速度。LOAD DATA INFILE是补充SELECT ... INTO OUTFILE。。。。。。。(这第13.2.10.1,“选择…为语法”。)从表到一个文件中写入数据,使用SELECT ... INTO OUTFILE。读取文件回表,使用LOAD DATA INFILE。的语法领域LINES条款是语句相同。两子句是可选的,但领域必须先LINES如果都是指定的

你也可以加载数据文件的使用mysqlimport效用;它通过发送一个LOAD DATA INFILE报表服务器。这个--local选择的原因mysqlimport从客户端读取数据文件。你可以指定--compress选择获得过慢的网络更好的性能,如果客户端和服务器支持压缩协议。看到4.5.5“,”mysqlimport-数据导入程序”

关于效率的更多信息INSERT对比LOAD DATA INFILE加快LOAD DATA INFILE,看到第8.2.5.1,“优化INSERT语句”

文件名必须给出一个字符串。在Windows中,指定路径名为反斜杠斜杠或反斜杠加倍。这个character_set_filesystem系统变量控制文件名称的解释。

LOAD DATA支持显式分区选择使用分区一个或多个用逗号分隔的名称分区,子分区选项,或两者。使用此选项时,如果文件不能任何行被插入到任何分区和子分区列表中的命名,该语句将失败与错误发现一行不匹配给定的分区设置。更多的信息和例子,看第22,“分区选择”

对于分区使用存储引擎使用表锁表,如MyISAM加载数据无法修剪任何分区锁。这不适用于使用存储引擎使用行级锁的表,如InnoDB。有关更多信息,参见分区和锁定

服务器使用的字符集表示的character_set_database系统变量在解释文件的信息。SET NAMES和设置character_set_client不影响理解的输入。如果输入文件的内容使用的字符集,不同于默认值,通常指定字符集的文件用字符集条款.一个字符集binary指定没有转换

LOAD DATA INFILE将文件中的所有字段具有相同的字符集,不管数据类型的列的字段的值被加载。对文件内容的正确解释,你必须确保它写得正确的字符集。例如,如果你写一个数据文件mysqldump T或通过发行SELECT ... INTO OUTFILE声明MySQL,一定要用--default-character-set选项,输出是用字符集时要用到的文件加载LOAD DATA INFILE

笔记

这是不可能的荷载数据文件,使用ucs2UTF16utf16le,或utf32字符集

如果你使用LOW_PRIORITY,执行的LOAD DATA声明推迟到其他客户端无法读取表。这仅影响存储引擎只使用表级锁(如MyISAMMEMORY,和合并

如果你指定CONCURRENT用一个MyISAM表满足并发插入的条件(即,它包含在中间没有空闲块),其他线程可以检索数据从表而LOAD DATA执行。这个选项会影响性能LOAD DATA一点,即使没有其他的线程是在同一时间使用表。

与基于行的复制,CONCURRENT无论是复制MySQL版本。与基于语句的复制同时发生的不会复制到MySQL 5.5.1之前(见虫# 34628)。有关更多信息,参见第17.4.1.19,“复制和加载数据文件”

这个LOCAL关键词影响的预期位置的文件和错误处理,为后面介绍。当地只如果您的服务器和客户端都配置为允许。例如,如果mysqld开始的local_infile系统变残疾,当地不工作。看到第6.1.6,“负荷数据的本地“安全问题

这个LOCAL关键词会影响文件有望被发现:

  • 如果LOCAL指定的文件是由客户端主机客户端程序读取和发送到服务器。该文件可以作为一个完整的路径名来指定它的确切位置。如果给出一个相对路径名,该名称被解释为相对于目录,客户端程序启动。

    当使用LOCALLOAD DATA,一份文件是在服务器的临时目录中创建。这是由价值确定的目录tmpdirslave_load_tmpdir,而操作系统的临时目录,并在MySQL服务器没有配置。(通常是系统临时目录/tmp在Linux系统和C:\WINDOWS\TEMP在Windows上。)在这个目录下复制缺乏足够的空间,可以使LOAD DATA LOCAL语句失败

  • 如果LOCAL没有指定,文件必须位于服务器主机,由服务器直接读取。服务器使用以下规则来查找文件:

    • 如果文件名是一个绝对路径名,服务器使用它了。

    • 如果文件名是与一个或多个主要部件的相对路径名,该文件相对于服务器的数据目录服务器搜索。

    • 如果一个文件没有主导成分名字,服务器中查找默认数据库的数据库目录的文件。

在非LOCAL的情况下,这些规则意味着一个文件命名为MyilFile TXT从服务器的数据目录中读取,而文件命名为myfile.txt从默认的数据库的数据库目录读取。例如,如果DB1是默认的数据库,如下LOAD DATA语句读取文件“data.txt”从数据库目录db1,尽管声明明确文件加载到一个表中db2数据库:

LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;
笔记

服务器也使用非—LOCAL规则定位SDI文件的IMPORT TABLE声明

非—LOCAL加载操作读取文本文件位于服务器上的。出于安全原因,这样的操作要求你有FILE特权。看到6.2.1节”,privileges提供由mysql”。。。。。。。因此,非LOCAL负荷运作受制于secure_file_priv系统变量设置。如果变量的值是一个非空的目录名,文件被加载必须位于该目录。如果变量的值是空的(这是不安全的),文件只需要通过服务器是可读的。

使用LOCAL是不是让服务器访问的文件直接慢一点,因为文件的内容必须在连接的客户端向服务器发送。另一方面,你不需要FILE加载本地文件的权限

LOCAL也影响错误处理:

  • LOAD DATA INFILE,数据解释和重复键错误终止操作。

  • LOAD DATA LOCAL INFILE,数据解释和重复键错误成为警告和操作继续,因为服务器没有办法阻止在操作中的文件传输。重复键错误,这好像是一样的忽略指定IGNORE进一步说明在本节的后面。

这个REPLACE忽略关键词控制处理输入行复制现有行独特的核心价值观:

  • 如果你指定REPLACE,输入行替换现有的行。换句话说,有一个主键或唯一索引相同的值作为一个现有的行行。看到第13.2.9,”代替语法”

  • 如果你指定IGNORE复制现有的排,排在一个独特的核心价值被丢弃。有关更多信息,参见在忽略关键词和严格的SQL模式比较

  • 如果你不指定选项,该行为取决于LOCAL一个指定的关键字。没有当地一个错误发生时,重复键值的发现,和文本文件的其余部分被忽略。与LOCAL,默认行为是一样忽略是指定的;这是因为服务器没有办法阻止在操作中的文件传输。

忽略外键约束加载操作过程中,问题SET foreign_key_checks = 0语句之前执行LOAD DATA

如果你使用LOAD DATA INFILE在一个空的MyISAM表,所有非唯一索引是一个单独的批处理创建(如REPAIR TABLE)。通常,这使得LOAD DATA INFILE当你有很多指标更快。在一些极端的情况下,你甚至可以更快的把他们从创建索引修改表…禁用按键在加载文件到表和使用ALTER TABLE ... ENABLE KEYS重新创建索引后加载的文件。看到第8.2.5.1,“优化INSERT语句”

LOAD DATA INFILESELECT ... INTO OUTFILE语句的语法领域LINES条款是相同的。两子句是可选的,但领域必须先LINES如果都是指定的

如果你指定一个FIELDS条款,它的每一小节(终止[OPTIONALLY] ENCLOSED BY,和逃跑了)也是可选的,但你必须指定至少一个。这些条款的争论可以只包含ASCII字符。

如果你不指定FIELDS线子句,默认是相同的如果你写了这个:

FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
LINES TERMINATED BY '\n' STARTING BY ''

(反斜杠转义字符在字符串中的MySQL的SQL语句,所以指定转义符,您必须指定被解释为一个反斜杠的价值两个反斜杠。转义序列'\t'&#39;\n&#39;指定制表符和换行符,分别。)

换句话说,违约的原因LOAD DATA INFILE作为如下阅读输入时:

  • 寻找在换行线

  • 不要跳过任何一行的前缀。

  • 断裂线成字段标签

  • 不要指望在任何领域被引用字符。

  • 解读人物之前的转义字符\作为转义序列。例如,t\n,和表示制表符,换行符和回车,分别。见的讨论FIELDS ESCAPED BY后来的转义序列的完整列表。

相反,违约的原因SELECT ... INTO OUTFILE作为如下写作输出时:

  • 写标签字段之间

  • 没有附上任何引用领域内的人物。

  • 使用\逃避的制表符,换行符,或\在字段值发生

  • 在线路两端写换行

笔记

如果你已经产生了在Windows系统下的文本文件,您可能需要使用LINES TERMINATED BY '\r\n'正确地读取文件,因为Windows程序通常使用两个字符作为行结束符。一些程序,如写字板,可以使用\r当写作作为一个线文件的终结者。搜索文件的读写,使用线终止“R”

如果所有的线,你想读的都有一个共同的前缀,你想忽略,您可以使用LINES STARTING BY 'prefix_string'跳过的前缀,和任何在它之前。如果一行中不包含前缀,全线跳过。假设你发表如下声明:

LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test
  FIELDS TERMINATED BY ','  LINES STARTING BY 'xxx';

如果数据文件看起来像这样:

xxx"abc",1
something xxx"def",2
"ghi",3

结果行将("abc",1)(“def”,2)。跳过,因为它不包含前缀是文件中的第三行。

这个IGNORE number LINES选项可以用来忽略线在文件的开始。例如,您可以使用忽略1线跳过包含列名称最初的标题行:

LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test IGNORE 1 LINES;

当你使用SELECT ... INTO OUTFILE随着LOAD DATA INFILE从数据库到一个文件中写入数据,然后读取文件到数据库后,现场和线处理语句选项必须匹配。否则,LOAD DATA INFILE不解释文件的内容正确。假设你使用SELECT ... INTO OUTFILE与由逗号分隔字段写入一个文件:

SELECT *为文件数据.txt”字段终止符&#39;,&#39;从表2;

读取逗号分隔的文件,正确的说法是:

LOAD DATA INFILE 'data.txt' INTO TABLE table2
  FIELDS TERMINATED BY ',';

如果你想在表下面的文件读取,它不会工作,因为它指示LOAD DATA INFILE寻找标签字段之间:

LOAD DATA INFILE数据.txt”为表表字段终止符&#39;\t&#39;;

可能的结果是,每行输入将被解释为一个单一的领域。

LOAD DATA INFILE可以用来读取从外部来源获得的文件。例如,许多程序可以在逗号分隔值(CSV)数据导出格式,如系由逗号分隔和包围在双引号的领域,随着列名的初始线。如果在这样的文件中的行由回车/换行符对终止,这里显示的声明说明了场和线处理选项可以用于加载文件:

LOAD DATA INFILE数据.txt”为表tbl_name字段终止符&#39;,&#39;封闭&#39;“&#39;线终止“\r\n”忽略1线;

如果输入的值不一定包含在引号的使用OPTIONALLY之前封闭的关键词

任何字段或行处理选项可以指定一个空字符串('')。如果不是空的[可选]封闭的领域FIELDS ESCAPED BY值必须是一个字符。这个字段终止符LINES STARTING BY,和线端值可以是多个字符。例如,写的是由回车/换行对终止线,或读取包含这样的线文件,指定LINES TERMINATED BY '\r\n'条款.

读取包含笑话,是由线条组成的分隔的文件%%,你可以这样做

创建表的笑话(一个int不空auto_increment主键,笑话文本不为空);LOAD DATA INFILE /甲氧苄啶/笑话.txt”为表笑话字段终止符”系用终止\n \n’%%(开玩笑);

FIELDS [OPTIONALLY] ENCLOSED BY控件的引用字段。输出(SELECT ... INTO OUTFILE如果你omit Word)任选所有字段都是封闭的,ENCLOSED BY人物这种输出的一个例子(使用逗号作为字段分隔符)显示在这里:

“1”、“弦”、“100.20”、“2”、“字符串,逗号”,“102.20”“3”,“一个包含“报价”、“102.20”、“4”、“字符串”,引号和逗号“,”102.20“

如果你指定OPTIONALLY,的封闭的字符只用于附值,字符串数据类型的列(如CHARBINARYTEXT,或ENUM):

一、“字符串”,100.202,”字符串,用逗号“,”102.203,字符串“报价”,102.204,“字符串”,引号和逗号“,102.20

出现的ENCLOSED BY在一个领域的价值性与逃跑的前缀逃跑了人物另外,如果你指定一个空的ESCAPED BY值,它可能是无意中产生的输出不能正确读取的LOAD DATA INFILE。例如,前面的输出只会出现如下如果转义字符是空的。观察到在四线的第二字段包含一个逗号后的报价,这(错误地)出现终止场:

1、“字符串”,100.202,“一个包含,逗号“,102.203,”一个字符串包含一个“引用”,102.204,“字符串”,引号和逗号”,102.20

输入的ENCLOSED BY字符,如果存在,是从字段值的两端剥离。(不管这是真的任选指定;OPTIONALLY对输入的解释没有出现的效果。)封闭的之前的字符ESCAPED BY字符被解释为当前字段值的一部分。

如果这场始于ENCLOSED BY角色,这个角色是公认的终止一个字段的值只有跟着现场或线实例终止序列。为了避免歧义,出现的ENCLOSED BY在一场价值特征可以增加一倍,被解释为字符的一个实例。例如,如果封闭的”指定,引号是如下所示的处理:

"The ""BIG"" boss"  -> The "BIG" boss
The "BIG" boss      -> The "BIG" boss
The ""BIG"" boss    -> The ""BIG"" boss

FIELDS ESCAPED BY控制如何读或写的特殊字符:

  • 输入,如果FIELDS ESCAPED BY性格不是空的,这个角色被事件和下面的字符是从字面上理解为字段值的一部分。有两个字符序列,是例外,在那里的第一个字符是转义字符。这些序列如下表所示(用\用于转义字符)。规则NULL本节中描述的后处理

    人物转义序列
    \0一个ASCII字符(X'00')字符
    \b退格字符
    \n在newline(linefeed)字符
    \r一个回车符
    \t一个制表符
    \ZASCII码26(控制Z)
    \N无效的

    为更多的信息关于\语法-逃跑,这9.1.1节,“String Literals”

    如果FIELDS ESCAPED BY字符转义序列的解释是空的,不会发生。

  • 输出,如果FIELDS ESCAPED BY性格不是空的,它是用来前缀以下字符输出:

    • 这个FIELDS ESCAPED BY人物

    • 这个FIELDS [OPTIONALLY] ENCLOSED BY人物

    • 的第一个字符FIELDS TERMINATED BY线端价值观

    • ASCII码0(实际上是转义字符以下写的是ASCII,不是一个零值字节)

    如果FIELDS ESCAPED BY性是空的,没有人物都逃了出来,无效的输出为NULL,不\n。它不可能是指定一个空的转义字符是一个好主意,特别是如果你的数据字段值包含的任何角色只是提供的清单。

在某些情况下,磁场线处理选项的互动:

  • 如果LINES TERMINATED BY是一个空字符串和字段终止符非空,线也终止FIELDS TERMINATED BY

  • 如果FIELDS TERMINATED BY封闭的领域值都是空的(''),一个固定的行(未分隔)格式的使用。固定行格式,没有分隔符之间使用的领域(但你仍然可以有一行结束符)。相反,列值的读写使用的字段宽度足够宽,以保持在该领域的所有值。为TINYINTSMALLINTMEDIUMINTINT,和BIGINT,字段宽度为4, 6, 8,11,和20,分别,不管什么声明显示宽度。

    LINES TERMINATED BY还用于分隔线。如果一行不包含所有领域,其余的列设置为它们的默认值。如果你没有行结束符,你应该设置为&#39; &#39;。在这种情况下,文本文件必须包含每一行的所有字段。

    固定行格式也影响处理NULL值,为后面介绍

    笔记

    固定大小的格式不如果你使用的是多字节字符集工作。

处理NULL根据不同的价值观领域LINES选择使用:

  • 为默认FIELDS线价值观,NULL是作为一个字段的值\n输出,和一个字段的值\N读作无效的输入(假设ESCAPED BY字符\

  • 如果FIELDS ENCLOSED BY是不是空的,一场含有字面字无效的作为其价值被解读为NULL值。这differs from the word无效的封闭在FIELDS ENCLOSED BY字,这是阅读作为字符串“空”

  • 如果FIELDS ESCAPED BY是空的,无效的写的字NULL

  • 固定行格式(这是用来当FIELDS TERMINATED BY封闭的领域都是空的),NULL写的是一个空字符串。这会导致两个无效的表中的值和空字符串可当写入文件因为都写为空字符串。如果你需要能够分辨出两者在阅读的文件,你不应该使用固定的行格式。

试图加载NULL为一个不为空柱引起的隐式的默认值分配给该列的数据类型和一个警告,或者一个错误严格的SQL模式。隐式的默认值的讨论11.7节,“数据类型的默认值”

有些是不支持的LOAD DATA INFILE

  • 固定大小的行(FIELDS TERMINATED BY封闭的领域都是空的),BLOBTEXT专栏

  • 如果你指定一个分离器是相同的或前缀的另一个,LOAD DATA INFILE无法解释输入正确。例如,下面的领域条款会造成问题:

    FIELDS TERMINATED BY '"' ENCLOSED BY '"'
    
  • 如果FIELDS ESCAPED BY是空的,一个字段的值包含一个发生封闭的领域LINES TERMINATED BY其次是字段终止符值的原因LOAD DATA INFILE再看一个字段或行为时过早。这是因为LOAD DATA INFILE不能正确确定所在领域或线的价值目标。

下面的示例将所有列的persondata

Load into table的日期是persondata.txt infile是persondata;

默认情况下,当没有列列表末尾提供LOAD DATA INFILE语句,输入线预计将包含一个字段,每个表的列。如果你想负荷只有一些表的列,指定列的列表:

负荷数据是persondata.txt infile是into table(persondatacol_name_or_user_var【,col_name_or_user_var]…);

如果你必须在输入文件中的字段的顺序不同于表中的列顺序指定列的列表。否则,MySQL不能告诉如何输入字段与表列赛。

每个col_name_or_user_var值是一个列名称或用户变量。用户变量的配置条款可以执行转换他们的价值观在列分配结果。

在用户变量SET条款可以采用的几种方法。下面的示例使用第一个输入列的值直接t1.column1,将第二输入列用户变量,在使用之前的值进行除法运算t1.column2

LOAD DATA INFILE 'file.txt'  INTO TABLE t1  (column1, @var1)  SET column2 = @var1/100;

这个SET条款可以用来提供值不从输入文件。下面的语句集的位置为当前的日期和时间:

LOAD DATA INFILE 'file.txt'
  INTO TABLE t1
  (column1, column2)
  SET column3 = CURRENT_TIMESTAMP;

你也可以抛弃一个输入值分配给一个用户变量和未分配的变量表列:

LOAD DATA INFILE 'file.txt'
  INTO TABLE t1
  (column1, @dummy, column2, @dummy, column3);

利用柱/变量列表SET条款受以下限制:

  • 在做作业SET条款应该只有列名在赋值运算符的左边。

  • 你可以在右边使用子查询SET作业.子查询返回的值被分配到一个列可以是标量子查询只。同时,你不能使用子查询从表中被加载的选择。

  • 线被一个IGNORE条款不处理柱/变量列表或配置条款.

  • 用户变量不能用加载数据的固定格式行因为用户变量没有显示宽度时。

当处理一个输入行,LOAD DATA将其分为领域,根据柱/变量列表和使用价值配置条款,如果存在。然后得到的行插入表。如果有BEFORE INSERT插入后表的触发器,它们之前或插入行后激活,分别。

如果一个输入行中有太多的领域,额外的域被忽略和警告的数量递增。

如果一个输入行有太少的领域,而输入字段丢失的表列设置为它们的默认值。默认值分配的描述11.7节,“数据类型的默认值”

空字段值解释不同于缺场:

  • 对于字符串类型的列设置为空字符串。

  • 对于数值类型,栏目设置0

  • 日期和时间类型、栏目设置适当的价值的价值。见11.3节,“戴特时间类型”

这些是结果相同的价值观,如果你指定一个空字符串显式字符串、数字或日期或时间型明确的INSERTUPDATE声明

空的或不正确的字段值不同,描述的是如果SQL模式设置为限制值的处理。例如,如果sql_mode是集TRADITIONAL,一个空值或值的转换等“X”在一个错误的数值列的结果,而不是转换为0。(与LOCAL忽略警告出现,而不是错误,即使有限制sql_mode价值,与排插使用相同的亲密行为用于非限制性的SQL模式的价值。这是因为服务器没有办法阻止在操作中的文件传输。)

TIMESTAMP列设置为当前日期和时间,如果有一个无效的该列的值(即,\N)和列不申报许可证无效的Values,or if theTIMESTAMP列的默认值为当前时间戳,它是从字段列表略当字段列表中指定。

LOAD DATA INFILE把所有的输入字符串,所以你不能用数字值ENUMSET列的方式你可以INSERT声明.全部ENUMSET值必须被指定为字符串。

BIT值不能直接加载使用二进制表示法(例如,B 011010’。”)。为了解决这个问题,使用SET条款脱光领先B和尾'并进行2到10转换使MySQL负荷值为BIT列好:

内核&#62;cat /tmp/bit_test.txtB B是10 1111111内核&#62;mysql testMySQL的&#62;LOAD DATA INFILE '/tmp/bit_test.txt'INTO TABLE bit_test (@var1)SET b = CAST(CONV(MID(@var1, 3, LENGTH(@var1)-3), 2, 10) AS UNSIGNED);查询行,2行受影响(0秒)记录:2:0:0删除了警告:0mysql &#62;SELECT BIN(b+0) FROM bit_test;---------- |仓(B0)| ---------- |十| | 1111111 | ---------- 2行集(0.001秒)

BIT价值观0b二进制记数法(例如,0b011010),使用这配置条款反而脱光领先0b

SET b = CAST(CONV(MID(@var1, 3, LENGTH(@var1)-2), 2, 10) AS UNSIGNED)

在UNIX系统上,如果你需要LOAD DATA从管道读,你可以使用下面的方法(实例加载一个上市的/目录表db1.t1):

mkfifo /数据库/数据/ DB1 / ls.datchmod 666 /数据库/数据/ DB1 / ls.datfind / LS &#62; /数据库/数据/ DB1 / ls.dat和MySQL E“LOAD DATA INFILE的LS。DAT”为表T1“db1

在这里你必须运行命令生成数据加载和MySQL命令在不同的终端,或运行数据生成过程中的背景(如前面的例子所示)。如果你不这样做,该管道将阻塞直到数据读取的MySQL过程

LOAD DATA INFILE声明完毕,返回以下格式的信息串:

记录:1删除:0:0 0跳过警告:

警告发生相同的情况下,当值插入使用INSERT声明(见第13.2.6,“插入语法”),但这LOAD DATA INFILE也会产生警告,当有太少或者太多的行字段中输入。

你可以使用SHOW WARNINGS得到一个列表中的第一个max_error_count关于什么是错的警告信息。看到第13.7.6.40,“显示警告语法”

如果你使用的是C的API,你可以得到关于语句的信息通过调用mysql_info()功能。看到第27.7.7.36,MySQL _信息()”

13.2.8加载XML语法

LOAD XML [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
    [REPLACE | IGNORE]
    INTO TABLE [db_name.]tbl_name
    [CHARACTER SET charset_name]
    [ROWS IDENTIFIED BY '<tagname>']
    [IGNORE number {LINES | ROWS}]
    [(field_name_or_user_var
        [, field_name_or_user_var] ...)]
    [SET col_name={expr | DEFAULT},
        [, col_name={expr | DEFAULT}] ...]

这个LOAD XML语句从XML文件读取数据到表。这个file_name必须给出一个字符串。这个tagname在可选行经条款也必须给出一个字符串,并且必须被尖括号(<&#62;

LOAD XML作为补充的运行MySQL在XML输出模式的客户端(即启动客户端与--xml选项)。从表到XML文件中写入数据,你可以调用MySQL客户端与--xml-e从系统的shell选项,如下所示:

内核&#62;mysql --xml -e 'SELECT * FROM mydb.mytable' > file.xml

读取文件回表,使用LOAD XML INFILE。默认情况下,该<row>元素是一个数据库表的行中的等效;这是可以改变的ROWS IDENTIFIED BY条款.

这一声明支持三种不同的XML格式:

  • 列名和列值的属性和属性值:

    <row column1="value1" column2="value2" .../>
    
  • 列名和列值的标签,这些标签的内容:

    <row>
      <column1>value1</column1>
      <column2>value2</column2>
    </row>
    
  • 塔的名字是name属性<field>和值标签,这些标签的内容:

    <row>
      <field name='column1'>value1</field>
      <field name='column2'>value2</field>
    </row>
    

    这是由其他MySQL工具使用的格式,如mysqldump

三格式可以使用相同的XML文件;导入程序自动检测每一行的格式和解释是正确的。标签匹配基于标签或属性名和列名。

以下条款基本相同的方式工作LOAD XML他们做的LOAD DATA

  • LOW_PRIORITY同时发生的

  • LOCAL

  • REPLACE忽略

  • CHARACTER SET

  • SET

看到第13.2.7、“LOAD DATA INFILE语法”,关于这些条款的更多信息。

(field_name_or_user_var, ...)是一个或多个用逗号分隔的XML字段或用户变量。一个用于此目的的用户变量名必须从XML文件匹配字段的名称,以@。你可以使用字段名称只选择所需的字段。用户变量可以用来存储以后再利用相应的字段值。

这个IGNORE number LINES忽略number条款导致第一number在XML文件中的行被跳过。这是类似于LOAD DATA声明的忽略线条款.

假设我们有一个表名person,创建如下所示:

使用测试;创建一个表(person_id INT NOT NULL主键名varchar(40)空、varchar(40)零,模型创建时间戳);

进一步假设这张桌子是空的。

现在,假设我们有一个简单的XML文件person.xml,其内容如下所示:

<list>  <person person_id="1" fname="Kapek" lname="Sainnouine"/>  <person person_id="2" fname="Sajon" lname="Rondela"/>  <person person_id="3"><fname>Likame</fname><lname>?rrtmons</lname></person>  <person person_id="4"><fname>Slar</fname><lname>Manlanth</lname></person>  <person><field name="person_id">5</field><field name="fname">Stoma</field>    <field name="lname">Milu</field></person>  <person><field name="person_id">6</field><field name="fname">Nirtam</field>    <field name="lname">Skl?d</field></person>  <person person_id="7"><fname>Sungam</fname><lname>Dulb?d</lname></person>  <person person_id="8" fname="Sraref" lname="Encmelt"/></list>

每个XML格式允许先前讨论的这个例子中的文件表现。

进口数据person.xml进入表格,你可以使用这个语句:

mysql> LOAD XML LOCAL INFILE 'person.xml'
    ->   INTO TABLE person
    ->   ROWS IDENTIFIED BY '<person>';

Query OK, 8 rows affected (0.00 sec)
Records: 8  Deleted: 0  Skipped: 0  Warnings: 0

在这里,我们假设person.xml位于MySQL数据目录。如果无法找到文件,下列错误的结果:

错误二(hy000):文件/人。XML没有找到(errcode:2)

这个ROWS IDENTIFIED BY '<person>'条款意味着每个<person>在XML文件中的元素被认为是相当于一个表的行中的数据是要进口。在这种情况下,这是person表中测试数据库

可以通过从服务器的响应,8行导入test.person表这可以通过一个简单的验证SELECT声明:

MySQL的&#62;SELECT * FROM person;----------- -------- ------------ --------------------- | person_id |名| LName |创造| ----------- -------- ------------ --------------------- | 1 | kapek | sainnouine | 2007-07-13 16:18:47 | | 2 | sajon | rondela | 2007-07-13 16:18:47 | | 3 | likame |?rrtmons | 2007-07-13 16:18:47 | | 4 | SLAR | manlanth | 2007-07-13 16:18:47 | | 5 |气孔|尼鲁| 2007-07-13 16:18:47 | | 6 | nirtam | SKL?D | 2007-07-13 16:18:47 | | 7 | sungam | dulb?D | 2007-07-13 16:18:47 | | 8 | sreraf | encmelt | 2007-07-13 16:18:47 | ----------- -------- ------------ --------------------- 8行集(0秒)

这表明,正如在本节前面,任何或所有的3允许XML格式可能会出现在一个单一的文件和阅读使用LOAD XML

导入操作的只是表明反,倾销MySQL表数据转化为XML文件可以使用MySQL从系统的客户端,如下图所示:

shell> mysql --xml -e "SELECT * FROM test.person" > person-dump.xml
shell> cat person-dump.xml
<?xml version="1.0"?>

<resultset statement="SELECT * FROM test.person" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <row>
	<field name="person_id">1</field>
	<field name="fname">Kapek</field>
	<field name="lname">Sainnouine</field>
  </row>

  <row>
	<field name="person_id">2</field>
	<field name="fname">Sajon</field>
	<field name="lname">Rondela</field>
  </row>

  <row>
	<field name="person_id">3</field>
	<field name="fname">Likema</field>
	<field name="lname">?rrtmons</field>
  </row>

  <row>
	<field name="person_id">4</field>
	<field name="fname">Slar</field>
	<field name="lname">Manlanth</field>
  </row>

  <row>
	<field name="person_id">5</field>
	<field name="fname">Stoma</field>
	<field name="lname">Nilu</field>
  </row>

  <row>
	<field name="person_id">6</field>
	<field name="fname">Nirtam</field>
	<field name="lname">Skl?d</field>
  </row>

  <row>
	<field name="person_id">7</field>
	<field name="fname">Sungam</field>
	<field name="lname">Dulb?d</field>
  </row>

  <row>
	<field name="person_id">8</field>
	<field name="fname">Sreraf</field>
	<field name="lname">Encmelt</field>
  </row>
</resultset>
笔记

这个--xml选择的原因MySQL客户端使用XML格式的输出;-e选项使客户端执行的SQL语句后立即选择。看到4.5.1“,”MySQL- MySQL命令行工具”

您可以验证通过创建一个副本的转储是有效的person表和进口转储文件到新表,这样:

MySQL的&#62;USE test;MySQL的&#62;CREATE TABLE person2 LIKE person;查询好,为受影响的行(0.001秒)MySQL &#62;LOAD XML LOCAL INFILE 'person-dump.xml'-&#62;INTO TABLE person2;查询行,8行受影响(0.01秒)记录:8:0:0删除了警告:0mysql &#62;SELECT * FROM person2;----------- -------- ------------ --------------------- | person_id |名| LName |创造| ----------- -------- ------------ --------------------- | 1 | kapek | sainnouine | 2007-07-13 16:18:47 | | 2 | sajon | rondela | 2007-07-13 16:18:47 | | 3 |利奇马|?rrtmons | 2007-07-13 16:18:47 | | 4 | SLAR | manlanth | 2007-07-13 16:18:47 | | 5 |气孔|尼鲁| 2007-07-13 16:18:47 | | 6 | nirtam | SKL?D | 2007-07-13 16:18:47 | | 7 | sungam | dulb?D | 2007-07-13 16:18:47 | | 8 | sreraf | encmelt | 2007-07-13 16:18:47 | ----------- -------- ------------ --------------------- 8行集(0秒)

不要求在XML文件中的每一个领域都有对应的表中的列相匹配。没有相应的列字段被跳过。你可以看到这一排空person2表和下降创建列,然后使用相同的LOAD XML声明我们只是以前,像这样:

MySQL的&#62;TRUNCATE person2;查询行,8行受影响(0.26秒)MySQL &#62;ALTER TABLE person2 DROP COLUMN created;查询行,0行受影响(0.52秒)记录:0份:0警告:0mysql &#62;SHOW CREATE TABLE person2\G*************************** 1. row ***************************       Table: person2Create Table: CREATE TABLE `person2` (  `person_id` int(11) NOT NULL,  `fname` varchar(40) DEFAULT NULL,  `lname` varchar(40) DEFAULT NULL,  PRIMARY KEY (`person_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf81 row in set (0.00 sec)mysql>LOAD XML LOCAL INFILE 'person-dump.xml'-&#62;INTO TABLE person2;查询行,8行受影响(0.01秒)记录:8:0:0删除了警告:0mysql &#62;SELECT * FROM person2;----------- -------- ------------ | person_id |名| LName | ----------- -------- ------------ | 1 | kapek | sainnouine | | 2 | sajon | rondela | | 3 |利奇马|?rrtmons | | 4 | SLAR | manlanth | | 5 |气孔|尼禄| | 6 | nirtam | SKL?D | | 7 | sungam | dulb?D | | 8 | sreraf | encmelt | ----------- -------- ------------ 8行集(0秒)

在该领域内的每一行的XML文件中给定的顺序并不影响操作LOAD XML;字段顺序可以不同的排,而不需要在同一顺序表中相应的列。

正如前面提到的,你可以使用一个(field_name_or_user_var, ...)一个或多个XML字段列表(仅选择所需字段)或用户变量(存储相应的字段后使用价值)。用户变量可以是特别有用,当你想从一个XML文件导入到表中的列的名称不匹配的XML字段插入数据。看到这是如何工作的,我们先创建一个表名个人其结构相匹配的person表,但其列的命名是不同的:

MySQL的&#62;CREATE TABLE individual (-&#62;individual_id INT NOT NULL PRIMARY KEY,-&#62;name1 VARCHAR(40) NULL,-&#62;name2 VARCHAR(40) NULL,-&#62;made TIMESTAMP- &#62;);查询行,0行受影响(0.42秒)

在这种情况下,你不能简单地加载XML文件直接导入表,因为字段和列名称不匹配:

mysql> LOAD XML INFILE '../bin/person-dump.xml' INTO TABLE test.individual;
ERROR 1263 (22004): Column set to default value; NULL supplied to NOT NULL column 'individual_id' at row 1

这是因为MySQL服务器查找字段名称匹配的目标表的列名。你可以解决这个问题通过选择字段值为用户变量,然后设定目标表的列的值等于这些变量的使用SET。你可以执行这些操作在一个语句,如下所示:

MySQL的&#62;LOAD XML INFILE '../bin/person-dump.xml'-&#62;INTO TABLE test.individual (@person_id, @fname, @lname, @created)-&#62;SET individual_id=@person_id, name1=@fname, name2=@lname, made=@created;查询行,8行受影响(0.05秒)记录:8:0:0删除了警告:0mysql &#62;SELECT * FROM individual;--------------- -------- ------------ --------------------- | individual_id | name1 name2 | |了| --------------- -------- ------------ --------------------- | 1 | kapek | sainnouine | 2007-07-13 16:18:47 | | 2 | sajon | rondela | 2007-07-13 16:18:47 | | 3 |利奇马|?rrtmons | 2007-07-13 16:18:47 | | 4 | SLAR | manlanth | 2007-07-13 16:18:47 | | 5 |气孔|尼鲁| 2007-07-13 16:18:47 | | 6 | nirtam | SKL?D | 2007-07-13 16:18:47 | | 7 | sungam | dulb?D | 2007-07-13 16:18:47 | | 8 | srraf | encmelt | 2007-07-13 16:18:47 | --------------- -------- ------------ --------------------- 8行集(0秒)

用户的变量名必须配合相应的字段从XML文件,在需要添加@前缀表示变量。用户变量不需要上市或分配在同一顺序的相应字段。

使用ROWS IDENTIFIED BY '<tagname>'条款,可以从相同的XML文件中的数据导入到数据库表的不同定义。例如,假设你有一个文件名为address.xml其中包含以下XML:

<?xml version="1.0"?>

<list>
  <person person_id="1">
    <fname>Robert</fname>
    <lname>Jones</lname>
    <address address_id="1" street="Mill Creek Road" zip="45365" city="Sidney"/>
    <address address_id="2" street="Main Street" zip="28681" city="Taylorsville"/>
  </person>

  <person person_id="2">
    <fname>Mary</fname>
    <lname>Smith</lname>
    <address address_id="3" street="River Road" zip="80239" city="Denver"/>
    <!-- <address address_id="4" street="North Street" zip="37920" city="Knoxville"/> -->
  </person>

</list>

你可以再次使用test.person在本节中定义表之前,清除所有现有的记录从表中并显示其结构如图所示后:

mysql<TRUNCATE person;Query OK, 0 rows affected (0.04 sec)mysql<SHOW CREATE TABLE person\G*************************** 1. row ***************************       Table: personCreate Table: CREATE TABLE `person` (  `person_id` int(11) NOT NULL,  `fname` varchar(40) DEFAULT NULL,  `lname` varchar(40) DEFAULT NULL,  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,  PRIMARY KEY (`person_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8mb41 row in set (0.00 sec)

现在创建一个address表中测试using the following数据库CREATE TABLE声明:

创建表的地址(address_id INT NOT NULL主键,person_id int空街varchar(40),无效,邮政国际空、市varchar(40)为空,创建时间戳);

从XML文件中的数据导入person表,执行以下LOAD XML语句,它指定行规定的<person>元素,如下所示;

mysql> LOAD XML LOCAL INFILE 'address.xml'
    ->   INTO TABLE person
    ->   ROWS IDENTIFIED BY '<person>';
Query OK, 2 rows affected (0.00 sec)
Records: 2  Deleted: 0  Skipped: 0  Warnings: 0

您可以验证记录进口使用SELECT声明:

MySQL的&#62;SELECT * FROM person;----------- -------- ------- --------------------- | person_id |名| LName |创造| ----------- -------- ------- --------------------- | 1 |罗伯特|琼斯| 2007-07-24 17:37:06 | | 2 |玛丽|史米斯| 2007-07-24 17:37:06 | ----------- -------- ------- --------------------- 2行集(0秒)

<address>在XML文件中的元素在没有相应的列表,他们跳过

从进口数据<address>元素为地址表,使用LOAD XML表所示:

MySQL的&#62;LOAD XML LOCAL INFILE 'address.xml'-&#62;INTO TABLE address-&#62;ROWS IDENTIFIED BY '<address>';查询行,3行受影响(0秒)记录:3:0:0删除了警告:0

你可以看到,数据导入使用SELECT如这一声明:

MySQL的&#62;SELECT * FROM address;------------ ----------- ----------------- ------- -------------- --------------------- | address_id | person_id |街|拉链|市|创造| ------------ ----------- ----------------- ------- -------------- --------------------- | 1 | 1 |磨溪路| 45365 |西德尼| 2007-07-24 17:37:37 | | 2 | 1 |大街| 28681 |泰勒斯维尔| 2007-07-24 17:37:37 | | 3 | 2 |河路| 80239 |丹佛| 2007-07-24 17:37:37 | ------------ ----------- ----------------- ------- -------------- --------------------- 3行集(0秒)

从数据<address>元,是包含在XML注释是不是进口的。然而,既然有人_ ID列在address表的价值人_ ID从父属性<person>元每<address>导入address

安全注意事项LOAD DATA声明的XML文件从客户端转移到服务器主机的MySQL服务器启动。在理论上,一个补丁服务器可以建立,会告诉客户程序来调用一个服务器的选择而不是文件名中的客户端文件LOAD XML声明。这样的服务器可以访问任何文件在客户端,客户端的用户进行读访问。

在网络环境下,客户端通常连接到MySQL的Web服务器。用户可以运行任何命令对MySQL服务器可以使用LOAD XML LOCAL阅读任何文件的读访问Web服务器的过程。在这种环境下,相对于MySQL服务器的客户端实际上是Web服务器,而不是远程程序是由谁连接到Web服务器的用户。

您可以禁用加载XML文件从客户端启动服务器--local-infile=0--local-infile=OFF。此选项也可用于启动时MySQL客户端禁用LOAD XMLfor the duration of the客户端会话。

为了防止客户端从服务器加载XML文件,不给予FILE特权相应的MySQL用户帐户,或废除这一特权如果客户端用户帐户已经有。

重要

撤销FILE特权(或不允许它在首位)让用户只执行LOAD XML INFILE声明(以及LOAD_FILE()它的功能;防止用户执行LOAD XML LOCAL INFILE。不允许这种说法,你必须启动服务器或客户端--local-infile=OFF

换句话说,这FILE特权只影响客户端是否可以读取服务器上的文件;它对客户端是否可以读取本地文件系统上的文件没有关系。

对于分区使用存储引擎使用表锁表,如MyISAM妈妈,locks引起by加载XML所有分区上的表执行锁。这不适用于使用存储引擎使用行级锁的表,如InnoDB。有关更多信息,参见分区和锁定

13.2.9取代语法

REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    {VALUES | VALUE} (value_list) [, (value_list)] ...

REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    SET assignment_list

REPLACE [LOW_PRIORITY | DELAYED]
    [INTO] tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [(col_name [, col_name] ...)]
    SELECT ...

value:
    {expr | DEFAULT}

value_list:
    value [, value] ...

assignment:
    col_name = value

assignment_list:
    assignment [, assignment] ...

REPLACE工作完全一样INSERT,如果表中的一个老行已为新的一行相同的值主键UNIQUE指数,旧行之前插入新的行被删除。看到第13.2.6,“插入语法”

REPLACE是一个mysql扩展SQL标准。它可以插入,或删除插入。另一个MySQL扩展标准的SQL插入或更新第13.2.6.2,插入…在重复的密钥更新语法”

DELAYED插入替换在MySQL 5.6否决。在MySQL 5.0,延迟不支持。服务器认识而忽视DELAYED关键词,办理更换为非替换,并生成一个er_warn_legacy_syntax_converted预警。(更换延迟不再支持。声明转换为替代。页:1DELAYED关键词将在未来的版本中删除。

笔记

REPLACE道理只有一个表有一个主键UNIQUE索引。否则,它变得相当于INSERT,因为没有指数是用来确定一个新的行重复另一。

所有列的值是从指定的值REPLACE声明。任何缺少的列设置为它们的默认值,如发生INSERT。你不能把值从当前行和使用它们在新的行。如果你使用一个分配等配置col_name=col_name,右边的列名称被视为参考DEFAULT(col_name),所以分配是等价的配置col_name= DEFAULT(col_name)1

使用REPLACE你必须拥有的,INSERTDELETE该表的权限

如果生成的列被明确,唯一被允许的值DEFAULT。有关生成的列的信息,参见第13.1.18.8,“创建表和生成的列”

REPLACE支持显式分区选择使用分区一个用逗号分隔的名称列表分区,子分区关键字,或两者。与INSERT,如果它是不可能为任何这些分区和子分区插入新的行,更换语句失败与错误发现一行不匹配给定的分区设置。更多的信息和例子,看第22,“分区选择”

这个REPLACE语句返回计数指示受影响的行数。这是该行被删除和插入的总和。如果算上1个单排REPLACE,一行插入没有行被删除。如果计数大于1,一个或多个旧行之前插入新的行删除。一行,如果表包含多个唯一索引和在不同的独特的指标不同旧行新行复制值替换多个旧行是有可能的。

受影响的行数可以很容易确定REPLACE只有添加行或是否也取代任何行:检查是否计数为1(添加)或更大(更换)。

如果你使用C API,受影响的行数可以获得使用mysql_affected_rows()功能

你不能替换成表并选择来自同一个表中查询。

MySQL使用下面的算法REPLACE(和加载数据…更换):

  1. 尝试向表中插入新的一行

  2. 而因为重复键错误发生主键或唯一索引插入失败:

    1. 从表中删除冲突的行,有重复的键值

    2. 再次尝试向表中插入新的一行

这是可能的,在一个重复键错误的情况下,存储引擎可以执行的REPLACE作为一个更新而不是删除和插入,但语义是相同的。没有用户可见的影响比如何其他存储引擎的增量可能的差异处理程序_xxx状态变量

因为结果REPLACE ... SELECT陈述取决于行的排序SELECT这个命令不能得到保证,这是可能的,记录这些陈述分歧主人与奴隶。因为这个原因,更换…选择声明标记为不安全的基于语句的复制。这些陈述产生在错误日志中的警告时,使用声明模式和写入使用基于行的格式时,使用二进制日志MIXED模式。参见第17.2.1.1,”优势和基础,基于行的复制”语句的缺点

当修改一个现有的未分区表的分区来容纳,或者,当修改一个已分区表的分区,你可能会考虑改变表的主键(见“22.6.1分解段,原钥匙,钥匙和钥匙,独特的”)。你应该知道,如果你这样做,结果REPLACE陈述可能会受到影响,就像他们会如果你修改了一个非分区表的主键。考虑一下下面的创建的表格CREATE TABLE声明:

创建测试表(ID int unsigned不空auto_increment数据varchar(64),默认为空,非空current_timestamp TS时间戳默认更新current_timestamp,主键(ID));

当我们创建这个表和运行在MySQL客户端显示的报表,结果如下:

mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.04 sec)

mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.04 sec)

mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.00 sec)

现在我们创建另一个表的第一个几乎一模一样,除了主键现在覆盖2列,如下所示(强调文本):

CREATE TABLE test2 (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id, ts)
);

当我们运行test2同样的两更换陈述我们在原test表,我们得到不同的结果:

MySQL的&#62;REPLACE INTO test2 VALUES (1, 'Old', '2014-08-20 18:47:00');查询行,1行的影响(0.05秒)MySQL &#62;REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42');查询行,1行的影响(0.06秒)MySQL &#62;SELECT * FROM test2;---- ------ --------------------- | ID |数据| TS | ---- ------ --------------------- | 1 |老| 2014-08-20 18:47:00 | | 1 |新| 2014-08-20 18:47:42 | ---- ------ --------------------- 2行集(0秒)

这是因为,当运行在test2,两身份证件ts列的值必须符合现有行的行被替换;否则,插入一行。

REPLACE影响分区表使用的存储引擎,如语句MyISAM使用表级锁只有分区包含匹配的行的更换陈述WHERE条款,只要没有分区表的列进行更新;否则,整个表锁定。(存储引擎等InnoDB使用行级锁,没有锁定的分区发生。)的更多信息,参见分区和锁定

13.2.10 SELECT语法

SELECT
    [ALL | DISTINCT | DISTINCTROW ]
      [HIGH_PRIORITY]
      [STRAIGHT_JOIN]
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    select_expr [, select_expr ...]
    [FROM table_references
      [PARTITION partition_list]
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
    [HAVING where_condition]
    [WINDOW window_name AS (window_spec)
        [, window_name AS (window_spec)] ...]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        export_options
      | INTO DUMPFILE 'file_name'
      | INTO var_name [, var_name]]
    [FOR {UPDATE | SHARE} [OF tbl_name [, tbl_name] ...] [NOWAIT | SKIP LOCKED] 
      | LOCK IN SHARE MODE]]

SELECT用于检索选定的一个或多个表中的行,并包括UNION报表和查询。看到第13.2.10.3”联盟,语法”,和13.2.11”查询语法”部分。。一SELECT语句可以从一个WITH条款定义公用表表达式内访问SELECT。看到第13.2.13,“语法(公用表表达式)”

最常用的条款SELECT这些陈述:

  • 每个select_expr指示列,你想找回。必须有至少一个select_expr

  • table_references显示表或表中检索行。它的语法描述第13.2.10.2,加入“语法”

  • SELECT支持显式分区选择使用分区用一个列表分区和子分区(或两者)以下的表的名称在table_reference(见第13.2.10.2,加入“语法”)。在这种情况下,行从分区上市的选择,和任何其他的分区表被忽略。更多的信息和例子,看第22,“分区选择”

    SELECT ... PARTITION使用存储引擎如表MyISAM执行表级锁(因此分区锁)锁只有分区或子分区命名的分区选项

    有关更多信息,参见分区和锁定

  • 这个WHERE条款,如果给出,表明行必须满足的条件或条件选择。where_condition是为真的每一行被选中的表达式。该语句选择所有行如果没有哪里条款.

    WHERE表达,你可以使用任何与运营商的功能,MySQL的支持,除了骨料(摘要)功能。看到9.5节,“表达式”,和12章,函数和操作符

SELECT也可用于检索行的计算没有任何表。

例如:

mysql> SELECT 1 + 1;
        -> 2

你可以指定DUAL作为一个虚拟的表名称的情况下,没有表的引用:

MySQL的&#62;SELECT 1 + 1 FROM DUAL;&#62; 2

DUAL是纯粹的人要求所有的便利SELECT声明should have可能还有其他条款。MySQL可能忽略的条款。MySQL不需要FROM DUAL如果没有表引用

在一般情况下,条款必须完全按语法描述显示了。例如,一个HAVING条款必须在任何和之前的任何条款ORDER BY条款.例外的是子句可以出现如图所示的语法描述或紧随select_expr列表为更多的信息关于,看到第13.2.10.1,“选择…为语法”

列表select_expr条款包括选择列表显示哪个列检索。指定的列或表达式或可以使用*-速记:

  • 选择列表只包含一个单一的不合格*可用于速记选择所有表中的所有列:

    SELECT * FROM T1 T2内加入…
  • tbl_name.*可作为一个合格的速记选择从命名表中的所有列:

    选择T1,T2,T1和T2 *从内…
  • 使用不合格的*在选择列表中的其他项目可能产生一个语法错误。为了避免这个问题,使用合格的tbl_name*参考

    选择AVG(评分),T1,T1…

下面的列表提供了其他额外的信息SELECT条款:

  • select_expr可以给出一个使用别名作为alias_name。别名作为表达的列名,可用于ORDER BY,或条款。例如:

    SELECT CONCAT(last_name,', ',first_name) AS full_name
      FROM mytable ORDER BY full_name;
    

    这个AS当关键字是可选的混叠aselect_expr一个标识符。前面的例子可能是这样写的:

    选择concat(last_name,&#39;,&#39;,first_name)从mytable为full_name full_name;

    然而,由于AS是可选的,如果你忘记了逗号两可以发生一个微妙的问题select_expr表情:MySQL解释二别名。例如,在下面的语句,columnb作为一个别名:

    SELECT columna columnb FROM mytable;
    

    出于这个原因,它是很好的做法是使用习惯AS明确在指定的列别名

    不允许把一列别名在WHERE条款,因为该列的值可能尚未确定时哪里条款执行。看到第b.5.4.4,”问题列别名”

  • 这个FROM table_references条款显示表或表从中检索行。如果你的名字多个表,你是执行联接。关于加入语法,看第13.2.10.2,加入“语法”。为每个表指定,您可以选择指定一个别名。

    tbl_name [[AS] alias] [index_hint]
    

    使用索引提示为优化器提供有关如何在查询处理过程中选择指标。用于指定这些提示描述的语法,看第8.9.4,”指标提示”

    你可以使用SET max_seeks_for_key=value作为一种替代的方式迫使MySQL选择键扫描代替表扫描。看到第5.1.7,服务器“系统变量”

  • 你可以引用一个表内的默认数据库tbl_name,或作为db_nametbl_name指定一个数据库明确。你可以参考一列col_nametbl_namecol_name,或db_nametbl_namecol_name。你不需要指定tbl_namedb_nametbl_name一列参考前缀除非参考会暧昧。看到9.2.1节,“标识符限定符”对歧义,需要更明确的列引用形式的例子。

  • 一个表可以参考别名的使用tbl_name AS alias_nametbl_name alias_name

    SELECT t1.name, t2.salary FROM employee AS t1, info AS t2  WHERE t1.name = t2.name;SELECT t1.name, t2.salary FROM employee t1, info t2  WHERE t1.name = t2.name;
  • 选择输出列中可以借鉴ORDER BY从句使用列名称、列的别名,或列位置。列的位置都是整数,从1开始:

    SELECT college, region, seed FROM tournament
      ORDER BY region, seed;
    
    SELECT college, region AS r, seed AS s FROM tournament
      ORDER BY r, s;
    
    SELECT college, region, seed FROM tournament
      ORDER BY 2, 3;
    

    要以相反的顺序排序,添加DESC(降)关键字中的列的名称顺序条款你排序。默认是升序;这可以明确指定使用ASC关键词

    如果ORDER BY在子查询中,也应用于外部查询,最外层的顺序优先。例如,下列语句结果按降序排序,不升阶:

    (SELECT ... ORDER BY a) ORDER BY a DESC;
    

    使用列位置是不因为语法已经从SQL标准删除。

  • MySQL 8.0.13之前,MySQL支持非标准语法的扩展,允许显式ASCdesc指示器GROUP BY专栏8.0.12后来支持MySQL顺序分组功能,使用这个扩展不再是必要的。(错误# 86312,错误# 26073525)这也意味着你可以在任意列排序时使用GROUP BY,像这样:

    选择一个,B、计数(C)是由test_table T组,由B级,T desc;

    作为的mysql 8.0.13,GROUP BY扩展不再支持:ASCDESC指示器列不允许

  • 当你使用ORDER BY在一列排序SELECT服务器类型值,只使用字节数表示的初始max_sort_length系统变量

  • MySQL扩展使用GROUP BY许可中未提及的领域选择条款.如果你没有得到结果,你期望从你的查询,请阅读说明GROUP BY发现12.19节,“总(组)功能”

  • GROUP BY允许与汇总改性剂。看到第12.19.2,“集团通过修改”

    以前,它是不允许使用ORDER BY在一个查询中有一个与汇总改性剂。这是解除限购作为MySQL 8.0.12。看到第12.19.2,“集团通过修改”

  • 这个HAVING条款适用近,就在物品发送到客户端,没有优化。(极限应用后HAVING。)

    SQL标准要求HAVING必须参考的列用于聚合函数的条款或列。然而,MySQL支持这种行为的延伸,并允许HAVING指在列SELECT在外的子查询表和列以及。

    如果HAVING条款是指明确列,发生了警告。在下面的语句,COL2暧昧是因为它作为一个别名和列名称:

    SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;
    

    优先标准SQL的行为,所以如果一个HAVING栏目名称都采用作为一个别名列输出中的列的列表,优先考虑在列GROUP BY专栏

  • 不要使用HAVING那应该是在项目哪里条款.例如,不写下:

    SELECT col_name FROM tbl_name HAVING col_name > 0;
    

    这不是写:

    SELECT col_name FROM tbl_name WHERE col_name > 0;
    
  • 这个HAVING条款可以参考聚合函数,其中哪里条款不能:

    SELECT user, MAX(salary) FROM users
      GROUP BY user HAVING MAX(salary) > 10;
    

    (这并不是在MySQL。一些老版本的工作)

  • MySQL允许重复的列名。是的,可以有一个以上的select_expr用相同的名字。这是对标准SQL的扩展。因为MySQL也允许HAVINGselect_expr值,这就导致了歧义:

    选择12作为一组,从一个;

    在声明中,都列有名字a。确保正确的列进行分组,使用不同的名称为每个select_expr

  • 这个WINDOW条款,如果存在,定义命名的窗可以称为窗函数。详情见第12.20.4,”命名的窗口”

  • MySQL解决不合格的列或别名引用ORDER BY条款中寻找select_expr值,然后在表的列条款.为GROUP BY条款,它搜索FROM在搜索之前的条款select_expr价值观。(For)HAVING,这不同于预MySQL5.0行为,使用相同的规则为顺序。)

  • 这个LIMIT子句可以用来限制返回的行数的SELECT声明极限以一个或两个数值参数,它必须是非负整数,这些例外:

    • 在准备好的声明,LIMIT参数可以指定使用placeholder标记。

    • 在存储程序,LIMIT参数可以使用整数的常规参数或局部变量指定。

    有两个参数,第一个参数指定要返回的第一行的偏移量,和第二指定返回的最大行数。的初始行的偏移量是0(而不是1):

    SELECT * FROM tbl LIMIT 5,10;  # Retrieve rows 6-15
    

    检索从一定的偏移到结果集的结束所有的行,你可以使用一些大量的二参数。这句话从第九十六排到最后一个检索所有行:

    SELECT * FROM tbl LIMIT 95,18446744073709551615;
    

    以一个参数的值指定的行数返回结果集的开始:

    SELECT * FROM tbl LIMIT 5;     # Retrieve first 5 rows
    

    换句话说,LIMIT row_count相当于极限0row_count

    为编制报表,你可以使用占位符。下面的语句将返回一行tbl

    SET @a=1;PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?';EXECUTE STMT USING @a;

    下面的语句将返回第二到第六行的tbl

    SET @skip=1; SET @numrows=5;PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?, ?';EXECUTE STMT USING @skip, @numrows;

    为了兼容PostgreSQL,MySQL也支持LIMIT row_count OFFSET offset语法

    如果LIMIT在子查询中,也应用于外部查询,最外层的极限优先。例如,下面的语句产生两行,不一:

    (SELECT ... LIMIT 1) LIMIT 2;
    
  • 这个SELECT ... INTO形式SELECT使查询结果被写入一个文件或存储在变量。有关更多信息,参见第13.2.10.1,“选择…为语法”

  • 如果你使用FOR UPDATE一个存储引擎使用页锁或行锁,行查询检查写锁定到当前事务结束。

    你不能使用FOR UPDATE的一部分SELECT如在一份声明中CREATE TABLE new_table SELECT ... FROM old_table ...。(如果你想这样做,声明被拒绝的错误无法更新表”old_table“而”new_table“正在创建。)

    FOR SHARE锁在共享模式设置共享锁允许其他事务读取数据但不进行更新或删除它们。FOR SHARE锁在共享模式是等价的。然而,FOR SHARE,像更新,支持NOWAIT跳过锁定,和OF tbl_name选项分享是一种替代LOCK IN SHARE MODE,但锁在共享模式仍然可以向后兼容

    NOWAIT原因一更新FOR SHARE查询立即执行,返回一个错误如果因锁被另一个事务举行了一排锁不能。

    SKIP LOCKED原因一更新FOR SHARE查询立即执行,不包括从结果集,是由另一个事务锁定的行。

    NOWAIT跳过锁定选择是基于语句的复制不安全。

    笔记

    跳过锁定行返回不一致的数据视图查询。SKIP LOCKED因此不适合普通的事务性工作。然而,它可以用来避免锁争用时,多个会话访问同一队列的表。

    OF tbl_name应用更新FOR SHARE查询指定表。例如:

    SELECT * FROM T1,T2为更新共享T1、T2;

    所有的表的查询块引用时被锁定OF tbl_name省略。因此,使用锁定条款无tbl_name结合另一个锁子句返回一个错误。在多个锁定条款指定相同的表中返回一个错误。如果一个别名是指定的表名选择声明,锁定条款只能使用别名。如果SELECT声明没有指定一个别名明确,锁定条款只能指定实际的表名。

    为更多的信息关于FOR UPDATE分享,看到第15.5.2.4,锁定读”。有关更多信息NOWAIT跳过锁定选项,看锁定读并发NOWAIT跳过锁定

SELECT关键词,你可以使用一些影响表的操作性。high_prioritySTRAIGHT_JOIN和修饰sql_正在MySQL扩展标准的SQL。

  • 这个ALL不同的修饰符指定是否应返回重复的行。ALL(默认值)指定要返回所有匹配的行,包括重复。不同的指定去除重复行的结果集。它是指定修饰符错误。DISTINCTROW是同义词不同的

    在MySQL 8.0.12后来,DISTINCT可以使用一个查询,同时使用与汇总。(错误# 87450,错误# 26640100)

  • HIGH_PRIORITY给出了SELECT比一个语句更新表的优先级更高。你应该利用这仅有的那是非常快的,必须马上做查询。一选择high_priority查询,同时发布表锁定阅读运行即使有等待表是免费的UPDATE语句。这仅影响存储引擎只使用表级锁(如MyISAM内存,和MERGE

    HIGH_PRIORITY不能使用SELECT语句的一部分UNION

  • STRAIGHT_JOIN军队优化器联接表中所列的顺序条款.你可以用这个来加快查询如果优化器连接表在非最佳秩序。STRAIGHT_JOIN因此,可以用在table_references列表看到第13.2.10.2,加入“语法”

    STRAIGHT_JOIN不适用于任何表,优化器将作为一个constsystem表这样一个表产生一个单排,是执行查询的优化阶段,阅读,和其列引用与相应的列值的查询执行前收益取代。这些表将出现在显示的查询计划的第一EXPLAIN。看到8.8.1节,“优化查询的解释”。这种异常可能不适用于constsystem表上使用无效的补面外连接(即,一个右表LEFT JOIN或左边的表一右连接

  • SQL_BIG_RESULTsql_small_result可以使用GROUP BY不同的对优化的结果集有许多行或是小的,分别。为SQL_BIG_RESULT直接使用临时表,MySQL基于磁盘如果他们被创造,喜欢排序使用临时表上的一个关键元素为SQL_SMALL_RESULTMySQL使用内存中的临时表,而不是使用排序结果表店。这通常不需要。

  • SQL_BUFFER_RESULT力量的结果放在一个临时表。这有助于MySQL的表锁,有助于早期自由的情况下,它需要很长的时间来发送到客户端的结果集。这个修改器只能用于顶层SELECT陈述,不为子查询或以下UNION

  • SQL_CALC_FOUND_ROWS告诉MySQL来计算有多少行就在结果集,无论任何极限条款.然后行数可以获得SELECT FOUND_ROWS()。看到12.14节,“信息功能”

  • 这个SQL_CACHE没有任何东西改性剂与MySQL 8之前的查询缓存。查询缓存是在MySQL 8中删除,所以SQL_CACHE没有任何东西不推荐使用,没有影响,并将在未来的MySQL版本中删除。

SELECT使用存储引擎如分区表MyISAM使用表级锁只有分区包含匹配的行的选择陈述WHERE条款.(这并不与存储引擎如发生InnoDB使用行级锁。)的更多信息,参见分区和锁定

13.2.10.1选择…为语法

这个SELECT ... INTO形式SELECT使查询结果被存储在变量或写入文件:

  • SELECT ... INTO var_list选择列的值存储到变量。

  • SELECT ... INTO OUTFILE将选定的行到一个文件。列和行终止符可以指定产生特定输出格式。

  • SELECT ... INTO DUMPFILE写一个单排去一个没有任何格式的文件。

这个SELECT语法描述(湖第13.2.10,选择“语法”)显示INTO条款在语句结束。也可以使用紧随select_expr列表

一个INTO条款不应使用嵌套SELECT因为这样的SELECT必须返回其结果外语境。

这个INTO条款名称列表中的一个或多个变量,它可以是用户定义的变量,存储过程或函数的参数,或存储程序的局部变量。(在准备select…outfile into声明,只有用户定义的变量是允许的;看第13.6.4.2,“局部变量的范围和分辨率”。)

选定的值赋给变量。变量的数目必须匹配的列数。查询应该返回一个单独的行。如果查询不返回行,一个错误代码1329警告出现(No data),和变量的值保持不变。如果查询返回多行,发生错误1172(结果由多个行)。如果有可能,声明可以检索多行,你可以使用LIMIT 1限制设置为单排的结果。

选择ID、数据为”X,Y从test.t1限1 @;

用户变量名不区分大小写。看到9.4节,“用户定义的变量

这个SELECT ... INTO OUTFILE 'file_name'形式SELECT将选定的行到一个文件。文件服务器主机上创建的,所以你必须有FILE特权使用此语法file_name不能被现有的文件,这在其他事情上防止文件等/etc/passwd与数据库表被破坏。这个character_set_filesystem系统变量控制文件名称的解释。

这个SELECT ... INTO OUTFILE声明的目的主要是让你很快甩掉一台服务器机器上的一个文本文件。如果你想创建的文件在其他主机到服务器主机,你通常不能使用SELECT ... INTO OUTFILE既然没有办法写文件的路径相对于服务器主机的文件系统。

然而,如果MySQL客户端软件安装在远程机器上,您可以使用客户端命令代替等mysql -e "SELECT ..." > file_name生成的客户端主机上的文件。

也可以创建的文件放在不同的主机服务器以外的主机,如果文件在远程主机的位置可以使用网络映射的路径在服务器的文件系统访问。在这种情况下,存在MySQL(或其他一些MySQL客户端程序)不在目标主机的要求。

SELECT ... INTO OUTFILE是补充LOAD DATA INFILE。列的值写入转换为字符集指定的字符集条款.如果没有这样的条款存在,价值被使用binary字符集。实际上,没有字符集转换。如果结果集包含多种字符集的列,输出数据文件以及您可能无法加载文件正确。

对于语法export_options声明的部分由相同领域LINES从句用LOAD DATA INFILE声明。看到第13.2.7、“LOAD DATA INFILE语法”,的信息FIELDS线条款,包括默认值和允许值。

FIELDS ESCAPED BY控制如何写特殊字符。如果场逃跑了性格不是空的,它是在必要的时候使用避免歧义作为前缀,在下列字符输出:

  • 这个FIELDS ESCAPED BY人物

  • 这个FIELDS [OPTIONALLY] ENCLOSED BY人物

  • 的第一个字符FIELDS TERMINATED BY线端价值观

  • ASCII码NUL(零值字节;实际上是转义字符下面写的是ASCII,不是一个零值字节)

这个FIELDS TERMINATED BY封闭的ESCAPED BY,或线端人物必须可避免的,你可以阅读的文件恢复可靠。ASCII码NUL逃脱,使它更容易与一些寻呼机的观点。

生成的文件没有符合SQL语法,所以没有什么需要逃。

如果FIELDS ESCAPED BY性是空的,没有人物都逃了出来,无效的输出为NULL,不\n。它不可能是指定一个空的转义字符是一个好主意,特别是如果你的数据字段值包含的任何角色只是提供的清单。

这里是在逗号分隔的值产生一个文件的一个实例(CSV)的许多程序使用的格式:

SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM test_table;

如果你使用INTO DUMPFILE而不是到输出文件只写一行,MySQL的文件,没有任何列或行终止和不执行任何逃避处理。如果你想存储这是有用的BLOB在一个文件中的值

笔记

创建的任何文件INTO OUTFILE成的dumpfile可写的服务器主机上的所有用户。这是因为MySQL服务器无法创建文件,其他比它运行的帐户下的用户谁拥有。(你应该从未运行mysqld作为root这和其他的原因。)文件必须是可写的,你可以操纵它的内容。

如果secure_file_priv系统变量设置为一个非空的目录名,文件可写必须位于该目录。

语境中的SELECT ... INTO由于事件调度器执行部分事件发生的陈述,诊断信息(不仅错误,而且警告)写入错误日志,并在Windows应用程序事件日志,以。更多信息,参见第23.4.5,“事件调度器的状态”

13.2.10.2加入语法

MySQL支持以下JOIN语法为table_references部分SELECT报表和多表DELETEUPDATE声明:

table_references:escaped_table_reference【,escaped_table_reference]…escaped_table_referencetable_reference| {黄table_reference}table_referencetable_factor|join_tabletable_factortbl_name[分区(partition_names[)] [ 13 ]alias] [index_hint_list| ]table_subquery[砷]alias[(col_list|()]table_referencesjoin_tabletable_reference[内] |交叉连接table_factorjoin_condition| ]table_referencestraight_jointable_factor|table_referencestraight_jointable_factor打开(放)conditional_expr|table_reference{左|权} [外]加入table_referencejoin_condition|table_reference自然[内| {左|权} [外] ]加入table_factorjoin_condition是:conditional_expr|使用(column_listindex_hint_listindex_hint【,index_hint]…index_hint:为{使用{指数|关键} [加入|通过|组} ]命令([index_list])|忽略{ } {关键指标| [加入|通过|组} ]命令(index_list)为{ |力{ } [加入| |关键指标的|组} ]命令(index_listindex_listindex_name【,index_name]…

一个参考表也被称为连接表达式。

表引用(当它指的是一个分区表)可能包含一个PARTITION选项,包括用逗号隔开的分区,子分区,或两者。这个选项如下表的名称和之前的任何别名声明。这个选项的效果是,行从列出的分区或子分区选择。任何分区或子分区列表中未命名的忽视。更多的信息和例子,看第22,“分区选择”

语法table_factor在标准SQL MySQL扩展比较。标准只接受table_reference,没有他们的列表放在圆括号内。

这是一个保守的扩展列表中的每个逗号table_reference项目被认为是相当于一个内部联接。例如:

SELECT * FROM t1 LEFT JOIN (t2, t3, t4)                 ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)

就相当于:

SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
                 ON (t2.a = t1.a AND t3.b = t1.b AND t4.c = t1.c)

在MySQL,JOIN交叉连接,和INNER JOIN语法等价物(它们可以相互替换)。在标准的SQL,他们是不等价的。内部联接使用一个ON条款,交叉连接否则使用

总的来说,括号可以忽略加入只包含内在表达的连接操作。MySQL还支持嵌套连接。看到第8.2.1.7,“嵌套连接优化”

指标提示可以指定如何影响MySQL优化器利用指标。有关更多信息,参见第8.9.4,”指标提示”。优化器提示和optimizer_switch系统变量可以有其他的方式来影响优化器使用索引。看到第8.9.2,“优化器提示”,和第3,“开关的优化”

下面的列表描述了考虑写作时加入的一般因素:

  • 一个表可以参考别名的使用tbl_name AS alias_nametbl_name alias_name

    SELECT t1.name, t2.salary  FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;SELECT t1.name, t2.salary  FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
  • table_subquery也被称为派生表或查询中条款.看到第13.2.11.8,“派生表”。。。。。。。搜索subqueries必须包括给子查询结果表名的一个别名,并可任选包括目录表中列的名称在括号中。一个平凡的例子如下:

    SELECT * FROM (SELECT 1, 2, 3) AS t1;
    
  • INNER JOIN(逗号)语义等价的加入条件缺失:产生指定表之间的笛卡尔积(即每行第一个表中是第二表每行加入)。

    然而,逗号运算符的优先级低于INNER JOIN交叉连接LEFT JOIN,等等。如果你把逗号和其他连接类型时,有条件的加入,形成一个错误未知的柱col_name这是在网上的第可能会发生。关于处理这个问题,给出本节后面的信息。

  • 这个conditional_expr使用打开(放)是的,可以用在任何形式的条件表达式WHERE条款.一般来说,的打开(放)条款为条件,指定如何连接表,和WHERE子句限制哪些行包含在结果集。

  • 如果没有匹配行右表中ON使用的一部分LEFT JOIN,设置所有列的行无效的用于右表。你可以利用这一点来查找表中的行,在另一个表中没有对应的:

    SELECT left_tbl.*
      FROM left_tbl LEFT JOIN right_tbl ON left_tbl.id = right_tbl.id
      WHERE right_tbl.id IS NULL;
    

    这个例子中发现的所有行left_tbl一个身份证件价值是不存在的right_tbl(即所有行left_tbl没有相应的行right_tbl)。这第8.2.1.8,外部连接优化”

  • 这个USING(column_list)条款名称的列的列表,必须在存在的表。如果表b既包含列C1c2,和C3,下面的加入比较来自两个表对应的列:

    a LEFT JOIN b USING (c1, c2, c3)
    
  • 这个NATURAL [LEFT] JOIN两表定义是语义上等同于一个内部联接LEFT JOIN用一个使用条款名称都列在表中存在。

  • RIGHT JOIN工作方式类似于左连接。将代码移植到数据库,建议您使用LEFT JOIN而不是右连接

  • 这个{ OJ ... }只是为了兼容ODBC语法在加入语法描述显示存在。在语法的大括号应写上;他们不是元语法作为其他语法描述。

    SELECT left_tbl.*    FROM { OJ left_tbl LEFT OUTER JOIN right_tbl ON left_tbl.id = right_tbl.id }    WHERE right_tbl.id IS NULL;

    你可以使用其他类型的连接在{ OJ ... },如内部联接RIGHT OUTER JOIN。这有助于与一些第三方应用程序的兼容性,但不是官方的ODBC语法。

  • STRAIGHT_JOIN类似于加入,除左表总是先于右表读。这可以用于那些(少数)的情况下,加入优化过程在一个次优的顺序表。

一些加入的例子:

SELECT * FROM table1, table2;

SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;

SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id;

SELECT * FROM table1 LEFT JOIN table2 USING (id);

SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
  LEFT JOIN table3 ON table2.id = table3.id;

自然连接和连接USING,包括外部联接的变种,按照SQL 2003标准:

  • 多余的一列NATURAL加入不出现。考虑到这套报表:

    创建表T1(I型、J int);创建表T2(K,int,int);插入T1值(1, 1);插入的T2值(1, 1);选择*从T1自然连接T2;SELECT * FROM T1 T2(J)一起使用;

    在第一SELECT声明,列J出现在表,从而成为一个连接柱,因此,根据标准的SQL,它应该出现在输出中只有一次,不是两次。同样,第二选择语句,柱j命名的使用条款应该出现在输出中只有一次,不是两次。

    因此,该语句产生输出:

    +------+------+------+
    | j    | i    | k    |
    +------+------+------+
    |    1 |    1 |    1 |
    +------+------+------+
    +------+------+------+
    | j    | i    | k    |
    +------+------+------+
    |    1 |    1 |    1 |
    +------+------+------+
    

    消除冗余列和列的顺序是根据标准的SQL,生产这种显示顺序:

    • 首先,结合常见的列的两个表,在它们出现在第一个表格的顺序

    • 其次,在第一个表独特的栏目,在他们的顺序出现在那张桌子

    • 第三、第二台独特的栏目,在他们的顺序出现在那张桌子

    单柱代替常见的两列结果使用合并操作定义。那就是,两t1.aT2的由此产生的单连接柱a被定义为a = COALESCE(t1.a, t2.a),在那里:

    COALESCE(x, y) = (CASE WHEN x IS NOT NULL THEN x ELSE y END)
    

    如果连接操作是任何其他连接,连接的结果列包含所有列联接表的连接。

    一个合并列定义的结果是,外部连接,聚列包含的值—NULL如果一列的两列总是无效的。如果没有或两列NULL,常见的列具有相同的值,所以它并选择哪一个作为聚列的值不重要。一个简单的方法来解释,这是考虑到,合并列外连接是由一个内部表的共同的列代表加入。假设表t1(a, b)T2(A,C)有以下内容:

    t1    t2
    ----  ----
    1 x   2 z
    2 y   3 w
    

    然后,这种连接,柱a包含值一个T1

    mysql> SELECT * FROM t1 NATURAL LEFT JOIN t2;
    +------+------+------+
    | a    | b    | c    |
    +------+------+------+
    |    1 | x    | NULL |
    |    2 | y    | z    |
    +------+------+------+
    

    相比之下,这种连接,柱a包含值T2的

    mysql> SELECT * FROM t1 NATURAL RIGHT JOIN t2;
    +------+------+------+
    | a    | c    | b    |
    +------+------+------+
    |    2 | z    | y    |
    |    3 | w    | NULL |
    +------+------+------+
    

    比较这些结果,否则等效查询JOIN ... ON

    MySQL的&#62;SELECT * FROM t1 LEFT JOIN t2 ON (t1.a = t2.a);------ ------ ------ ------ | A B C A | | | | ------ ------ ------ ------ | | X 1 2 | |零零| | | Y Z 2 | | | ------ ------ ------。
    MySQL的&#62;SELECT * FROM t1 RIGHT JOIN t2 ON (t1.a = t2.a);------ ------ ------ ------ | A B C A | | | | ------ ------ ------ ------ | | | 2 2 Y Z | | | |零零| 3 | W | ------ ------ ------。
  • USING条款可以改写为打开(放)条款比较对应的列。然而,尽管USING打开(放)是相似的,他们都不太一样。考虑以下两个查询:

    a LEFT JOIN b USING (c1, c2, c3)
    a LEFT JOIN b ON a.c1 = b.c1 AND a.c2 = b.c2 AND a.c3 = b.c3
    

    对于确定哪些行满足条件的加入,同时加入在语义上是相同的。

    相对于确定显示哪些列SELECT *扩张,两连接语义不一致。这个使用加入选择合并值对应的列,而ON加入选择所有表的所有列。对于使用加入,SELECT *选择这些值:

    Coalece(A.C1,B.C1),coalece(A.C2,B.C2),coalece(A.C3,B.C3)

    对于ON加入,选择*选择这些值:

    a.c1, a.c2, a.c3, b.c1, b.c2, b.c3
    

    与内部联接,COALESCE(a.c1, b.c1)是不是相同的a.c1b.c1因为两列都有相同的值。外部连接(如左连接),其中一个列可以NULL。这列从结果略

  • 一个ON条款只能是指其操作数。

    例子:

    CREATE TABLE t1 (i1 INT);
    CREATE TABLE t2 (i2 INT);
    CREATE TABLE t3 (i3 INT);
    SELECT * FROM t1 JOIN t2 ON (i1 = i3) JOIN t3;
    

    声明未与Unknown column 'i3' in 'on clause'错误的原因i3是一列t3,这不是一个操作数打开(放)条款.使加入被处理,重写声明如下:

    SELECT * FROM t1 JOIN t2 JOIN t3 ON (i1 = i3);
    
  • JOIN比逗号操作符的优先级更高的(),所以加入的表达t1, t2 JOIN t3被解释为((T1,T2和T3))不作为,((t1, t2) JOIN t3)。这会影响报表使用打开(放)条款因为条款只能是指列在操作数的加入,并优先与操作数是什么解释。

    例子:

    CREATE TABLE t1 (i1 INT, j1 INT);
    CREATE TABLE t2 (i2 INT, j2 INT);
    CREATE TABLE t3 (i3 INT, j3 INT);
    INSERT INTO t1 VALUES(1, 1);
    INSERT INTO t2 VALUES(1, 1);
    INSERT INTO t3 VALUES(1, 1);
    SELECT * FROM t1, t2 JOIN t3 ON (t1.i1 = t3.i3);
    

    这个JOIN优先于逗号操作符的操作数,所以打开(放)条款t2T3。因为t1.i1是不是操作数列,结果是未知列“T1。I1的“条款”误差

    为了使连接进行处理,使用这些策略:

    • 第一组的两个表明确使用括号这样的操作数ON条款(T1,T2)t3

      SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3);
    • 避免逗号运算符和使用JOIN相反:

      SELECT * FROM t1 JOIN t2 JOIN t3 ON (t1.i1 = t3.i3);

    同一优先级的解释也适用于语句,逗号运算符与混合INNER JOIN交叉连接LEFT JOIN,和右连接,所有这一切都不是逗号运算符的优先级更高。

  • MySQL扩展相比,SQL:2003标准MySQL允许你获得普通(聚结)柱NATURAL使用加入,而标准不允许

13.2.10.3联盟的语法

SELECT ...
UNION [ALL | DISTINCT] SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]

UNION用于组合来自多个结果SELECT声明为一个结果集

the names from the first columnSELECT声明作为列名称返回的结果。选定的列在每个位置对应上市SELECT声明应具有相同的数据类型。(例如,通过第一个语句选中第一列应该有同类型的其他报表。选中第一列)

如果相应的数据类型SELECT列不匹配,在列的长度和类型UNION结果考虑到值的检索SELECT声明.例如,考虑下面的:

MySQL的&#62;SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10);--------------- |重复(A,1)| --------------- |一| | bbbbbbbbbb | ---------------

这个SELECT报表是正常的select语句,但有以下限制:

  • 只有最后一个SELECT语句可以使用到输出文件。??The entire?UNION结果写入文件。)

  • HIGH_PRIORITY不能使用SELECT语句的一部分UNION。如果你指定了它的第一个SELECT,它没有任何效果。如果你指定的任何后续SELECT语句、语法错误的结果。

默认的行为UNION是的,从结果中删除重复的行。可选不同的关键词已经不是默认没有影响,因为它还指定去除重复行。与可选的ALL关键词,去除重复行不发生和结果包括所有匹配行的所有SELECT声明.

你可以混合UNION ALLUNION DISTINCT在同一查询。混合的UNION类型的处理等,不同的联盟将覆盖任何ALL工会对左。一不同的联盟可以通过明确的产生UNION DISTINCT或隐式地使用UNION没有后不同的ALL关键词

应用ORDER BY极限一个人SELECT,将条款括号内括SELECT

(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)UNION(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);

然而,使用ORDER BY个人SELECT声明意味着什么它的行出现在最终的结果,因为UNION默认情况下,会产生一个无序的行集。因此,使用顺序在这种情况下通常是结合LIMIT,所以,它是用来确定所选择的行的子集来检索该SELECT,即使它并不一定影响最后的那些行的顺序UNION结果如果顺序似乎没有LIMIT在一个SELECT,它是优化掉,因为它会无论如何没有效果。

使用一个ORDER BY极限子句排序或限制整个UNION结果,插入个人SELECT报表和地方顺序LIMIT在最后一个。下面的示例使用条款:

(SELECT a FROM t1 WHERE a=10 AND B=1)UNION(SELECT a FROM t2 WHERE a=11 AND B=2)ORDER BY a LIMIT 10;

声明中没有括号相当于一个括号只是显示。

这类ORDER BY不能使用列引用,包括表名(即名字tbl_namecol_name格式)。相反,提供一个别名在第一SELECT声明所指的是别名顺序。(或者,是指在列ORDER BY使用列的位置。然而,使用列位置是过时的。)

同样,如果一个列进行排序的别名,ORDER BY条款必须指的是别名,不列名。下面的语句将第一、第二会失败的Unknown column 'a' in 'order clause'误差:

(选择B T)联盟(选择…)为B;(选择B T)联盟(选择…)的命令;

引起排在UNION结果包括检索每个行集SELECT一前一后,选择在每一个额外的列SELECT使用一个排序列并添加一个顺序继去年SELECT

(选择1 sort_col,COL1A,col1b,…从T1)联盟(选择2,col2a,col2b,…从T2)为sort_col;

另外保持排序顺序内的个体SELECT结果,到添加辅助列顺序条款:

(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col, col1a;

使用一个额外的列也可以确定SELECT每一行来自。额外的列可以提供其他识别信息,如一个字符串,表示一个表名。

UNION在一个聚合函数的查询顺序条款被拒绝的ER_AGGREGATE_ORDER_FOR_UNION错误。例子:

选择1为foo联盟选择二阶最大(一);

13.2.11查询语法

子查询是一个SELECT在另一个表

所有的子查询的形式和操作要求SQL标准的支持,以及一些功能,MySQL特定的。

这里是一个查询的一个例子:

SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);

在这个例子中,SELECT * FROM t1 ...是的外部查询(或忘却),和(SELECT column1 FROM t2)是的子查询。我们说,子查询是嵌套在外部查询,事实上有可能在其他子查询嵌套查询,到一定深度。子查询必须始终出现在括号内。

子查询的主要优点是:

  • 他们允许查询,结构化的因此,它是可能的分离声明的每个部分。

  • 他们提供替代的方法来进行手术,否则将需要复杂的连接和工会。

  • 许多人发现子查询比复杂连接或工会更具可读性。事实上,这是子查询,给人叫早SQL原有观念的创新结构化查询语言

这里有一个例子证明的主要观点由SQL标准规定和支持MySQL对查询的语法:

DELETE FROM t1
WHERE s11 > ANY
 (SELECT COUNT(*) /* no hint */ FROM t2
  WHERE NOT EXISTS
   (SELECT * FROM t3
    WHERE ROW(5*t2.s1,77)=
     (SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM
      (SELECT * FROM t5) AS t5)));

子查询可以返回一个标量(单值),单排,单柱,或一个表(一个或多个行或多个列)。这些被称为标量,列,行和表的子查询。子查询返回一个特定的结果往往只能在一定的语境,在下面的章节中描述。

在语句中的子查询可以使用的类型的限制很少。子查询可以包含很多,一个普通的关键词或句子SELECT可以包含:不同的GROUP BY顺序LIMIT, joins, index hints,UNION构建、评论功能,等等。

子查询的语句可以是任何一个外:SELECTINSERTUPDATEDELETESET,或DO

在MySQL,你不能修改一个表,选择来自同一个表中查询。这适用于报表等DELETEINSERTREPLACEUPDATE(因为子查询,并可用于配置条款)LOAD DATA INFILE

对于优化器如何处理子查询的信息,参见第8.2.2条,“优化子查询、派生表、视图的引用,和公用表表达式”。对于一个在子查询中使用限制的讨论,包括子查询语法的某些形式的性能问题,看第4号、“限制查询”

13.2.11.1查询Scalar Operand

在其最简单的形式是一个标量子查询,子查询返回单个值。标量子查询是一个简单的操作,你可以使用几乎任何地方一个列值或文字是合法的,你可以期望它有这些特点,所有的操作数有:数据类型,长度,表明它可以NULL,等等。例如:

创建表T1(S1 S2 int,char(5)不为空);插入T1值(100,“ABCDE”);选择(选择S2从T1);

茶叶中的子查询SELECT返回一个值(“ABCDE”)有一个数据类型,CHAR,长度为5,字符集和整理等于实际上默认在CREATE TABLE时间,并显示在列中的值可以是无效的。用标量子查询选择的值为空性是不可复制的因为如果子查询结果是空的,结果是NULL。如果只是shown for the子查询,T1是空的,结果会是NULL尽管S2NOT NULL

有几个上下文中标量子查询不能使用。如果一个语句只允许一个文本值,不能使用子查询。例如,LIMIT需要文字的整数参数,和LOAD DATA INFILE需要一个字符串的文件名。你不能使用子查询来供应这些值。

当你看到的例子在下面的章节中包含相当简朴的构建(SELECT column1 FROM t1),想象您自己的代码包含了更加多样化和复杂的结构。

假如我们让两表:

CREATE TABLE t1 (s1 INT);
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (s1 INT);
INSERT INTO t2 VALUES (2);

然后执行SELECT

选择(选择S1 T1 T2);

其结果是2因为有一个排T2含有柱s1有一个值

标量子查询可以是表达式的一部分,但是记住,括号,即使子查询是一个操作数,提供了一个函数的参数。例如:

SELECT UPPER((SELECT s1 FROM t1)) FROM t2;

13.2.11.2比较使用子查询

一个查询最常用的形式:

non_subquery_operand comparison_operator (subquery)

哪里comparison_operator是这些运营商之一:

=  >  <  >=  <=  <>  !=  <=>

例如:

... WHERE 'a' = (SELECT column1 FROM t1)

MySQL也允许这样的构建:

non_subquery_operand LIKE (subquery)

在同一时间为子查询的唯一合法的地方是在一个比较正确的一面,你仍然可以找到一些旧的数据库管理系统,坚持这。

这是一个常见的子查询比较例不能连接。它在表中的所有行t1其中1值等于表中的最大值t2

SELECT * FROM t1  WHERE column1 = (SELECT MAX(column2) FROM t2);

这里是另一个例子,这是不可能的因为它涉及到一个加入聚合为一张桌子。它在表中的所有行t1包含一个值在一个给定的列发生两次:

SELECT * FROM t1 AS t  WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);

一个比较一个标量子查询,子查询必须返回一个标量。一个比较的子查询行构造函数,子查询必须行子查询返回的值的行数相同的行构造函数。看到第13.2.11.5,“行子”

13.2.11.3 subqueries任何,或一些,

语法:

operand comparison_operator ANY (subquery)
operand IN (subquery)
operand comparison_operator SOME (subquery)

哪里comparison_operator是这些运营商之一:

=  >  <  >=  <=  <>  !=

这个ANY关键词,它必须遵循一个比较运算符,意味着退货TRUE如果比较真的ANY在列的子查询返回的值。例如:

选择在S1 T1 S1 &#62;任何(选择S1 T2);

假设有表中的一行t1(10)。表达的是TRUE如果表T2包含(21,14,7)因为有一个值进入t2这是小于。表达的是FALSE如果表T2包含(20,10),或者表T2是空的。表达的是未知(这是,NULL如果表)T2包含(NULL,NULL,NULL)

当使用与查询、WordIN是一个别名= ANY。因此,这两种说法都是一样的:

SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 IN    (SELECT s1 FROM t2);

IN= ANY不使用时有一个表达式列表的同义词。IN可以把一个表达式列表,但= ANY不能。看到第12.3.2,“比较函数和操作符”

NOT IN不是一个别名<> ANY,但<> ALL。看到第13.2.11.4,“所有”的子查询

这个词SOME是一个别名任何。因此,这两种说法都是一样的:

SELECT s1 FROM t1 WHERE s1 <> ANY  (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2);

这个词的使用SOME是罕见的,但这个例子说明了为什么它可能是有用的。对大多数人来说,英语短语一个不等于任何B方法没有B等于一,但这不是什么是SQL语法。语法手段有一些B,是不平等的。使用<> SOME相反,有助于确保每个人都理解查询的真正含义。

13.2.11.4查询所有

语法:

operand comparison_operator ALL (subquery)

这个词ALL,必须遵循比较运算符,意味着退货TRUE如果比较真的ALL在列的子查询返回的值。例如:

选择在S1 T1 S1 &#62;所有(选择S1 T2);

假设有表中的一行t1(10)。表达的是TRUE如果表T2包含(-5,0,+5)因为大于三的值t2。表达的是错误的如果表t2包含(12,6,空- 100)因为有一个单一的价值12T2这是更大的比10。表达的是未知(这是,NULL如果表)T2包含(0,NULL,1)

最后,表达TRUE如果表T2是空的。所以,下面的表达式TRUE当表T2是空的:

SELECT * FROM t1 WHERE 1 > ALL (SELECT s1 FROM t2);

但这种表达NULL当表T2是空的:

SELECT * FROM t1 WHERE 1 > (SELECT s1 FROM t2);

此外,下列表达式NULL当表T2是空的:

SELECT * FROM t1 WHERE 1 > ALL (SELECT MAX(s1) FROM t2);

一般来说,表中NULL价值观空表边缘情况写子查询的时候,总是考虑你是否已经采取了这两种情况考虑。

NOT IN是一个别名<> ALL。因此,这两种说法都是一样的:

SELECT s1 FROM t1 WHERE s1 <> ALL (SELECT s1 FROM t2);
SELECT s1 FROM t1 WHERE s1 NOT IN (SELECT s1 FROM t2);

13.2.11.5行子查询

标量子查询返回单个值或列或列的值。一行子查询是一个查询的变种,返回单行可以返回多个列的值。行子查询比较合法经营者:

=  >  <  >=  <=  <>  !=  <=>

这里有两个例子:

SELECT * FROM t1
  WHERE (col1,col2) = (SELECT col3, col4 FROM t2 WHERE id = 10);
SELECT * FROM t1
  WHERE ROW(col1,col2) = (SELECT col3, col4 FROM t2 WHERE id = 10);

对于查询,如果表t2包含一个单排id = 10子查询返回一行。如果这一行col3COL4值等于col1COL2在任何行值t1,的哪里表达的是TRUE每个查询返回的T1排.如果t2col3col4值不相等的2col2的任何值T1行,表达FALSE该查询将返回空结果集。表达的是未知(这是,NULL)如果子查询不产生排。如果子查询产生多行,因为行子查询最多可一行返回发生错误。

关于每个操作员工作排的比较信息,看第12.3.2,“比较函数和操作符”

的表达(1,2)行(1,2)有时被称为行构造函数。两者是等价的。行构造函数返回行的查询必须包含相同数量的值。

行构造函数用于子查询返回两个或两个以上的列的比较。当一个查询返回一个列,这被视为标量值,而不是作为一个排,所以一排构造函数不能用于子查询不返回至少两列。因此,以下查询将失败,语法错误:

SELECT * FROM t1 WHERE ROW(1) = (SELECT column1 FROM t2)

排在其他情况下是合法的构造函数。例如,下面两个语句的语义等价的(并由优化器的处理方式相同):

SELECT * FROM t1 WHERE (column1,column2) = (1,1);
SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;

the following the request的查询的答案,发现在表中的所有行t1也存在于表T2

SELECT column1,column2,column3
  FROM t1
  WHERE (column1,column2,column3) IN
         (SELECT column1,column2,column3 FROM t2);

为更多的信息关于优化器和行构造函数,看第8.2.1.20,“行构造函数表达式优化”

13.2.11.6子查询与存在或不存在

如果子查询返回任何行在所有,EXISTS subquery真的,和NOT EXISTS subquery错误的。。。。。。。例如:

SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);

传统上,一个EXISTS子查询的开始选择*,但它可能开始SELECT 5SELECT column1或任何东西。MySQL忽略SELECT在这样一个查询表,所以实际上没有什么区别。

在前面的示例中,如果t2包含任何行,即使行不无效的价值观的EXISTS条件是真的。这实际上是一个不可能的例子,因为[NOT] EXISTS几乎总是包含子查询的相关性。这里有一些更现实的例子:

  • 什么样的店是在一个或更多的城市吗?

    SELECT DISTINCT store_type FROM stores
      WHERE EXISTS (SELECT * FROM cities_stores
                    WHERE cities_stores.store_type = stores.store_type);
    
  • 什么样的商店是没有城市的礼物吗?

    SELECT DISTINCT store_type FROM stores
      WHERE NOT EXISTS (SELECT * FROM cities_stores
                        WHERE cities_stores.store_type = stores.store_type);
    
  • 什么样的店是在所有的城市吗?

    SELECT DISTINCT store_type FROM stores s1
      WHERE NOT EXISTS (
        SELECT * FROM cities WHERE NOT EXISTS (
          SELECT * FROM cities_stores
           WHERE cities_stores.city = cities.city
           AND cities_stores.store_type = stores.store_type));
    

最后一个例子是一个双嵌套NOT EXISTS查询。那就是,它有一个不存在条款内NOT EXISTS条款.形式上,它回答的问题是不是一个城市一个店,是不存在的Stores?但它是更容易说嵌套不存在回答问题x真的所有y

13.2.11.7相关子查询

相关子查询是一个查询包含表的一个引用,也出现在外部查询。例如:

SELECT * FROM t1
  WHERE column1 = ANY (SELECT column1 FROM t2
                       WHERE t2.column2 = t1.column2);

注意,子查询包含一个参考一列t1,即使子查询条款不提表t1。因此,MySQL是在子查询,发现T1在外部查询

假设表t1集装箱column1 = 5column2 = 6同时,表;T2包含一行,column1 = 5column2 = 7。简单的表达... WHERE column1 = ANY (SELECT column1 FROM t2)真的,但是在这个例子中,该WHERE在子查询子句错误的(因为(5,6)不等于(5,7)),所以表达式作为一个整体FALSE

作用域规则:MySQL的评价从内到外。例如:

SELECT column1 FROM t1 AS x
  WHERE x.column1 = (SELECT column1 FROM t2 AS x
    WHERE x.column1 = (SELECT column1 FROM t3
      WHERE x.column2 = t3.column1));

在这份声明中,x.column2必须在表列T2因为SELECT column1 FROM t2 AS x ...重命名T2。它不在表列t1因为选择1从T1…是外部查询,更远的地方

子查询中的HAVING顺序子句,MySQL也在寻找外部选择列表的列名称。

某些情况下,一个相关子查询优化。例如:

val IN (SELECT key_val FROM tbl_name WHERE correlated_condition)

否则,他们是没有效率的,可能是缓慢的。重写查询作为一个连接可以提高性能。

在相关子查询聚合函数可以包含外部引用,提供的功能仅仅包含外部引用,和提供的功能是不包含在另一个函数或表达式。

13.2.11.8派生表

派生表生成表查询的范围内表达FROM条款。For example,in a子查询SELECT陈述条款派生表:

SELECT ... FROM (subquery) [AS] tbl_name ...

这个JSON_TABLE()函数生成一个表格,提供了另一种方式来创建一个派生表:

SELECT * FROM json_table(arg_list[你])tbl_name

这个[AS] tbl_name条款是强制性的因为在每个表条款必须有一个名字。在派生表中的任何列的名称必须是唯一的。另外,tbl_name可随后用于派生表的列名称括号列表:

选择从(subquery[你])tbl_namecol_list)…

人名的数目必须为表中的列数相同。

为了举例说明,假设你有此表:

CREATE TABLE t1 (s1 INT, s2 CHAR(5), s3 FLOAT);

这里是如何在使用子查询FROM条款,使用示例表:

插入T1值(1,1,1);插入T1值(2,2’,2);选择SB1、SB2、SB3从(选择S1 SB1,SB2 S2,S3 * 2 SB3从T1)为某人在SB1 &#62; 1;

结果:2, '2', 4.0

这里是另一个例子:假设你想知道一个分组表和的平均值。这不工作:

SELECT AVG(SUM(column1)) FROM t1 GROUP BY column1;

然而,这个查询提供了所需的信息:

SELECT AVG(sum_column1)
  FROM (SELECT SUM(column1) AS sum_column1
        FROM t1 GROUP BY column1) AS t1;

注意that the column name used within the(子查询sum_column1在外部查询确认)

这个源表的列的名字来自于它的选择列表:

mysql> SELECT * FROM (SELECT 1, 2, 3, 4) AS dt;
+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+

提供列名,遵循派生表名和列名括号列表:

mysql> SELECT * FROM (SELECT 1, 2, 3, 4) AS dt (a, b, c, d);
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+

派生表可以返回一个标量,列,行,或表。

派生表不相关子查询,或包含外部引用或引用其他表的相同SELECT

优化器确定信息源表在这样一种方式,体现他们不发生EXPLAIN。看到第8.2.2.3,“优化派生表、视图的引用,和公用表表达式”

这可能是在某些情况下,使用EXPLAIN SELECT要修改表中的数据。这可以在外部查询访问任何表内查询调用存储函数,改变一个或多个表中的行时。假设有两个表T1t2在数据库D1,和存储功能f1修改T2,创建如下所示:

CREATE DATABASE d1;
USE d1;
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
CREATE FUNCTION f1(p1 INT) RETURNS INT
  BEGIN
    INSERT INTO t2 VALUES (p1);
    RETURN p1;
  END;

引用函数直接在EXPLAIN SELECT没有影响T2,如下所示:

mysql> SELECT * FROM t2;
Empty set (0.02 sec)

mysql> EXPLAIN SELECT f1(5)\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: NULL
   partitions: NULL
         type: NULL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: NULL
     filtered: NULL
        Extra: No tables used
1 row in set (0.01 sec)

mysql> SELECT * FROM t2;
Empty set (0.01 sec)

这是因为SELECT声明没有参考任何表,可以看出在Extra列的输出。这也是以下正确嵌套SELECT

MySQL的&#62;EXPLAIN SELECT NOW() AS a1, (SELECT f1(5)) AS a2\G*************************** 1。行*************************** ID:1 select_type:主表:null类型:nullpossible_keys:空键:空key_len:零号:零排:空:空:没有额外的过滤表used1行集,警告(0.001秒)MySQL &#62;SHOW WARNINGS;------- ------ ------------------------------------------ |水平|代码|消息| ------- ------ ------------------------------------------ |注| 1249 |选择2降低优化| ------- ------ ------------------------------------------ 1排在设定(0秒)MySQL &#62;SELECT * FROM t2;空集(0.001秒)

然而,if the OuterSELECT引用任何表,优化器执行子查询语句以及:

MySQL的&#62;EXPLAIN SELECT * FROM t1 AS a1, (SELECT f1(5)) AS a2\G*************************** 1. row ***************************           id: 1  select_type: PRIMARY        table: <derived2>   partitions: NULL         type: systempossible_keys: NULL          key: NULL      key_len: NULL          ref: NULL         rows: 1     filtered: 100.00        Extra: NULL*************************** 2. row ***************************           id: 1  select_type: PRIMARY        table: a1   partitions: NULL         type: ALLpossible_keys: NULL          key: NULL      key_len: NULL          ref: NULL         rows: 1     filtered: 100.00        Extra: NULL*************************** 3. row ***************************           id: 2  select_type: DERIVED        table: NULL   partitions: NULL         type: NULLpossible_keys: NULL          key: NULL      key_len: NULL          ref: NULL         rows: NULL     filtered: NULL        Extra: No tables used3 rows in set (0.00 sec)mysql>SELECT * FROM t2;------ | C1 | ------ |五| ------一行集(0.001秒)

这也意味着EXPLAIN SELECT表如图所示的可能需要很长的时间来执行,因为BENCHMARK()函数中的每一行执行一次T1

EXPLAIN SELECT * FROM t1 AS a1, (SELECT BENCHMARK(1000000, MD5(NOW())));

13.2.11.9查询错误

有一些只适用于子查询错误。本节描述了他们。

  • 不支持子查询语法:

    ERROR 1235 (ER_NOT_SUPPORTED_YET)
    SQLSTATE = 42000
    Message = "This version of MySQL doesn't yet support
    'LIMIT & IN/ALL/ANY/SOME subquery'"
    

    这意味着MySQL不支持下列表格报表:

    SELECT * FROM t1 WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1)
    
  • 从查询的列数不正确:

    ERROR 1241 (ER_OPERAND_COL)
    SQLSTATE = 21000
    Message = "Operand should contain 1 column(s)"
    

    这个错误发生在这样的情况下:

    SELECT (SELECT column1, column2 FROM t2) FROM t1;
    

    你可以使用子查询返回多个列,如果目的是排的比较。在其他情况下,子查询必须是一个标量操作数。看到第13.2.11.5,“行子”

  • 从查询的行数不正确:

    ERROR 1242 (ER_SUBSELECT_NO_1_ROW)
    SQLSTATE = 21000
    Message = "Subquery returns more than 1 row"
    

    这个错误发生在子查询语句必须在一行返回,返回多行。考虑下面的例子:

    SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
    

    如果SELECT column1 FROM t2只返回一行,前面的查询工作。如果子查询返回多个行,会出现错误1242。在这种情况下,查询应改写为:

    SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2);
  • 在子查询中使用表错误:

    Error 1093 (ER_UPDATE_TABLE_USED)
    SQLSTATE = HY000
    Message = "You can't specify target table 'x'
    for update in FROM clause"
    

    如以下情况发生这种错误,试图修改一个表,选择来自同一个表的查询:

    UPDATE t1 SET column2 = (SELECT MAX(column1) FROM t1);
    

    你可以使用子查询的任务在一个UPDATE因为法律声明:UPDATEDELETE报表以及SELECT声明.然而,你不能使用相同的表(在这种情况下,表T1子查询)for both theFROM条款和更新目标

对于事务性存储引擎,一个子查询失败的原因整个语句失败。对于非事务性存储引擎,数据修改之前错误中保存。

13.2.11.10优化子查询

发展是持续的,所以没有优化提示长期可靠。下面的列表提供了一些有趣的技巧,你可能想玩。参见第8.2.2条,“优化子查询、派生表、视图的引用,和公用表表达式”

  • 使用查询子句中的子查询影响的行数或命令。例如:

    SELECT * FROM t1 WHERE t1.column1 IN
      (SELECT column1 FROM t2 ORDER BY column1);
    SELECT * FROM t1 WHERE t1.column1 IN
      (SELECT DISTINCT column1 FROM t2);
    SELECT * FROM t1 WHERE EXISTS
      (SELECT * FROM t2 LIMIT 1);
    
  • 使用子查询替换加入。例如,试试这个:

    SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN (
      SELECT column1 FROM t2);
    

    而这:

    SELECT DISTINCT t1.column1 FROM t1, t2
      WHERE t1.column1 = t2.column1;
    
  • 一些子查询可以转化为加入与旧版本的MySQL不支持子查询的兼容性。然而,在某些情况下,将查询到的加入可以提高性能。看到第13.2.11.11“重写查询,加入“

  • 移动条款从外到内的子查询。例如,使用此查询:

    SELECT * FROM t1
      WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);
    

    而这个查询:

    SELECT * FROM t1
      WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);
    

    另一个例子,使用此查询:

    SELECT (SELECT column1 + 5 FROM t1) FROM t2;
    

    而这个查询:

    SELECT (SELECT column1 FROM t1) + 5 FROM t2;
    
  • 使用行查询而不是一个相关子查询。例如,使用此查询:

    SELECT * FROM t1
      WHERE (column1,column2) IN (SELECT column1,column2 FROM t2);
    

    而这个查询:

    SELECT * FROM t1
      WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1
                    AND t2.column2=t1.column2);
    
  • 使用NOT (a = ANY (...))而不是a <> ALL (...)

  • 使用x = ANY (table containing (1,2))而不是x=1 OR x=2

  • 使用= ANY而不是存在

  • 相关子查询总是返回一行,IN总是慢于=。例如,使用此查询:

    SELECT * FROM t1
      WHERE t1.col_name = (SELECT a FROM t2 WHERE b = some_const);
    

    而这个查询:

    SELECT * FROM t1
      WHERE t1.col_name IN (SELECT a FROM t2 WHERE b = some_const);
    

这些技巧可能会导致程序走快或慢。使用MySQL等设备设施BENCHMARK()功能,你可以得到什么有助于你自己的情况的想法。看到12.14节,“信息功能”

一些优化,MySQL本身做:

  • MySQL执行相关子查询只有一次。使用EXPLAIN确保一个给定的查询是不相关的。

  • MySQL的改写IN全部ANY,和一些在试图利用这一选择列表中的列的索引查询子查询的可能性。

  • MySQL取代下列索引查找函数形式的子查询,这EXPLAINdescribes作为一个特殊的连接类型unique_subqueryindex_subquery):

    …………………(选择indexed_columnsingle_table…)
  • MySQL增强下列表达式的表达式MIN()MAX(),除非无效的值或空集合参与:

    value {ALL|ANY|SOME} {> | < | >= | <=} (uncorrelated subquery)
    

    例如,这WHERE条款:

    5 &#62;所有(选择X T)

    可能是由优化器这样处理:

    WHERE 5 > (SELECT MAX(x) FROM t)
    

参见MySQL内核:MySQL如何将子查询

13.2.11.11重写查询加入

有时会有其他的方法来测试的一组值的会员比使用子查询。另外,在某些情况下,它不仅可以编写一个查询,没有查询,但它可以更有效地利用这些技术,而不是使用子查询。其中之一是IN()构造:

例如,该查询:

SELECT * FROM t1 WHERE id IN (SELECT id FROM t2);

可以改写为:

SELECT DISTINCT t1.* FROM t1, t2 WHERE t1.id=t2.id;

查询:

SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2);
SELECT * FROM t1 WHERE NOT EXISTS (SELECT id FROM t2 WHERE t1.id=t2.id);

可以改写为:

SELECT table1.*
  FROM table1 LEFT JOIN table2 ON table1.id=table2.id
  WHERE table2.id IS NULL;

LEFT [OUTER] JOIN可以比同等的查询更快,因为服务器可以优化它完美的事实,是不特定的MySQL服务器单独。在SQL-92,外连接不存在,所以子查询来做某些事情的唯一方法。今天,MySQL服务器和其他许多现代数据库系统提供了一个广泛的外部联接类型。

MySQL服务器支持多表DELETE语句可以用来有效地删除基于信息从一个表中的行或从多个表同时。多表UPDATE语句也支持。看到第13.2.2,删除语法”,和第13.2.12,“更新语法”

13.2.12更新语法

UPDATE在桌上改变了Rows。

一个UPDATE语句可以从一个WITH条款定义公用表表达式内访问UPDATE。看到第13.2.13,“语法(公用表表达式)”

单表的语法:

UPDATE [LOW_PRIORITY] [IGNORE] table_reference
    SET assignment_list
    [WHERE where_condition]
    [ORDER BY ...]
    [LIMIT row_count]

value:
    {expr | DEFAULT}

assignment:
    col_name = value

assignment_list:
    assignment [, assignment] ...

多表的语法:

UPDATE [LOW_PRIORITY] [IGNORE] table_references
    SET assignment_list
    [WHERE where_condition]

对于单表的语法,UPDATE声明更新列中的现有行命名表的新价值。这个配置条款表明列修改,应给予他们的价值。每个值可以作为一个表达式,或关键字DEFAULT设定一个明确列为默认值。这个哪里条款,如果给定的,指定哪些行更新条件。没有WHERE子句,则更新所有行。如果顺序条款规定,行是指定的顺序更新。这个LIMIT条款放在可更新的行数限制。

对多个表的语法,UPDATE更新的行的每个表中的命名table_references满足条件。每个匹配的行被更新一次,即使它符合条件多次。多个表的语法,顺序LIMIT不能使用

对于分区表,无论是单一的单个和多个表的这一声明形式支持使用APARTITION期权作为表的参考部分。此选项需要一个或多个分区和子分区(或两者)。只有分区(或不会)列出检查比赛,和一排不在任何这些分区和子分区没有更新,是否满足where_condition或不

笔记

不同的情况下使用时PARTITION一个INSERTREPLACE声明,在本合同有效更新分区声明是即使在上市的分区没有行被认为是成功的(或不会)匹配where_condition

更多的信息和例子,看第22,“分区选择”

where_condition是为真的每一行被更新的表达式。为表达语法,看9.5节,“表达式”

table_referenceswhere_condition被指定为描述第13.2.10,选择“语法”

你所需要的UPDATE只有一列中引用特权UPDATE这实际上是更新。你需要的仅仅是SELECT任何列,读取但不能修改权限。

这个UPDATE声明支持下列修饰符:

  • LOW_PRIORITY修改,执行UPDATE被延迟直到没有其他客户端读取表。这仅影响存储引擎只使用表级锁(如MyISAMMEMORY,和合并

  • IGNORE改性剂,UPDATE语句不放弃即使错误发生在更新。行重复上一个独特的核心价值发生冲突不是更新的关键。行更新的值会导致数据转换错误更新到最接近的有效值代替。有关更多信息,参见在忽略关键词和严格的SQL模式比较

UPDATE IGNORE报表,包括那些具有顺序条款,标记为不安全的基于语句的复制。(这是因为在这行更新的顺序决定哪些行被忽略。)这样的语句产生在错误日志中的警告时,使用声明模式和写入使用基于行的格式时,使用二进制日志MIXED模式。(错误# 11758262,错误# 50439)看第17.2.1.3,“确定安全和不安全的语句在二进制日志”为更多的信息

如果你访问一个栏目从桌子上是一个表达更新,UPDATE使用列的当前值。例如,下面的语句集2一个超过其目前的价值:

UPDATE t1 SET col1 = col1 + 1;

以下语句中设置第二分配col2到目前(更新)2价值,而不是原来的col1值。结果是,2col2有相同的价值。这种行为不同于标准的SQL。

UPDATE t1 SET col1 = col1 + 1, col2 = col1;

单表UPDATE作业的评价一般都是从左到右。多表更新,没有保证的任务是在任何特定的顺序进行。

如果你设定了一个专栏,它目前拥有的价值,MySQL注意这不更新。

如果你更新一个栏目,已申报NOT NULL通过设置无效的,如果严格的SQL模式启用发生错误;否则,该列设置为列的数据类型和警告计数的隐式的默认值是增加的。隐式的默认值0对于数值类型,空字符串(&#39; &#39;)为字符串类型,和日期和时间类型的值。看到11.7节,“数据类型的默认值”

如果生成的更新列明确,唯一被允许的值DEFAULT。有关生成的列的信息,参见第13.1.18.8,“创建表和生成的列”

UPDATE返回的行数,实际上改变了。这个mysql_info()C API函数返回的匹配和更新和警告发生在数行数UPDATE

你可以使用LIMIT row_count限制的范围UPDATE。一极限从句是一行匹配约束。该声明一旦有发现row_count行,满足哪里条款,他们是否真的改变了。

如果一个UPDATE声明包括顺序条款,一排排的子句指定的顺序更新。这在某些情况下,可能会导致一个错误是有用的。假设一个表t包含一个列身份证件有一个唯一索引。下面的语句将失败,重复键错误,根据订单中的行更新:

UPDATE t SET id = id + 1;

例如,如果表包含1和2的id柱和1 2 2更新之前更新,出现错误。为了避免这个问题,添加一个顺序条款引起较大的行id值被更新之前,那些较小的值:

UPDATE t SET id = id + 1 ORDER BY id DESC;

你也可以做UPDATE业务涵盖多个表。但是,您不能使用顺序LIMIT与多个表UPDATE。这个table_references子句列出参与联接的表。它的语法描述第13.2.10.2,加入“语法”。下面是一个例子:

UPDATE items,month SET items.price=month.price
WHERE items.id=month.id;

前面的例子显示了一个内部连接使用逗号操作符,但多个表UPDATE语句可以使用任何类型的连接允许SELECT报表,如左连接

如果您使用多个表UPDATE声明中涉及InnoDB其中有外键约束的表,MySQL的优化器可能会以不同于他们的父/子关系过程表。在这种情况下,该语句失败并回滚。相反,更新一个表和依靠ON UPDATE的能力,InnoDB为使其他表进行相应的修改。看到第15.8.1.6,“InnoDB和外键约束”

你不能更新一个表,选择来自同一个表中查询。

一个UPDATE使用存储引擎,如分区表MyISAM使用表级锁只有分区包含匹配的行的更新陈述WHERE条款,只要没有分区表列被更新。(存储引擎等InnoDB使用行级锁,没有锁定的分区发生。)的更多信息,参见分区和锁定

13.2.13语法(公用表表达式)

公用表表达式(CTE)是一个命名的临时结果集内存在单个语句的范围,可以称后的声明,可能多次。下面的讨论描述如何写语句,使用热膨胀系数。

关于热膨胀系数的优化信息,看第8.2.2.3,“优化派生表、视图的引用,和公用表表达式”

额外资源

这些文章包含在MySQL使用CTE的附加信息,包括很多的例子:

公用表表达式的语法

指定公用表表达式,使用WITH条款,有一个或多个用逗号分隔的几个小节。每个小节提供了一个查询产生的结果集,并将名字与子查询。下面的示例定义CTE命名cte1cte2WITH条款,是指他们在顶层SELECT如下WITH条款:

WITH  cte1 AS (SELECT a, b FROM table1),  cte2 AS (SELECT c, d FROM table2)SELECT b, d FROM cte1 JOIN cte2WHERE cte1.a = cte2.c;

在一份声明中包含WITH条款,每个CTE名称可以引用来访问相应的CTE结果集。

CTE的名字可以在其他企业参考,使企业可以基于其他CTE定义。

CTE可以参考本身定义一个递归CTE。递归CTE的常见应用包括序列生成和遍历层次或树状结构的数据。

公用表表达式是DML语句语法的一个可选部分。他们定义的使用WITH条款:

with_clause:[ ]与递归cte_name[(col_name【,col_name](AS)]subquery)[,cte_name[(col_name【,col_name](AS)]subquery)]…

cte_name名称单公用表表达式可以作为一种参考表在声明中包含WITH条款.

这个subquery部分为(subquery被称为热膨胀系数的子查询是什么产生CTE结果集。下面的括号AS是必需的

公用表表达式的递归查询是指如果它自己的名字。这个RECURSIVE关键词必须如果CTE在包括WITH条款是递归的。有关更多信息,参见递归公用表表达式

对于一个给定的CTE发生如下列名的测定:

  • 如果一名括号列表如下,CTE的名字,这些名字列名称:

    WITH cte (col1, col2) AS
    (
      SELECT 1, 2
      UNION ALL
      SELECT 3, 4
    )
    SELECT col1, col2 FROM cte;
    

    列表中的名称必须为结果集的列数相同。

  • 否则,吃the column names from the list of the First选择SELECT为(subquery部分:

    与热膨胀系数为(选择1 col1,col2两作为联盟的所有选择的三、四选择col1,col2)从CTE;

WITH在这些情况下,许可条款:

  • 在开始SELECTUPDATE,和DELETE声明.

    与与选择…与更新…删除
  • 在子查询的开始(包括派生表子查询):

    SELECT ... WHERE id IN (WITH ... SELECT ...) ...
    SELECT * FROM (WITH ... SELECT ...) AS dt ...
    
  • 紧接SELECT对于报表,包括SELECT声明:

    插入…与替代选择…与创建表的选择…与创建视图的选择…与声明游标SELECT…与解释选择…与选择

只有一个WITH条款是允许在同一水平。WITH然后WITH在同一水平上是不允许的,所以这是违法的:

与cte1(……)的选择与cte2(……)…………………

做陈述的法律,使用一个单一的WITH条款,将几个小节用逗号:

与cte1的cte2(……),(……)的选择…………………

然而,声明可以包含多个WITH条款,如果他们发生在不同的水平:

与cte1为(选一)SELECT * FROM(与cte2为(选择)选择*从cte2加入cte1)为DT;

WITH子句可以定义一个或多个公用表表达式,但每个CTE名称必须是独特的条款。这是违法的:

与cte1的cte1(……),(……)的选择…………………

做陈述的法律,具有独特的名称定义热膨胀系数:

WITH cte1 AS (...), cte2 AS (...) SELECT ...

CTE可以参考本身或其他CTEs:

  • a Self-Reference Cte is Rev.1 .

  • CTE可以引用CTE定义在相同的前WITH条款,而不是那些定义。

    这个约束规则相互递归cte,哪里cte1推荐信cte2cte2推荐信cte1。其中一个引用必须是CTE定义后,这是不允许的。

  • CTE在一个给定的查询块可以参考中定义的查询块在更外层的热膨胀系数,但不热膨胀系数定义的查询块在一个范围内。

为解决引用的对象具有相同的名称,派生表的热膨胀系数和热膨胀系数,隐藏;隐藏基表,TEMPORARY表和视图。名称解析时通过搜索在同一个查询块的对象,然后在转外块而没有找到对象的名称。

CTE不能包含外部引用。与派生表,并禁止外部引用,这是一个MySQL的限制,没有限制的SQL标准。额外的语法考虑具体的递归cte,看递归公用表表达式

递归公用表表达式

递归公用表表达式是一个有一个的子查询,指的是自己的名字。例如:

WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte WHERE n < 5
)
SELECT * FROM cte;

当执行语句产生这样的结果,一个列包含一个简单的线性序列:

+------+
| n    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
+------+

递归CTE具有这样的结构:

  • 这个WITH条款必须开始用递归如果任何CTE在WITHrefers to Clause本身。(如果没有CTE refers to itself,递归是允许的但不是必需的。)

    如果你忘记了RECURSIVE一个递归CTE,这个错误的一个可能的结果是:

    (错误:表“42s02 1146)cte_name”不存在
  • 递归CTE查询有两部分,分开UNION [ALL]UNION DISTINCT

    选择返回初始行并集合allselect…返回行集

    第一SELECT产生的热膨胀系数的初始行,不是指CTE的名字。第二SELECT产生额外的行和递归参照其CTE的名字条款.递归结束时,这一部分不产生新的行。因此,递归CTE由一个非递归SELECT部分依次递推SELECT部分

    每个SELECT部分本身可以是一个联盟的多SELECT声明.

  • 热膨胀系数的结果列的类型是从非列的类型推断SELECT的一部分,和列都为空。对于类型的确定、递归SELECT部分被忽略

  • 如果非递归和递归部分是分开的UNION DISTINCT,消除了重复的行。这对于执行传递闭包查询是有用的,以避免无限循环。

  • 每一次迭代的递归部分的操作只对上一次迭代产生的行。如果递归部分有多个查询块,每个查询块迭代预定指定的顺序,每个查询块操作,已通过其先前的迭代或其他查询块自从上一次迭代的结束行。

递归CTE查询证明这非递归部分检索一行产生初始行集:

SELECT 1

CTE查询也有这个递归部分:

SELECT n + 1 FROM cte WHERE n < 5

在每个迭代,这SELECT生产排一个新的价值,一个比一个大的价值N从以前的行集。第一次迭代操作的初始行集(1)而产生的1+1=2;第二迭代运行在第一次迭代的行集(2)而产生的2+1=3而且如此这个连续不断地重新思考,什么时候?n不再是小于5

如果一个CTE递归部分为柱相比,非递归部分产生更大的价值,可能有必要扩大栏目在非递归部分避免数据截断。考虑这一说法:

WITH RECURSIVE cte AS
(
  SELECT 1 AS n, 'abc' AS str
  UNION ALL
  SELECT n + 1, CONCAT(str, str) FROM cte WHERE n < 3
)
SELECT * FROM cte;

在非严格的SQL语句产生这种输出方式:

+------+------+
| n    | str  |
+------+------+
|    1 | abc  |
|    2 | abc  |
|    3 | abc  |
+------+------+

这个str列的值都是“ABC”因为不隐含SELECT确定列的宽度。因此,更大的STR由递归产生价值SELECT被截断

严格的SQL模式,语句产生一个错误:

ERROR 1406 (22001): Data too long for column 'str' at row 1

为了解决这个问题,这样的声明不产生截断或错误使用CAST()在非递归SELECT为了使STR柱宽:

WITH RECURSIVE cte AS
(
  SELECT 1 AS n, CAST('abc' AS CHAR(20)) AS str
  UNION ALL
  SELECT n + 1, CONCAT(str, str) FROM cte WHERE n < 3
)
SELECT * FROM cte;

现在语句产生这样的结果,没有截断:

+------+--------------+
| n    | str          |
+------+--------------+
|    1 | abc          |
|    2 | abcabc       |
|    3 | abcabcabcabc |
+------+--------------+

列访问的名字,没有地位,这意味着列在递归部分可以有一个不同的位置的非递归部分列,因为这CTE说明:

WITH RECURSIVE cte AS
(
  SELECT 1 AS n, 1 AS p, -1 AS q
  UNION ALL
  SELECT n + 1, q * 2, p * 2 FROM cte WHERE n < 5
)
SELECT * FROM cte;

因为p在一排的是来自Q在前一排,反之亦然,正负值互换位置在每个连续的行输出:

+------+------+------+
| n    | p    | q    |
+------+------+------+
|    1 |    1 |   -1 |
|    2 |   -2 |    2 |
|    3 |    4 |   -4 |
|    4 |   -8 |    8 |
|    5 |   16 |  -16 |
+------+------+------+

一些语法的限制适用于递归CTE查询:

  • 递归SELECT部分不能包含这些结构:

    • 汇总等功能SUM()

    • 窗函数

    • GROUP BY

    • ORDER BY

    • LIMIT

    • DISTINCT

    此限制不适用于非递归SELECT一个递归CTE的部分。禁止在不同的仅适用于UNION成员;结合不同的是允许的

  • 递归SELECT部分必须引用CTE的只有一次,只有在其条款,没有任何查询。可参考表以外的CTE和加入他们的热膨胀系数。如果用在像这样的连接,CTE不得对右侧LEFT JOIN

这些约束来自SQL标准,比其他的MySQL特定的删减ORDER BY极限,和DISTINCT

递归CTE,EXPLAIN递归输出行SELECT部分显示递归Extra专栏

成本估算显示EXPLAIN代表成本每迭代,这可能从总成本有很大的不同。优化器不能预测迭代的次数,因为它无法预测何时哪里条款将成为虚假

CTE实际成本也可以通过结果集大小的影响。CTE产生多行可能需要一个内部临时表大到足以被转换从内存到磁盘上的格式和可能遭受的性能损失。如果是这样的话,增加允许的内存中的临时表的大小可以提高性能;看第8.4.4,“MySQL”使用内部临时表

限制递归公用表表达式

递归cte的递归是很重要的SELECT部分包括终止递归的条件。作为一个发展技术防范失控的递归CTE,可以通过将执行时间限制强行终止:

  • 这个cte_max_recursion_depth系统变量执行CTE在递归级数的极限。服务器终止执行任何递归CTE比这个变量的值水平。

  • 这个max_execution_time系统变量强制执行超时SELECT在当前会话中执行的语句。

  • 这个MAX_EXECUTION_TIME优化器提示执行每个查询执行超时的SELECT声明在它出现

假设一个递归CTE是误写没有递归执行的终止条件:

WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte
)
SELECT * FROM cte;

默认情况下,cte_max_recursion_depth有一个价值一千,造成的热膨胀系数在过去一千层次递归终止。应用程序可以更改会话值来调整他们的要求:

SET SESSION cte_max_recursion_depth = 10;      -- permit only shallow recursionSET SESSION cte_max_recursion_depth = 1000000; -- permit deeper recursion

你也可以设置全局cte_max_recursion_depth影响开始所有会议随后的价值。

查询执行从而做出缓慢或在环境中,有理由设置cte_max_recursion_depth价值很高,另一方面要防范深度递归是设定每一个会话超时。这样做,执行下面的语句之前执行CTE语句:

SET max_execution_time = 1000; -- impose one second timeout

另外,包括优化器提示在CTE语句本身:

WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte
)
SELECT /*+ MAX_EXECUTION_TIME(1000) */ * FROM cte;

如果一个递归查询没有执行时间限制进入一个无限循环,你可以终止它从另一个会话中使用KILL QUERY。在会议期间,用于运行查询的客户端程序可以杀死查询提供了一种方法。例如,在MySQL,打字控制C中断当前的声明

递归公用表表达式的例子

如前所述,递归公用表表达式(CTE)经常用于序列生成和遍历层次或树状结构的数据。这一部分展示了一些简单的这些技术的例子。

斐波那契数列的生成

斐波纳契数列开始与两数字0和1(或1、1),每个号码后,都是前两个数字的总和。递归公用表表达式可以如果每行由递归产生生成斐波那契数列SELECT能够从系列前两个数。以下的热膨胀系数产生10号系列采用0和1作为第一个数字:

WITH RECURSIVE fibonacci (n, fib_n, next_fib_n) AS(  SELECT 1, 0, 1  UNION ALL  SELECT n + 1, next_fib_n, fib_n + next_fib_n    FROM fibonacci WHERE n < 10)SELECT * FROM fibonacci;

产生这一结果的CTE:

+------+-------+------------+
| n    | fib_n | next_fib_n |
+------+-------+------------+
|    1 |     0 |          1 |
|    2 |     1 |          1 |
|    3 |     1 |          2 |
|    4 |     2 |          3 |
|    5 |     3 |          5 |
|    6 |     5 |          8 |
|    7 |     8 |         13 |
|    8 |    13 |         21 |
|    9 |    21 |         34 |
|   10 |    34 |         55 |
+------+-------+------------+

如何在CTE的作品:

  • n是一个显示列表示该行包含N世纪的斐波那契数。例如,8 Fibonacci数的13。

  • 这个fib_n哥伦比亚N

  • 这个next_fib_n列显示下一个斐波那契数后数N。本栏目提供了一系列价值到下一行,这样行可以在其生产的前两系列值的总和fib_n专栏

  • 递归结束时n达到10。这是一个任意的选择,限制产量的一小部分的行。

上面的输出结果显示整个CTE。选择只是其中的一部分,添加适当的WHERE条款的顶层SELECT。例如,选择第八个Fibonacci数,这样做:

MySQL的&#62;WITH RECURSIVE fibonacci ...SELECT fib_n FROM fibonacci WHERE n = 8;------- | fib_n | ------- | 13 | -------
日期序列生成

公用表表达式可以产生一系列连续的日期,从而产生的摘要,包括系列中的所有日期一行是有用的,包括在总结的数据代表的不是约会。

假设一个表包含这些行的销售数字:

mysql> SELECT * FROM sales ORDER BY date, price;
+------------+--------+
| date       | price  |
+------------+--------+
| 2017-01-03 | 100.00 |
| 2017-01-03 | 200.00 |
| 2017-01-06 |  50.00 |
| 2017-01-08 |  10.00 |
| 2017-01-08 |  20.00 |
| 2017-01-08 | 150.00 |
| 2017-01-10 |   5.00 |
+------------+--------+

此查询每天的销售总结:

mysql> SELECT date, SUM(price) AS sum_price
       FROM sales
       GROUP BY date
       ORDER BY date;
+------------+-----------+
| date       | sum_price |
+------------+-----------+
| 2017-01-03 |    300.00 |
| 2017-01-06 |     50.00 |
| 2017-01-08 |    180.00 |
| 2017-01-10 |      5.00 |
+------------+-----------+

然而,这个结果包含在日期范围代表的不是日期跨越的表。因此,代表范围内所有的日期可以使用递归CTE产生那套生产日期,同一LEFT JOIN对销售数据

这里是CTE生成日期范围系列:

WITH RECURSIVE dates (date) AS
(
  SELECT MIN(date) FROM sales
  UNION ALL
  SELECT date + INTERVAL 1 DAY FROM dates
  WHERE date + INTERVAL 1 DAY <= (SELECT MAX(date) FROM sales)
)
SELECT * FROM dates;

产生这一结果的CTE:

+------------+
| date       |
+------------+
| 2017-01-03 |
| 2017-01-04 |
| 2017-01-05 |
| 2017-01-06 |
| 2017-01-07 |
| 2017-01-08 |
| 2017-01-09 |
| 2017-01-10 |
+------------+

如何在CTE的作品:

  • 非递归SELECT生产日期范围最低日期跨越的特价

  • 每一行由递归产生SELECT增加一天的前一行生产日期。

  • 递归结束后的日期到达的日期范围最高日期跨越的sales

一个连接LEFT JOIN反对特价表生产销售汇总与该范围内的每个数据行:

WITH RECURSIVE dates (date) AS
(
  SELECT MIN(date) FROM sales
  UNION ALL
  SELECT date + INTERVAL 1 DAY FROM dates
  WHERE date + INTERVAL 1 DAY <= (SELECT MAX(date) FROM sales)
)
SELECT dates.date, COALESCE(SUM(price), 0) AS sum_price
FROM dates LEFT JOIN sales ON dates.date = sales.date
GROUP BY dates.date
ORDER BY dates.date;

输出看起来像这样:

+------------+-----------+
| date       | sum_price |
+------------+-----------+
| 2017-01-03 |    300.00 |
| 2017-01-04 |      0.00 |
| 2017-01-05 |      0.00 |
| 2017-01-06 |     50.00 |
| 2017-01-07 |      0.00 |
| 2017-01-08 |    180.00 |
| 2017-01-09 |      0.00 |
| 2017-01-10 |      5.00 |
+------------+-----------+

需注意的几点:

  • 是查询效率低下,特别是有MAX()子查询执行的每一行中的递归SELECT?检查解释结果表明:优化了效率。

  • 使用COALESCE()避免显示无效的sum_price柱天,没有销售数据出现在特价

药草数据

递归公用表表达式用于遍历数据,形成一个层次。考虑到这些语句创建一个小的数据集显示,每个员工在一个公司,雇员的姓名和身份证号码,和员工的经理的身份。顶级员工(首席执行官),有一个教练的身份NULL(没有教练)

创建员工信息表(ID为主键,名称为varchar(100)不为空,manager_id int空,指数(manager_id),外键(manager_id)参考员工(ID));插入员工价值(333,“斯米”,null),#斯米是首席执行官(manager_id是空的)(198,“约翰”,333),#约翰ID 198和报告333(Yasmina)(692,“Tarek”,333),(29,“佩德罗”,198),(4610,“莎拉”,29),(72,“彼埃尔”,29),(123,“阿迪力”,692);

由此产生的数据集,看起来像这样:

mysql> SELECT * FROM employees ORDER BY id;
+------+---------+------------+
| id   | name    | manager_id |
+------+---------+------------+
|   29 | Pedro   |        198 |
|   72 | Pierre  |         29 |
|  123 | Adil    |        692 |
|  198 | John    |        333 |
|  333 | Yasmina |       NULL |
|  692 | Tarek   |        333 |
| 4610 | Sarah   |         29 |
+------+---------+------------+

对于每个员工的管理链的组织结构图(即路径从总裁到员工),使用递归CTE:

WITH RECURSIVE employee_paths (id, name, path) AS
(
  SELECT id, name, CAST(id AS CHAR(200))
    FROM employees
    WHERE manager_id IS NULL
  UNION ALL
  SELECT e.id, e.name, CONCAT(ep.path, ',', e.id)
    FROM employee_paths AS ep JOIN employees AS e
      ON ep.id = e.manager_id
)
SELECT * FROM employee_paths ORDER BY path;

热膨胀系数产生的输出:

+------+---------+-----------------+
| id   | name    | path            |
+------+---------+-----------------+
|  333 | Yasmina | 333             |
|  198 | John    | 333,198         |
|   29 | Pedro   | 333,198,29      |
| 4610 | Sarah   | 333,198,29,4610 |
|   72 | Pierre  | 333,198,29,72   |
|  692 | Tarek   | 333,692         |
|  123 | Adil    | 333,692,123     |
+------+---------+-----------------+

如何在CTE的作品:

  • 非递归SELECT产生的首席执行官行(一行无效的经理ID)

    这个path柱加宽CHAR(200)确保有较长的房间path由递归产生价值SELECT

  • 每一行由递归产生SELECT发现所有的员工直接由前一行产生一个员工。对每一个这样的员工,该行包括雇员ID和名称,和员工管理链。外链是经理的链,与雇员ID添加到结束。

  • 递归结束时,员工没有人向他们报告。

对于一个特定的员工或员工找到路径,添加WHERE条款的顶层SELECT。例如,显示Tarek和莎拉的结果,修改SELECT这样地:

MySQL的&#62;WITH RECURSIVE ...SELECT * FROM employees_extendedWHERE id IN (692, 4610)ORDER BY path;------ ------- --------------------- | ID名称| |路径| ------ ------- --------------------- | 4610 |莎拉| 333198,294610 | | 692 | Tarek | 333692 | ------ ------- ---------------------

公用表表达式相类似的构造

公用表表达式(CTE)与派生表在某些方面:

  • 结构的命名

  • 无论是构建单个语句的范围内存在。

因为这些相似,热膨胀系数和派生表通常可以互换使用。作为一个平凡的例子,这些陈述是等价的:

WITH cte AS (SELECT 1) SELECT * FROM cte;
SELECT * FROM (SELECT 1) AS dt;

然而,乡镇企业有派生表的一些优点:

  • 派生表可以被引用,只有一次在一个查询。CTE可多次引用。使用派生表结果的多个实例,你必须得到多次。

  • CTE可自引用(递归)。

  • 一个CTE可以参考另一个。

  • CTE可能更容易阅读的时候它的定义出现在开始的声明,而不是嵌入。

乡镇企业有类似的表创建CREATE [TEMPORARY] TABLE但不需要定义或下降显。对于一个CTE,你不需要权限来创建表。

13.3事务和锁的陈述

MySQL支持本地事务(在一个给定的客户端会话)通过报表等SET autocommitSTART TRANSACTIONCOMMIT,和ROLLBACK。看到第13.3.1条,“开始事务,提交和回滚语法”。XA事务的支持使MySQL参与分布式事务以及。看到第13.3.8,“XA事务”

13.3.1启动事务,提交和回滚语法

START TRANSACTION
    [transaction_characteristic [, transaction_characteristic] ...]

transaction_characteristic:
    WITH CONSISTENT SNAPSHOT
  | READ WRITE
  | READ ONLY

BEGIN [WORK]
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]
SET autocommit = {0 | 1}

这些陈述提供过度使用的控制交易

  • START TRANSACTION开始开始一个新的交易

  • COMMIT提交当前事务,使其改变永久。

  • ROLLBACK回滚当前事务,取消其变化。

  • SET autocommit禁用或启用默认的自动提交模式为当前会话。

默认情况下,MySQL运行自动提交模式启用。这意味着,当你执行一个语句,更新(修改)一个表,MySQL存储在磁盘上的更新使其永久。这种变化不能回滚。

禁用自动提交模式隐含的一系列语句,使用START TRANSACTION声明:

START TRANSACTION;SELECT @A:=SUM(salary) FROM table1 WHERE type=1;UPDATE table2 SET summary=@A WHERE type=1;COMMIT;

START TRANSACTION,将保持禁用状态直到你结束交易承诺ROLLBACK。自动提交模式然后恢复到以前的状态。

START TRANSACTION允许多个修饰符控制交易特征。指定多个修饰符,用逗号分开。

  • 这个WITH CONSISTENT SNAPSHOT改变星座一致性读存储引擎,能够做到。这仅适用于InnoDB。的作用是发出同样的开始交易其次是SELECT从任何InnoDB表看到第15.5.2.3,“一致的非锁定读”。这个WITH CONSISTENT SNAPSHOT改性剂不改变当前的交易隔离级别,所以它提供了一个一致的快照,只有当前的隔离级别是一个允许一致性读。唯一的隔离级别允许读是一致的REPEATABLE READ。对于所有其他隔离级别,这一致的快照条款被忽视。报警时产生的WITH CONSISTENT SNAPSHOT条款被忽视

  • 这个READ WRITE只读修饰符设置事务访问模式。他们允许或禁止更改用于交易表。这个READ ONLY限制防止事务修改或锁定交易和非事务表,对其他事务可见;交易仍可以修改或锁定临时表。

    MySQL允许额外的优化查询InnoDB表当事务是只读的。指定只读确保这些优化应用的情况下,只读状态,不能自动确定。看到第8.5.3,“优化InnoDB只读事务”更多信息

    如果未指定访问模式,默认的模式应用。除非默认已经改变,它是读/写。不允许指定READ WRITE只读在同一个声明

    在只读模式下,它仍然可能改变创建表TEMPORARY使用DML语句关键字。DDL语句的更改不允许,就像永久表。

    有关事务访问模式的更多信息,包括更改默认的方式,看第13.3.7,“事务语法”

    如果read_only系统变量是启用的,明确的开始一个事务开始读写事务处理要求CONNECTION_ADMINSUPER特权

重要

许多API用于写入MySQL客户端应用程序(如JDBC)开始交易,可以提供自己的方法(有时应该)被用来代替发送START TRANSACTION从客户声明。看到27章,连接器和API文件,或为你的API的更多信息。

禁用自动提交模式明确,使用以下语句:

SET autocommit=0;

在禁用自动提交模式设置autocommit变为零,交易安全表的更改(例如InnoDBNDB)不是永久立即。你必须使用COMMIT保存更改磁盘或回降忽视的变化

autocommit是一个会话变量必须为每个会话。为每个新连接禁用自动提交模式,看到的描述autocommit系统变量第5.1.7,服务器“系统变量”

BEGIN开始工作支持别名START TRANSACTION发起一个交易开始交易是标准的SQL语法,是推荐的方式开始一个事务,并允许修改器BEGIN

这个BEGIN从使用differs statement of the开始关键词:开始BEGIN ... END复合语句。the latter does not开始交易。See第13.6.1,”开始…端复合语句语法”

笔记

在所有的存储程序(存储过程和函数、触发器和事件),解析器将BEGIN [WORK]构象的研究BEGIN ... END块。在这样的背景下开始交易START TRANSACTION相反

可选WORK关键词负载is for承诺ROLLBACK是的,RELEASE条款.RELEASE可用于额外的控制权交易完成。的价值completion_type系统变量决定默认完成行为。看到第5.1.7,服务器“系统变量”

这个AND CHAIN条款产生了一个新的交易,只要当前的一端开始,和新的交易具有相同的隔离级别为刚终止交易。新的交易也使用相同的访问模式(读写READ ONLY)由于刚刚终止交易。这个发布条款导致服务器断开当前客户端会话终止当前事务后。包括NO关键词抑制RELEASE这是一个很好的事情completion_type系统变量设置导致链接或默认释放完成。

开始一个事务造成任何挂起的事务提交。看到13.3.3部分,”声明,因为一个隐含的承诺”为更多的信息

开始一个事务也导致表锁收购LOCK TABLES被释放,仿佛你已经执行的UNLOCK TABLES。开始一个事务不释放一个全局读锁,获得FLUSH TABLES WITH READ LOCK

最好的结果是,交易应该只使用表由一个事务安全的存储引擎管理的执行。否则,以下问题发生:

  • 如果你使用表从多个事务安全的存储引擎(如InnoDB),和事务隔离级别是不SERIALIZABLE,这是可能的,当一个事务提交时,另一个正在进行的交易,使用相同的表只能看到一些由第一个事务的更改。这是交易的非原子混合引擎和保证结果不一致。(如果混合引擎交易中是很少见的,你可以使用SET TRANSACTION ISOLATION LEVEL设置隔离级别SERIALIZABLE在每一个交易的基础是必要的。)

  • 如果你使用表格不安全交易在交易,那些表更改存储一次,而对自动提交模式的现状。

  • 如果你的问题ROLLBACK更新事务中非事务表后的声明中,一个ER_WARNING_NOT_COMPLETE_ROLLBACK警告出现。事务安全表的更改回滚,但不改变非事务安全表。

每个事务存储在二进制日志在一块,在COMMIT。这是回滚事务不登录。(例外:对非事务表不能回滚修改。如果一个事务回滚包括非事务表的修改,整个交易记录与ROLLBACK声明最后确保修改的非事务表)看到的复制。5.4.4节,“二进制日志”

您可以更改交易与隔离级别或访问模式SET TRANSACTION声明。看到第13.3.7,“事务语法”

回滚可以是一个缓慢的操作,可以隐式的用户不必明确要求它发生(例如,当一个错误发生)。因为这个,SHOW PROCESSLIST显示器滚回去State本次会议专栏,不仅为显式回滚执行的ROLLBACK声明还隐式回滚

笔记

在MySQL 8,BEGIN承诺,和ROLLBACK不受影响--replicate-do-db--replicate-ignore-db规则

13.3.2语句不能回滚

有些语句不能回滚。总的来说,这些措施包括数据定义语言(DDL)语句,如那些创建或删除数据库,那些创造,下降,或更改表或存储过程。

你应该设计你的交易不包括这样的语句。如果你发布一个声明在一个事务不能回滚的早期,然后另一个声明后的失败,不能充分发挥作用的事务被回滚在这样的情况下,通过发行ROLLBACK声明

13.3.3陈述引起隐式提交

本节中列出的语句(和任何对它们的同义词)隐含在当前会话结束任何交易活动,如果你已经做了COMMIT在执行该语句

大多数这些报表也引起隐式提交后执行。其意图是处理自己的特殊交易每个这样的语句。交易控制和锁定的陈述是例外:如果一个隐式提交之前发生的执行,另一个不发生后。

13.3.4保存点回滚保存点和两个保存点语法,释

SAVEPOINT identifier
ROLLBACK [WORK] TO [SAVEPOINT] identifier
RELEASE SAVEPOINT identifier

InnoDB支持SQL语句SAVEPOINTROLLBACK TO SAVEPOINTRELEASE SAVEPOINT与可选的工作关键词ROLLBACK

这个SAVEPOINT语句设置一个指定的事务的保存点个名identifier。如果当前事务有一个同名的保存点,老点被删除,新的设置。

这个ROLLBACK TO SAVEPOINT语句回滚事务到指定的保存点不终止交易。修改后保存点设置了行的当前事务在回滚撤消,但InnoDB释放行锁,保存点后存储在存储器中。(一个新插入的行,锁的信息被存储在列;交易ID进行锁不分别存储在内存中。在这种情况下,行锁是在撤销释放。)保存点,分别设置在稍后的时间比指定的保存点删除。

如果ROLLBACK TO SAVEPOINT语句将返回以下错误,这意味着不存在具有指定名称的保存点:

错误1305(42000):保存点identifier不存在

这个RELEASE SAVEPOINT语句删除指定从当前事务的保存点的设置保存点。没有提交或回滚的发生。如果保存点不存在,这是一个错误。

所有保存点当前的交易如果你执行一个删除COMMIT,或ROLLBACK那不叫一个保存点

一个新的保存点水平时创建一个存储调用函数或触发器被激活。在以前的水平成为不可用,因此不在新的水平冲突的事务保存点。当函数或触发器终止,它创建的任何事务发布和先前的保存点水平恢复。

13.3.5备份锁和解锁实例语法实例

LOCK INSTANCE FOR BACKUP

UNLOCK INSTANCE

LOCK INSTANCE FOR BACKUP获得一个实例备份锁允许DML在线备份期间防止可能导致不一致的快照操作。

执行LOCK INSTANCE FOR BACKUP静态的要求BACKUP_ADMIN特权。这个BACKUP_ADMIN授予用户的特权是自动的RELOAD特权在执行就地升级到MySQL 8从较早版本。

多个会话可以同时备份锁。

UNLOCK INSTANCE释放由当前会话举行备份锁。通过举办一届备份锁也如果会话终止发布。

LOCK INSTANCE FOR BACKUP防止文件被创建,重命名或删除。REPAIR TABLETRUNCATE TABLEOPTIMIZE TABLE,和帐户管理报表被封锁。看到第13.7.1,“账户管理报表”。操作修改InnoDB不记录在文件InnoDB重做日志也被阻塞

LOCK INSTANCE FOR BACKUP允许DDL操作只影响用户创建临时表。实际上,文件属于创建临时表的用户可以创建、重命名或删除一个备份而被锁定。二进制日志文件的创建也允许。

备份锁了LOCK INSTANCE FOR BACKUP是独立的事务锁和锁的FLUSH TABLES tbl_name [, tbl_name] ... WITH READ LOCK,和下面的序列的陈述是允许的:

备份实例锁;冲洗表tbl_name【,tbl_name]…读锁;解锁解锁情况表;
冲洗表tbl_name【,tbl_name]…读锁;锁解锁备份实例;实例;打开表;

这个lock_wait_timeout设置定义的时间量,备份实例锁声明在放弃之前获得一个锁。

13.3.6表加锁和解锁表语法

LOCK TABLES
    tbl_name [[AS] alias] lock_type
    [, tbl_name [[AS] alias] lock_type] ...

lock_type:
    READ [LOCAL]
  | [LOW_PRIORITY] WRITE

UNLOCK TABLES

MySQL允许客户端会话获得表锁明确与其他会话的访问表合作的目的,或防止其他会话修改表期间会话需要他们独家访问。一个会话可以获取或释放锁,只为自己。一次不能获取锁的另一个会话或释放锁的另一次会议召开。

锁可以用来模拟交易或得到更多的速度更新时表。这是更详细的解释在本节稍后。

LOCK TABLES明确获取表级锁当前客户端会话。表锁可以为表或视图获取。你必须有LOCK TABLES特权,和SELECT每个对象被锁定的特权。

查看锁定,LOCK TABLES添加视图中使用的表被锁定的设置所有基表和自动锁。如果你锁定表明确LOCK TABLES,用于触发任何表也上了锁,含蓄,如第13.3.6.2,“锁表和触发器”

如果你锁定表明确LOCK TABLES,任何通过外键约束相关表的打开和锁定的含蓄。国外重点抽查,共享只读锁(LOCK TABLES READ)采取相关表。级联更新,无共享的写锁(LOCK TABLES WRITE)是在相关表中所涉及的操作。

UNLOCK TABLES显式释放任何表锁的当前会话举行。LOCK TABLES隐式释放任何表锁的当前会话之前获取新的锁。

另一个用途UNLOCK TABLES是释放全局读锁获得的FLUSH TABLES WITH READ LOCK声明,这使您可以锁定所有表中的所有数据库。看到第13.7.7.3“同花顺语法”。(这是如果你有一个文件系统如真理,可以及时采取快照备份,得到一个非常方便的方式)

表锁只可以预防不适当的读取或写入其他会话。会议举行WRITE锁可以进行表级操作,如DROP TABLETRUNCATE TABLE。会议的举行阅读锁,DROP TABLETRUNCATE TABLE操作不允许

下面的讨论仅适用于非—TEMPORARYLOCK TABLES是允许的(忽略)了临时表表格可以通过会话内创建它自由访问,不管其他锁定会影响。没有锁是必要的因为没有其他会话可以看到表。

在使用其他条件的信息LOCK TABLES和声明时不能使用LOCK TABLES实际上,看第13.3.6.3,“表锁的限制和条件”

对锁的获取规则

获得表锁在当前会话,使用LOCK TABLES声明。下面的锁类型可供选择:

READ [LOCAL]锁具

  • 持有锁可以读取表会议(但不写)。

  • 多个会话可以获得READ同时为表锁

  • 其他会议可以没有明确获取读表READ锁具

  • 这个LOCALnonconflicting改变支持INSERT报表(并发插入)被其他会话执行而被锁定。(见第8.11.3,并发插入”然而。),READ LOCAL不能如果你要操纵数据库使用服务器外部过程,而你持有的锁。为InnoDB桌子,READ LOCAL是一样的阅读

[LOW_PRIORITY] WRITE锁具

  • 持有锁的读写桌会议

  • 只有持有锁的会话可以访问表。没有其他会话可以访问它直到锁被释放。

  • 锁请求表由其他会话块而WRITE持有锁

  • 这个LOW_PRIORITY改性剂没有影响。MySQL的在以前的版本中,它影响了锁定行为,但这是不真实的。现在是过时的和它的使用产生一个警告。使用没有LOW_PRIORITY相反

如果LOCK TABLES声明必须等待,由于任何其他会议的表锁,它的锁块直到所有可获得的。

会话需要锁必须获得所有的锁,它需要在一个单一的LOCK TABLES声明。而由此获得的锁举行,会议只能访问被锁定的表。例如,下面的语句序列,发生了一个错误的尝试访问T2因为它不是锁在LOCK TABLES声明:

MySQL的&#62;LOCK TABLES t1 READ;MySQL的&#62;SELECT COUNT(*) FROM t1;---------- |计数(*)| ---------- | 3 | ---------- MySQL &#62;SELECT COUNT(*) FROM t2;错误1100(hy000):表“T2”未锁锁表

表中的INFORMATION_SCHEMA数据库是一个例外。他们也可以在不锁定明确甚至当一个会话持有表锁获得访问LOCK TABLES

你不能把一个锁表多次使用同一名称在一个单一的查询。使用别名代替,并获得一个单独的锁表和每个别名:

mysql> LOCK TABLE t WRITE, t AS t1 READ;
mysql> INSERT INTO t SELECT * FROM t;
ERROR 1100: Table 't' was not locked with LOCK TABLES
mysql> INSERT INTO t SELECT * FROM t AS t1;

错误发生的第一INSERT因为有两个引用相同的名字一个锁定表。第二INSERT成功是因为表使用不同名称的引用。

如果你的陈述是指表的别名,你必须使用相同的别名锁表。它不工作,不指定别名锁表:

mysql> LOCK TABLE t READ;
mysql> SELECT * FROM t AS myalias;
ERROR 1100: Table 'myalias' was not locked with LOCK TABLES

相反,如果你锁定一个表使用一个别名,你必须是你的陈述,它使用别名:

mysql> LOCK TABLE t AS myalias READ;
mysql> SELECT * FROM t;
ERROR 1100: Table 't' was not locked with LOCK TABLES
mysql> SELECT * FROM t AS myalias;

WRITE锁通常有更高的优先级比阅读锁以确保更新尽快处理。这意味着,如果一次获得READ然后另一个会话请求的锁锁,随后READ锁请求等到会话请求锁已获得锁和释放它

LOCK TABLES获取锁如下:

  1. 排序的所有表格,被锁定在一个内部定义的顺序。从用户的角度来看,这个顺序是不确定的。

  2. 如果一个表被锁定一个读写锁,把写锁请求之前读锁的请求。

  3. 锁一表一次直到会议的所有锁。

这一政策确保表锁死锁。

笔记

LOCK TABLES打开表,当应用到一个分区表,总是锁定或解除锁定整个表;这些语句不支持分区锁修剪。看到分区和锁定

锁的释放规律

当表锁的会话被释放,他们都是在同一时间发布。一个会话可以释放它的锁或锁可以释放明确,隐含在一定条件下。

如果一个客户端会话连接终止,无论是正常或异常,服务器隐式释放所有表锁由会议举行(事务和非事务)。如果客户端重新连接,锁将不再有效。此外,如果客户有一个活跃的交易,服务器回滚事务一旦断开连接,如果连接时,新一届开始自动提交功能。为此,客户可能希望禁用自动重新连接。在自动重新连接,如果连接的客户端没有发生但任何表锁或当前的交易将会失去已通知。自动重新连接禁用,如果连接丢失,错误发生在接下来的声明。客户端可以检测到错误并采取适当的行动,如重新加锁或重做交易。看到第27.7.24,“C API自动重联控制”

笔记

如果你使用ALTER TABLE在一个锁着的桌子,它可能成为开启。例如,如果你尝试一次ALTER TABLE操作,结果可能是一个错误表“tbl_name“没有锁锁表。为了解决这个问题,锁表再到二变更前。参见第b.5.6.1,“问题表”

13.3.6.1交互表锁和事务

LOCK TABLESUNLOCK TABLES与交易的用途如下:

13.3.6.2锁表和触发器

如果你锁定表明确LOCK TABLES,用于触发任何表也被隐式:

  • 锁作为时间为那些获得明确的同LOCK TABLES声明

  • 一个用于触发表锁取决于表只用于阅读。如果是这样的话,一个读锁就够了。否则,一个写锁是使用。

  • 如果一个表锁明确阅读LOCK TABLES,但需要锁定写作因为它可能是在触发器中修改,写锁是不是读锁。(即隐写锁需要在表格的外观在触发原因明确的读锁请求表被转换成一个写锁的请求。)

假设你锁表,t1T2用这句话:

LOCK TABLES t1 WRITE, t2 READ;

如果t1T2有任何触发器,在触发器用表也将被锁定。假设t1有这样定义的触发器:

CREATE TRIGGER t1_a_ins AFTER INSERT ON t1 FOR EACH ROWBEGIN  UPDATE t4 SET count = count+1      WHERE id = NEW.id AND EXISTS (SELECT a FROM t3);  INSERT INTO t2 VALUES(1, 2);END;

的结果LOCK TABLES声明的是,T1t2是因为他们出现在表锁定,并T3t4是因为他们是在触发用锁:

  • t1锁定写作每锁的请求

  • t2锁定写作,即使请求的是一个阅读锁具这是因为t2插入触发器中,所以阅读请求转换为WRITE请求

  • t3锁定阅读,因为只有阅读从内部触发。

  • t4锁定写作因为它可能在触发更新。

13.3.6.3表锁的限制和条件

你可以安全的使用KILL终止一个会话,等待表锁。看到第13.7.7.4,“杀语法”

LOCK TABLESUNLOCK TABLES不能在存储程序中使用。

表中的performance_schema数据库无法锁定LOCK TABLES,除了setup_xxx

下面的语句是禁止的,LOCK TABLES声明是有效的:CREATE TABLECREATE TABLE ... LIKECREATE VIEWDROP VIEW,和DDL语句在存储函数和过程和事件。

对一些操作,在系统表mysql必须将数据库访问。例如,在HELP声明要求服务器端帮助表的内容,和CONVERT_TZ()可能需要读时区表。服务器隐式锁系统表的阅读是必要的,你不需要把他们明确。这些表被视为只是描述:

mysql.help_categorymysql.help_keywordmysql.help_relationmysql.help_topicmysql.procmysql.time_zonemysql.time_zone_leap_secondmysql.time_zone_namemysql.time_zone_transitionmysql.time_zone_transition_type

如果你想明确地WRITE与那些表锁LOCK TABLES表,该表必须只有一个锁;没有其他的表可以锁定同一语句。

通常情况下,你不需要锁表,因为所有的单UPDATE报表是原子;没有其他会话可以干扰其他正在执行的SQL语句。然而,有几例当锁定表可以提供一个优势:

  • 如果你要运行很多操作的一组MyISAM表,就是把你要使用的表快得多。锁定MyISAM表加快了插入、更新或删除,因为MySQL不冲水的锁表高速缓存到关键UNLOCK TABLES被称为。通常,关键是每个SQL语句缓存刷新后。

    锁定表的缺点是,没有会话可以更新READ锁表(其中包括持有锁)和无会话可以访问锁定表比其他人持有的锁。

  • 如果你正在使用的表为非事务性存储引擎,您必须使用LOCK TABLES如果你想确保没有其他会话修改之间的表SELECT和一个UPDATE。这里显示的示例要求LOCK TABLES执行安全:

    LOCK TABLES trans READ, customer WRITE;SELECT SUM(value) FROM trans WHERE customer_id=some_id;UPDATE customer  SET total_value=sum_from_previous_statementWHERE customer_id=some_id打开表;

    没有LOCK TABLES,这是可能的,另一个会话可以在插入新的一行反式执行之间的表SELECTUPDATE声明.

你可以避免使用LOCK TABLES在许多情况下,采用相对更新(更新客户设置value=value new_value)或LAST_INSERT_ID()功能

你也可以避免锁定表在某些情况下,使用用户级别咨询锁功能GET_LOCK()RELEASE_LOCK()。这些锁被保存在一个哈希表在服务器上执行pthread_mutex_lock()pthread_mutex_unlock()高速。看到12.22节,“多功能”

看到8.11.1节,“内锁法”,在锁定策略的更多信息。

13.3.7事务语法

SET [GLOBAL | SESSION] TRANSACTION
    transaction_characteristic [, transaction_characteristic] ...

transaction_characteristic:
    ISOLATION LEVEL level
  | READ WRITE
  | READ ONLY

level:
     REPEATABLE READ
   | READ COMMITTED
   | READ UNCOMMITTED
   | SERIALIZABLE

此定单交易特点.它需要一个或多个特征值用逗号隔开。这些特点设置事务隔离级别或访问模式。隔离级别是用于操作InnoDB表访问模式可以被指定为交易是否在读/写或只读模式操作。

此外,SET TRANSACTION可以包括一个可选的全球SESSION关键词to the scope of the statement的列。

交易特征范围

你可以设置交易特征在全球范围内,为当前会话,或者下一交易:

  • GLOBAL关键词,声明适用于全球所有的后续会议。现有会话不受影响。

  • SESSION关键词,声明适用于所有当前会话内进行后续交易。

  • 没有任何SESSION全球关键词,声明适用于下一个(开始)在当前会话中进行交易。随后的交易中恢复使用SESSION隔离级别

全球变化对交易特性要求CONNECTION_ADMINSUPER特权。任何会话可以自由改变其会话特性(即使在一个事务中),或为下一次的交易特点。

SET TRANSACTION没有全球SESSION是不是有一个活跃的交易许可:

MySQL的&#62;START TRANSACTION;查询行,0行受影响(0.02秒)MySQL &#62;SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;错误:1568(25001)交易特性不能changedwhile交易正在进行中

将全局默认隔离级别在服务器启动时,使用--transaction-isolation=level选项mysqld在命令行或在一个选项文件。值level这个选项使用破折号而不是空间,所以允许值READ-UNCOMMITTEDREAD-COMMITTEDREPEATABLE-READ,或SERIALIZABLE。例如,设置默认的隔离级别REPEATABLE READ在使用这些线,[ mysqld ]型期权的一个文件:

[mysqld]
transaction-isolation = REPEATABLE-READ

它是可能的检查或在运行时设置全局和会话事务隔离级别的应用transaction_isolation可变系统:

SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation;SET GLOBAL transaction_isolation='REPEATABLE-READ';SET SESSION transaction_isolation='SERIALIZABLE';

同样,设置交易接入方式在服务器启动或运行时,使用--transaction-read-only选择或transaction_read_only系统变量。一个多月以前评论关闭(模式的读/写)但可设置ON默认模式为只读

设置全局或会话的值transaction_isolationtransaction_read_only相当于设置隔离级别或访问模式SET GLOBAL TRANSACTIONSET SESSION TRANSACTION

事务隔离级

有关事务隔离级别的信息,参见第15.5.2.1,”事务隔离级别”

交易的接入方式

交易可以指定访问模式SET TRANSACTION。默认情况下,事务发生在读写模式下,读取和写入都允许用于交易表。这种模式可以被明确的指定使用访问模式读写

如果事务访问模式设置为READ ONLY禁止,变化表。这可能使存储引擎进行性能改进,可能当写是不允许的。

不允许指定READ WRITE只读在同一个声明

在只读模式下,它仍然可能改变创建表TEMPORARY使用DML语句关键字。DDL语句的更改不允许,就像永久表。

这个READ WRITE只读接入方式也可能被指定为个人交易使用START TRANSACTION声明

13.3.8 XA事务

支持XA交易是可用的InnoDB存储引擎。MySQL XA的实现是基于X/Open CAE文件分布式事务处理:XA规范。本文件公布的公开组和可在http://www.opengroup.org /公共/酒吧/目录/ c193.htm。当前XA实施限制进行第6号,“限制XA事务”

在客户端,有没有特殊的要求。XA接口到一个MySQL服务器由SQL语句开头的XA关键词MySQL客户端程序必须能够发送SQL语句,了解XA声明接口的语义。他们不需要链接到最近的客户端库。老客户端库也将。

MySQL连接器中,MySQL Connector/J 5.0.0和较高的支持下直接通过类接口处理SQL语句对你意味着XA接口。

XA支持分布式事务,即允许多个独立的事务性资源参与全球事务的能力。事务性资源往往是关系数据库管理系统,但可能是其他种类的资源。

全球交易涉及到本身是事务性的几个动作,但都必须成功完成为一组,或全部回滚为一组。在本质上,这种延伸酸性质升一级所以,多酸的交易可以执行在演唱会作为一个全球性的行动,也有酸性成分。(与非分布式事务,SERIALIZABLE可如果你的应用程序读现象的敏感者优先。REPEATABLE READ可能没有足够的分布式事务。)

一些分布式交易的例子:

  • 一个应用程序可以作为一个集成的工具,将通讯服务与RDBMS。应用程序可以确保处理消息的发送、检索和处理交易,也包括事务数据库中所有发生在全球交易。你可以认为这是交互的电子邮件

  • 应用程序执行的行动,涉及到不同的数据库服务器,如MySQL服务器和Oracle数据库服务器(或多个MySQL服务器),在那里的行动,涉及多个服务器必须作为一个全球性的交易发生,而不是作为单独的交易地方每个服务器。

  • 银行帐户信息保持RDBMS和分布,通过自动取款机(ATM)收到的钱。要保证ATM的行为是正确反映在账目中,但这不能与单独的数据库。一个全球性的事务管理器集成了ATM和数据库资源保证金融交易的整体一致性。

使用全局事务的应用涉及一个或多个资源管理器和事务管理器:

  • 资源管理(RM)提供了访问事务性资源。数据库服务器是一种资源管理器。它必须能够提交或回滚事务由RM管理。

  • 事务管理器(TM)的坐标,是一个全球交易的交易的一部分。它与处理这些交易的有效沟通。在全球交易的个人交易分支的全球交易。全球交易及其分支的命名方案后确定。

XA MySQL实现使MySQL服务器作为一个资源管理器处理XA事务在全球交易。一个客户端程序连接到MySQL服务器作为交易经理。

进行全球交易,有必要知道哪些成分参与,并把每个组件到一个点时,可以提交或回滚。这取决于每个部件的报道取得成功的能力,他们都必须提交或回滚作为一个原子组。那就是,所有部件必须提交或回滚所有组件必须。管理全球事务,有必要考虑任何组件或连接的网络可能会失败。

执行全球交易过程中使用两阶段提交(2PC)。这发生在全球的分支机构进行交易的行为已被处决。

  1. 在第一阶段,各分行准备。是,他们是由TM告诉准备提交。通常,这意味着每一个企业,经营部门记录的行动稳定存储的分支。树枝表明他们是否能够做到这一点,这些结果被用于第二阶段。

  2. 在第二阶段,TM告诉RMS是否提交或回滚。如果所有的树枝表明当他们准备的,他们能够提交,所有分支机构都告诉犯。如果任何分支表示当它准备,它将无法提交,所有分支机构都对回滚。

在某些情况下,全局事务可以使用单阶段提交(1张)。例如,当一个事务经理发现全局事务只包含一个事务性资源(即一个单一的分支),资源可以用来准备和提交的同时。

13.3.8.1 XA事务的SQL语法

在MySQL执行XA事务,使用下面的语句:

XA {START|BEGIN} xid [JOIN|RESUME]

XA END xid [SUSPEND [FOR MIGRATE]]

XA PREPARE xid

XA COMMIT xid [ONE PHASE]

XA ROLLBACK xid

XA RECOVER [CONVERT XID]

XA START,的加入RESUME不支持条款

XA END这个暂停[转移]条款是不支持的

每个XA语句开头XA关键词,而他们中的大多数需要一个xid价值。一个xid是XA事务标识符。这表明交易声明适用于。xid价值是由客户提供,或由MySQL服务器生成。一个xid价值已经从一到三件:

xidgtrid【,bqual【,formatID] ]

gtrid是一个全球性的事务标识符,bqual是一支预选赛,和formatID是标识使用的格式数gtridbqual价值观。由语法指示,bqualformatID是可选的。默认的bqual&#39; &#39;如果没有给出。默认的formatID值是1如果没有给出

gtridbqual必须是字符串,每个最多64个字节(不是字符)长。gtridbqual可以指定在几个方面。你可以使用一个引用串(AB)、字符串(X'6162'0x6162),或位值(b'nnnn'

formatID是一个无符号整数

这个gtridbqual值解释的字节数由MySQL服务器的基本XA支持程序。然而,当含XA语句解析SQL语句,服务器的工作方式与一些特殊的字符集。为了安全起见,写gtridbqual十六进制字符串

xid值通常是由事务管理器生成。由一个TM生成的值必须不同于其他TMS产生的值。一个给定的TM必须能够认识到自己的xid通过返回值列表的值XA RECOVER声明

XA START xid与给定的XA事务的开始xid价值。每个XA事务必须有一个唯一的xid价值,因此价值不能正在被另一个XA事务的应用。唯一性是评估使用gtridbqual价值观。以下为XA事务XA语句必须使用相同的规定xid值是给定的作为XA START声明。如果你使用任何这些报表,但指定xid价值不符合现有的XA事务,发生了一个错误。

一个或多个XA事务可以是相同的全球交易的一部分。在一个给定的全球交易的所有XA事务必须使用相同的gtrid中的价值xid值。for this reason,gtrid值必须是全局唯一的,没有歧义,全球交易给定XA事务的一部分。这个bqual部分的xid值必须是不同的每个XA事务在全球交易。(要求bqual价值观的不同是当前MySQL XA实施限制。它不是XA规范的一部分。)

这个XA RECOVER语句返回的MySQL服务器,在那些XA事务信息制备的国家。(这第13.3.8.2,“XA事务的国家”。)的输出包括在服务器上为每个这样的XA事务的行,无论哪个客户开始。

XA RECOVER要求XA_RECOVER_ADMIN特权。这种特权要求防止用户未备XA事务比自己发现的xid值。它不影响正常的提交或回滚因为XA事务的用户开始知道xid。

XA RECOVER输出行看起来像这样(为例xid组成部分的价值“ABC”'def',和):

mysql> XA RECOVER;
+----------+--------------+--------------+--------+
| formatID | gtrid_length | bqual_length | data   |
+----------+--------------+--------------+--------+
|        7 |            3 |            3 | abcdef |
+----------+--------------+--------------+--------+

输出列具有以下含义:

  • formatID是的formatID交易的一部分xid

  • gtrid_length以字节为单位的长度gtrid部分的xid

  • bqual_length以字节为单位的长度bqual部分的xid

  • data是的拼接gtridbqual部分的xid

XID值可能包含不可打印字符。XA RECOVER允许可选转换码的条款,客户可以要求xid值进制。

美国13.3.8.2 XA事务

XA事务的进展通过以下状态:

  1. 使用XA START启动XA事务放在活动中状态

  2. 对于一个ACTIVEXA事务,问题构成事务的SQL语句,然后发出一个XA END声明XA END把交易的闲置状态

  3. 对于一个IDLEXA事务,你可以发出一个XA PREPARE声明或xa commit…一个阶段声明:

    • XA PREPARE把交易的制备状态一个XA RECOVER在这一点上声明将包括交易xid其输出值,因为XA RECOVER列出所有XA事务,在制备状态

    • XA COMMIT ... ONE PHASE准备和提交事务。这个xid价值不会上市XA RECOVER因为交易终止

  4. 对于一个PREPAREDXA事务,你可以发出XA COMMIT声明承诺,终止交易,或XA ROLLBACK回滚和终止交易

这里是一个简单的XA事务,将行插入到表中作为一个全球交易的一部分:

mysql> XA START 'xatest';
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO mytable (i) VALUES(10);
Query OK, 1 row affected (0.04 sec)

mysql> XA END 'xatest';
Query OK, 0 rows affected (0.00 sec)

mysql> XA PREPARE 'xatest';
Query OK, 0 rows affected (0.00 sec)

mysql> XA COMMIT 'xatest';
Query OK, 0 rows affected (0.00 sec)

在一个客户端连接的上下文中,XA事务和地方(非XA)事务是互斥的。例如,如果XA START已经发出开始XA事务,地方事务不能到XA事务已提交或回滚开始。相反,如果一个地方的交易已经开始START TRANSACTION不可以使用XA语句,直到事务被提交或回滚。

如果XA事务中ACTIVE的状态,你不能发布任何声明,因为一个隐含的承诺。这将违反XA合同因为你不能回滚XA事务。如果您尝试执行这样一个声明收到以下错误:

错误1399年(xae07):xaer_rmfail:命令无法执行全局事务处于活动状态

报表,前面的话将被列在13.3.3部分,”声明,因为一个隐含的承诺”

13.4 .折叠定制

复制可以通过使用本节中描述的语句的SQL接口控制。报表分为控制主服务器组,一个对照组,一组从服务器,它可以应用于任何复制服务器。

13.4.1控制主服务器的SQL语句

该部分论述了管理主复制服务器报表。第13.4.2,“SQL语句用于控制从服务器”论述了从服务器,管理报表。

除了这里所描述的语句,如下SHOW语句中使用复制主服务器。关于这些语句的信息,参见第13.7.6,“语法”

13.4.1.1清除二进制日志的语法

PURGE { BINARY | MASTER } LOGS
    { TO 'log_name' | BEFORE datetime_expr }

二进制日志是一套包含关于数据修改的MySQL服务器信息文件。日志由一组二进制日志文件,再加上一个索引文件(见5.4.4节,“二进制日志”

这个PURGE BINARY LOGS语句删除所有的二进制日志文件中列出的日志索引文件到指定的日志文件的名称或日期之前。二元的MASTER是同义词。删除日志文件也记录在索引文件列表中删除,以便给日志文件成为第一个列表中。

如果服务器没有启动的这项声明没有影响--log-bin选项可启用二进制日志。

实例:

PURGE BINARY LOGS TO 'mysql-bin.010';
PURGE BINARY LOGS BEFORE '2008-04-02 22:46:26';

这个BEFORE变异的datetime_expr要评估一个论点DATETIME值(值“YYYY-MM-DD HH:MM:SS”格式

这项声明是安全运行而奴隶被复制。你不能阻止他们。如果你有一个活跃的奴隶正在读一你想删除日志文件的,这句话并不删除正在使用或任何日志文件后,一个日志文件,但它删除任何以前的日志文件。一个警告信息,就是在这种情况下发行。然而,如果一个奴隶没有连接和你吹一日志文件还没有读,奴隶将在它将无法复制。

安全地清除二进制日志文件,遵守本程序:

  1. 在每个从属服务器,使用SHOW SLAVE STATUS检查日志文件是阅读

  2. 获得的二进制日志文件列表在主服务器SHOW BINARY LOGS

  3. 确定所有的奴隶最早的日志文件。这是目标文件。如果所有的奴隶都是最新的,这是名单上最后一个日志文件。

  4. 使所有的日志文件,你要删除的备份。(这一步是可选的,但总是明智的。)

  5. 清除所有的日志文件到目标文件,但不包括。

PURGE BINARY LOGS TO清除二进制日志之前无论失败与错误时,二进制日志文件中列出.index文件已经通过其他的方式从系统中删除(如使用RM在Linux)。(错误# 18199,错误# 18453)来处理这些错误,编辑.index文件(这是一个简单的文本文件)手动确保它只列出了二进制日志文件,实际上是存在的,然后再次运行PURGE BINARY LOGS语句失败

二进制日志文件服务器的二进制日志保质期后自动删除。文件的去除可以在启动发生,当二进制日志刷新。默认的二进制日志的保质期是30天。你可以指定一个替代保质期使用binlog_expire_logs_seconds系统变量。如果您使用的是复制,你必须指定一个有效期限不低于你的奴隶可能滞后于主的最大数量。

13.4.1.2复位掌握语法

RESET MASTER [TO binary_log_file_index_number]

RESET MASTER使您可以删除任何二进制日志文件和相关的二进制日志索引文件,返回主前状态的二进制日志的开始。

警告

小心使用这个语句来确保你不会失去二进制日志文件中的数据。

发行RESET MASTERwithout the optional条款中删除所有的二进制日志文件,索引文件的上市,将二进制日志索引文件是空的,并创建一个新的二进制日志文件的开始1。使用可选的条款以外的其他数字开头的二进制日志文件索引1复位后。发行复位大师也明确的价值观gtid_purged系统变量和gtid_executed系统变量;即发布此声明设置这些值为空字符串(&#39; &#39;页:1This statement also清themysql.gtid_executed(这台mysql.gtid_executed表

使用RESET MASTER子句指定一个二进制日志文件的索引号开始从简化了故障转移到提供单表替代FLUSH BINARY LOGSPURGE BINARY LOGS TO声明.

下面的示例演示TO从句的用法:

复位大师1234;显示二进制日志;------------------- ----------- | log_name | file_size | ------------------- ----------- | master-bin.001234 | 154 | ------------------- -----------
重要

的影响RESET MASTER没有从这些不同的条款PURGE BINARY LOGS两关键途径:

  1. RESET MASTER删除全部二进制日志文件,索引文件中列出,只留下一个单一的,空的二进制日志文件包含一个数字后缀.000001,而不是重新编号PURGE BINARY LOGS

  2. RESET MASTER为了在任何复制正在运行使用的奴隶。的行为RESET MASTER当你的奴隶正在运行的是未定义的(因此不支持),而PURGE BINARY LOGS可以在复制的奴隶正在运行的安全使用。

参见第13.4.1.1,“清除二进制日志语法”

RESET MASTER没有条款可以证明是有用的当你第一次建立了主人与奴隶,这样你就可以验证设置如下:

  1. 开始的主人和奴隶,并开始复制(见第17.1.2,“建立复制二进制日志文件的位置

  2. 在主执行一些测试查询。

  3. 检查查询复制到奴隶

  4. 当复制运行正确,问题STOP SLAVE然后RESET SLAVE对奴隶,然后验证,从测试查询没有无用的数据存在于奴隶。

  5. 问题RESET MASTER在清理测试查询主

验证安装后,重新设置主从,确保没有不必要的数据或二进制日志文件生成的测试仍在主人或奴隶,你可以开始从开始复制。

13.4.1.3集sql_log_bin语法

SET sql_log_bin = {0|1}

这个sql_log_bin变量控制是否记录到二进制日志了。默认值为-1(做记录)。更改当前会话记录,改变这个变量的值的会话。会话的用户必须有SYSTEM_VARIABLES_ADMINSUPER权限设置这个变量。这个变量设置为0个会话暂时禁用二进制日志而改变的主,你不想复制的奴隶。

这是不可能的设置@@session.sql_log_bin在一个事务或子查询

13.4.2控制从服务器的SQL语句

本节讨论从复制服务器报表管理。13.4.1节,“SQL语句用于控制主服务器”,讨论了主服务器报表管理。

除了这里所作的陈述,SHOW SLAVE STATUSSHOW RELAYLOG EVENTS也可用于复制的奴隶。关于这些语句的信息,参见第13.7.6.34,“SHOW SLAVE STATUS语法”,和第13.7.6.32,“显示relaylog事件语法”

13.4.2.1变化掌握语法

CHANGE MASTER TO option [, option] ... [ channel_option ]

option:
    MASTER_BIND = 'interface_name'
  | MASTER_HOST = 'host_name'
  | MASTER_USER = 'user_name'
  | MASTER_PASSWORD = 'password'
  | MASTER_PORT = port_num
  | MASTER_CONNECT_RETRY = interval
  | MASTER_RETRY_COUNT = count
  | MASTER_DELAY = interval
  | MASTER_HEARTBEAT_PERIOD = interval
  | MASTER_LOG_FILE = 'master_log_name'
  | MASTER_LOG_POS = master_log_pos
  | MASTER_AUTO_POSITION = {0|1}
  | RELAY_LOG_FILE = 'relay_log_name'
  | RELAY_LOG_POS = relay_log_pos
  | MASTER_SSL = {0|1}
  | MASTER_SSL_CA = 'ca_file_name'
  | MASTER_SSL_CAPATH = 'ca_directory_name'
  | MASTER_SSL_CERT = 'cert_file_name'
  | MASTER_SSL_CRL = 'crl_file_name'
  | MASTER_SSL_CRLPATH = 'crl_directory_name'
  | MASTER_SSL_KEY = 'key_file_name'
  | MASTER_SSL_CIPHER = 'cipher_list'
  | MASTER_SSL_VERIFY_SERVER_CERT = {0|1}
  | MASTER_TLS_VERSION = 'protocol_list'
  | MASTER_PUBLIC_KEY_PATH = 'key_file_name'
  | GET_MASTER_PUBLIC_KEY = {0|1}
  | IGNORE_SERVER_IDS = (server_id_list)

channel_option:
    FOR CHANNEL channel

server_id_list:
    [server_id [, server_id] ... ]

CHANGE MASTER TO的变化,从服务器用于连接到主服务器参数,阅读大师的二进制日志,并阅读从中继日志。它还更新了内容的掌握信息和中继日志信息库(参见第17.2.4,“复制继电器和状态日志”CHANGE MASTER TO要求REPLICATION_SLAVE_ADMINSUPER特权

你的问题CHANGE MASTER TO在一个运行的奴隶陈述没有停止它,这取决于奴隶和奴隶的SQL线程I/O线程的状态。管理使用规定在本节稍后。

使用多线程的奴隶时(换句话说slave_parallel_workers大于0),停止奴隶可以引起空白在已经从中继日志执行事务的序列,无论奴隶停止有意无意地。当这种差距的存在,发行CHANGE MASTER TO失败.在这种情况下,解决方案是问题START SLAVE UNTIL SQL_AFTER_MTS_GAPS使间隙关闭

可选FOR CHANNEL channel条款使你名字的声明适用于复制通道。提供一个通道channel条款的适用改变主声明一个特定的复制通道,是用来添加一个新的通道或修改现有的渠道。例如,添加一个新的通道称为2:

CHANGE MASTER TO MASTER_HOST=host1, MASTER_PORT=3002 FOR CHANNEL 'channel2'

如果没有条款命名并没有额外的渠道存在,该声明适用于默认频道。

当使用多个复制的渠道,如果CHANGE MASTER TO声明没有指定的信道使用通道channel条款,发生了一个错误。看到第17.2.3,“复制通道”更多信息

选择不指定保留自己的价值,除了在下面的讨论中表示。因此,在大多数情况下,不需要指定选项,不改变。

MASTER_HOSTmaster_userMASTER_PASSWORD,和master_port提供的信息,从如何连接到它的主人:

  • MASTER_HOSTmaster_port是主机名(或IP地址)的主机的TCP/IP端口。

    笔记

    复制不能使用Unix套接字文件。你必须能够连接到使用TCP / IP主机的MySQL服务器。

    如果您指定的MASTER_HOSTmaster_port选项,从假设主服务器是不同于之前(即使期权价值是其当前值相同。)在这种情况下,对于掌握二进制日志文件的名称和位置,旧的价值观被认为不再适用,所以如果你不指定MASTER_LOG_FILEmaster_log_pos在声明,MASTER_LOG_FILE=''MASTER_LOG_POS=4默默地附加到它

    设置MASTER_HOST=''(即,设置它的值为空字符串是明确)不设置相同MASTER_HOST完全.试图设置master_host一个空字符串失败与错误。

    值用于MASTER_HOST和其他改变主可选择的选项\n0x0a)人物;这些价值观这样的人物的存在导致语句失败ER_MASTER_INFO。(错误# 11758581,错误# 50801)

  • MASTER_USERmaster_password是该帐户的用户名和密码用于连接到主。

    MASTER_USER不能为空;设置MASTER_USER = ''或者把它设置设定值时MASTER_PASSWORD导致错误(bug # 13427949)。

    用于MySQL复制从账户中的密码CHANGE MASTER TO语句的长度限于32个字符;试图用一个密码超过32个字符的原因改变主失败

    一个运行中的文本CHANGE MASTER TO声明,包括值master_userMASTER_PASSWORD,可以在一个并行输出的视SHOW PROCESSLIST声明。(一个完整的文本START SLAVE声明中还可见SHOW PROCESSLIST。)

这个MASTER_SSL_xxx选项,并master_tls_version选项,指定如何从使用加密和密码保护的复制连接。这些选项可以是奴隶,编译时没有SSL支持转变。他们保存到主信息库,但被忽略,如果奴隶没有启用SSL的支持。这个MASTER_SSL_xxx功能选择perform the same as the——SSL—xxx选项描述第6.4.2,“加密连接”命令选项。这两个选项之间的对应关系,并使用该MASTER_SSL_xxxmaster_tls_version选项来设置一个安全的连接,是解释第17.3.9,“设置复制使用加密连接”

重要

连接使用的用户帐户进行身份验证和复制大师caching_sha2_password插件,你必须建立一个安全连接所述第17.3.9,“设置复制使用加密连接”,或启用加密连接支持密码交换使用RSA密钥对。这个caching_sha2_password身份验证插件是从MySQL 8中创建新用户的默认值(详情见第6.5.1.3,“缓存SHA-2认证”)。如果你的用户帐户创建或使用复制(指定的MASTER_USER选项)使用该认证插件,你不使用安全连接,您必须启用基于RSA密钥对一个成功的连接密码。

为了使基于RSA密钥对密码交换,指定MASTER_PUBLIC_KEY_PATHGET_MASTER_PUBLIC_KEY=1选项这些选项提供了RSA公钥的奴隶:

  • MASTER_PUBLIC_KEY_PATH表示路径名包含由RSA密钥对的密码交换所必须掌握的公共密钥从复制文件。该文件必须在PEM格式。此选项适用于奴隶的鉴定与sha256_passwordcaching_sha2_password认证插件。(forsha256_passwordMASTER_PUBLIC_KEY_PATH可如果MySQL建立使用OpenSSL使用。)

  • GET_MASTER_PUBLIC_KEY指示是否从主人的RSA密钥对的公钥密码交换所需的基础要求。此选项适用于奴隶的鉴定与caching_sha2_password身份验证插件。通过帐户验证使用这个插件连接,主不发送公钥除非有要求,所以必须要求或客户指定。如果MASTER_PUBLIC_KEY_PATH给出指定有效的公钥文件,它将优先于get_master_public_key

MASTER_CONNECT_RETRY指定要等待多少秒之间连接重试。默认的是60。

MASTER_RETRY_COUNT限制重联的尝试和更新的价值Master_Retry_Count输出中的列SHOW SLAVE STATUS. The default value is 24 * 3600 = 86400.硕士_ _重试计数是为了取代旧的--master-retry-count服务器选项,现在是设置该限制的首选方法。我们鼓励你不依靠--master-retry-count在新的应用程序,升级时比MySQL 5.6版本之前,更新任何现有的应用程序依赖于它,所以他们使用改变主…master_retry_count相反

MASTER_DELAY指定在主人的奴隶要滞后几秒。一个事件从主接收不到至少执行interval迟于主执行秒。默认值是0。如果一个错误发生interval是不是从0到2范围内的一个非负整数三十一?1。有关更多信息,参见第17.3.11,“延迟复制”

CHANGE MASTER TO声明中使用master_delay选项可以在运行时执行的奴隶,奴隶的SQL线程停止。

MASTER_BIND用于复制的奴隶有多个网络接口,并确定其中奴隶的网络接口选择连接到主。

地址配置了这个选项,如果有的话,可以看到的Master_Bind列的输出SHOW SLAVE STATUS。在掌握信息库表mysql.slave_master_info的值,可以看作是Master_bind专栏

MASTER_HEARTBEAT_PERIOD集之间复制的心跳在秒的间隔。每当主人的二进制日志与事件的更新,为下一步的心跳等待期间复位。interval是一个十进制值的范围为0到4294967秒和毫秒级的分辨率;最小的非零的值是0.001。心跳发送大师只是如果没有未发送的事件在二进制日志文件一段时间超过intervalmaster_heartbeat_period可以看作是价值的Heartbeat列的mysql.slave_master_info

设置interval0禁用心跳完全。默认值为interval等于价值slave_net_timeout除以2

设置@@global.slave_net_timeout一个值小于当前的心跳间隔的结果在警告发出。发行的影响RESET SLAVE在心跳间隔重置为默认值。

MASTER_LOG_FILEmaster_log_pos是坐标,从I/O线程应该阅读从主下次线程开始开始。RELAY_LOG_FILErelay_log_pos是坐标,从SQL线程应该开始阅读从中继日志下次线程开始。如果你指定MASTER_LOG_FILEmaster_log_pos,你不能指定RELAY_LOG_FILErelay_log_pos。如果你specify毋宁ofMASTER_LOG_FILEmaster_log_pos,你也不能指定MASTER_AUTO_POSITION = 1(在本节后面介绍)。如果没有master_log_fileMASTER_LOG_POS是指定的,从使用的最后的坐标从SQL线程之前CHANGE MASTER TO发布。这保证了在复制没有间断,即使从SQL线程是比较晚的Slave I/O线程,当你只是想改变,说,使用密码。

CHANGE MASTER TO声明中使用relay_log_fileRELAY_LOG_POS,或都可以在运行时执行的奴隶奴隶SQL线程停止。

如果MASTER_AUTO_POSITION = 1使用改变主,奴隶试图连接到使用基于gtid复制协议的主。这个选项可以使用CHANGE MASTER TO只有从SQL和从I/O线程都停止。

当使用gtids,奴隶告诉主交易已经收到,执行,或两者。计算这一套,它读取全球价值gtid_executed和值retrieved _ gtid _看到SHOW SLAVE STATUS。由于最后发送的交易gtid包含在retrieved _ gtid _看到即便交易仅部分传送,最后收到的是这套gtid减去。因此,从计算如下:

UNION(@@global.gtid_executed, Retrieved_gtid_set - last_received_GTID)

这一套是作为初始的握手部分发送给主人,和主人发回的所有交易,它已执行不集的一部分。如果这些交易已经从主人的二进制日志清除,主发送错误ER_MASTER_HAS_PURGED_REQUIRED_GTIDS的奴隶,并复制不启动。

当gtid基础采用复制,坐标表示的MASTER_LOG_FILEmaster_log_pos不习惯,和全球事务标识符代替。因此,一个或多个选项一起使用MASTER_AUTO_POSITION导致错误

你可以看看是否复制与autopositioning检查输出启用运行SHOW SLAVE STATUS

gtid_mode也必须启用发布之前CHANGE MASTER TO ... MASTER_AUTO_POSITION = 1。否则,该语句将失败与错误。

恢复旧的基于文件的复制协议后使用gtids,你可以发出一个新的CHANGE MASTER TO语句指明MASTER_AUTO_POSITION = 0,以及至少一个MASTER_LOG_FILEmaster_log_position

中继日志如果在奴隶和奴隶的SQL线程I/O线程至少一个运行保存;如果两个线程都停止了,所有的中继日志文件被删除,除非至少有一个RELAY_LOG_FILErelay_log_pos指定

RELAY_LOG_FILE可以使用绝对路径或相对路径,并使用相同的基名称master_log_file。。。。。。。(错误# 12190)

IGNORE_SERVER_IDS以逗号分隔的0个或更多的服务器ID列表。从相应的服务器事件被忽略,随着旋转和删除事件日志的例外,这仍然是在中继日志记录。

在循环复制,发起服务器通常作为它自己的事件的终结者,所以他们不能应用超过一次。因此,这个选项是有用的在循环复制时一个圈子中的服务器被删除。假设你有4台服务器有一个圆形的复制设置,在服务器ID是1, 2, 3,和4,3和服务器失败。当缩小差距从2服务器复制到服务器4,您可以包括IGNORE_SERVER_IDS = (3)CHANGE MASTER TO声明你问题在服务器4告诉它使用Server 2作为代替3主服务器。这样做的原因是忽视和不传播任何声明,源于服务器,不再使用。

如果IGNORE_SERVER_IDS包含服务器的ID和服务器开始的--replicate-same-server-id启用选项,一个错误的结果。

笔记

当全球事务标识符(gtids)用于复制,已经应用的交易都自动忽略,所以IGNORE_SERVER_IDS功能不是必需的,不推荐使用。如果gtid_mode=ON设置为服务器,一个贬低警告如果包括ignore_server_ids选择一个CHANGE MASTER TO声明

主信息库和输出SHOW SLAVE STATUS提供目前被忽略的服务器列表。有关更多信息,参见第17.2.4.2,“奴隶状态日志”,和第13.7.6.34,“SHOW SLAVE STATUS语法”

如果一个CHANGE MASTER TO声明没有任何ignore_server_ids选项,任何现有的列表保存。明确忽视服务器列表,有必要使用的选项有一个空的:

CHANGE MASTER TO IGNORE_SERVER_IDS = ();

RESET SLAVE ALL清除ignore_server_ids

笔记

一个贬低警告如果SET GTID_MODE=ON发出时,任何现有的服务器ID设置通道ignore_server_ids。在开始gtid通过复制,检查并清楚服务器的所有忽视服务器ID列表。这个SHOW_SLAVE_STATUS语句显示忽略的ID列表,如果有一个。如果你真的收到了贬低的警告,你仍然可以清除列表后gtid_mode=ON将通过发行CHANGE MASTER TO声明包含ignore_server_ids一个空的列表选项

调用CHANGE MASTER TO使以前的值master_hostMASTER_PORTmaster_log_file,和MASTER_LOG_POS要写入错误日志,以及其他信息关于奴隶的状态执行之前。

CHANGE MASTER TO原因一个隐式提交一项正在进行的交易。看到13.3.3部分,”声明,因为一个隐含的承诺”

从MySQL 5.7,执行严格的要求STOP SLAVE发行之前CHANGE MASTER TO(和声明START SLAVE后来)被移除。而不是取决于奴隶的行为停止,改变主取决于奴隶和奴隶的SQL线程I/O线程的状态;而这些线程停止或运行现在决定可以或不可以使用一个选项CHANGE MASTER TO在给定的时间点声明。对于决策的规则如下:

  • 如果SQL线程停止时,你可以执行CHANGE MASTER TO使用任何组合,否则不准relay_log_fileRELAY_LOG_POS,和master_delay选择,即使从I/O线程正在运行。没有其他的选项可以用这句话当I/O线程正在运行。

  • 如果I/O线程停止时,你可以执行CHANGE MASTER TO使用任何这种说法的选项(在任何允许的组合)除了RELAY_LOG_FILErelay_log_pos,或MASTER_DELAY线程是SQL,even when the跑步。这三个选项may not be used is when the I / O线程运行。

  • 无论是SQL线程和I/O线程必须在发出停止CHANGE MASTER TO声明中使用MASTER_AUTO_POSITION = 1

你可以从SQL的当前状态和I/O线程使用SHOW SLAVE STATUS

有关更多信息,参见第17.3.8,“转换大师在故障转移期间”

如果您使用的是基于复制和临时表的声明,一个是可能的CHANGE MASTER TO在表后停止奴隶声明临时表上留下的奴隶。警告(ER_WARN_OPEN_TEMP_TABLES_MUST_BE_ZERO每当发生这种情况现在发布)。你可以避免在这种情况下,通过确定的价值Slave_open_temp_tables系统状态变量等于0执行之前改变主声明

CHANGE MASTER TO是用于设定一个奴隶当你主人的快照和记录的掌握二进制日志坐标对应的快照的时间。在加载的快照到奴隶同步它的主人,你可以运行CHANGE MASTER TO MASTER_LOG_FILE='log_name', MASTER_LOG_POS=log_pos对从指定坐标的奴隶开始读硕士的二进制日志。

下面的示例使用变化的奴隶主服务器并建立掌握二进制日志坐标从奴隶开始阅读。这是当你想建立奴隶复制大师:

CHANGE MASTER TO
  MASTER_HOST='master2.example.com',
  MASTER_USER='replication',
  MASTER_PASSWORD='password',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='master2-bin.001',
  MASTER_LOG_POS=4,
  MASTER_CONNECT_RETRY=10;

下面的例子表明,不常用的操作。它是用来当从中继日志文件,你想让它再执行的一些原因。为此,主人不必可达。你只需要使用CHANGE MASTER TO启动SQL线程(开始从sql_thread):

CHANGE MASTER TO
  RELAY_LOG_FILE='slave-relay-bin.006',
  RELAY_LOG_POS=4025;

下表显示的字符串值选项允许的最大长度。

选项最大长度
MASTER_HOST六十
MASTER_USER九十六
MASTER_PASSWORD三十二
MASTER_LOG_FILE五百一十一
RELAY_LOG_FILE五百一十一
MASTER_SSL_CA五百一十一
MASTER_SSL_CAPATH五百一十一
MASTER_SSL_CERT五百一十一
MASTER_SSL_CRL五百一十一
MASTER_SSL_CRLPATH五百一十一
MASTER_SSL_KEY五百一十一
MASTER_SSL_CIPHER五百一十一
MASTER_TLS_VERSION五百一十一
MASTER_PUBLIC_KEY_PATH五百一十一

13.4.2.2改变复制筛选器语法

CHANGE REPLICATION FILTER filter[, filter]
	[, ...] [FOR CHANNEL channel]

filter:
    REPLICATE_DO_DB = (db_list)
  | REPLICATE_IGNORE_DB = (db_list)
  | REPLICATE_DO_TABLE = (tbl_list)
  | REPLICATE_IGNORE_TABLE = (tbl_list)
  | REPLICATE_WILD_DO_TABLE = (wild_tbl_list)
  | REPLICATE_WILD_IGNORE_TABLE = (wild_tbl_list)
  | REPLICATE_REWRITE_DB = (db_pair_list)

db_list:
    db_name[, db_name][, ...]

tbl_list:
    db_name.table_name[, db_name.table_name][, ...]
wild_tbl_list:
    'db_pattern.table_pattern'[, 'db_pattern.table_pattern'][, ...]

db_pair_list:
    (db_pair)[, (db_pair)][, ...]

db_pair:
    from_db, to_db

CHANGE REPLICATION FILTER设置一个或多个复制过滤规则以相同的方式从开始的奴隶mysqld与复制的过滤选项如--replicate-do-db--replicate-wild-ignore-table。与服务器选项的情况下,这样的声明不需要重启服务器才能生效,只有从SQL线程被停止使用STOP SLAVE SQL_THREAD第一(和启动START SLAVE SQL_THREAD接着)CHANGE REPLICATION FILTER要求REPLICATION_SLAVE_ADMINSUPER特权。使用通道channel条款进行复制筛选特定的复制通道,例如在多源复制从。没有一个特定的过滤器的应用通道条款被认为是全球过滤器,这意味着他们将应用于所有复制通道。

笔记

全球复制筛选器不能建立在MySQL服务器实例配置为组复制,因为有些服务器过滤交易将使集团无法达成一致的状态协议。通道特定复制过滤器可以设置复制的通道没有直接参与组的复制,如其中一组成员也作为一个奴隶主,是一个复制组外。他们不能设置在group_replication_appliergroup_replication_recovery频道

下面的列表显示CHANGE REPLICATION FILTER选项和它们如何与* -复制服务器选项:

精确的影响REPLICATE_DO_DB复制这个网站过滤器是依赖于是否基于或基于行的复制效果的声明。看到第17.2.5,“服务器如何评价复制过滤规则”为更多的信息

多复制过滤规则可以在一个单一的创建CHANGE REPLICATION FILTER通过用逗号分隔的规则语句,如下所示:

CHANGE REPLICATION FILTER    REPLICATE_DO_DB = (d1), REPLICATE_IGNORE_DB = (d2);

发卡上面的语句等价于从奴隶mysqld与选择--replicate-do-db=d1--replicate-ignore-db=d2

在多源复制的奴隶,它使用多个复制的渠道来源不同的交易过程中,使用FOR CHANNEL channel条款设置的复制在复制通道滤波器:

CHANGE REPLICATION FILTER REPLICATE_DO_DB = (d1) FOR CHANNEL channel_1;

这使您可以创建一个特定渠道复制过滤器过滤选择的数据从源。当一个FOR CHANNEL设置条款,复制筛选语句作用于奴隶,删除任何现有的复制复制通道滤波器具有相同的滤波器类型,指定复制的过滤器,并更换他们指定的过滤器。过滤器类型没有明确列出在声明中未被修改。如果对一个奴隶的复制通道配置不发出,声明未与斯拉夫语误差。如果对组复制的渠道发行,则语句失败的er_slave_channel_operation_not_allowed误差

在多通道配置复制从复制、发行CHANGE REPLICATION FILTER没有通道条款配置每配置从复制通道复制过滤器,和全球复制过滤器。每个过滤器类型,如果过滤器类型在声明中列出,那么任何现有的过滤规则,通过在最新发布的声明中指定的过滤规则取代,否则过滤器类型的旧值保留。更多信息见第17.2.5.4,“复制通道滤波器”

如果同样的过滤规则多次指定,只有最后的这样的规则实际上是用。例如,两个报表显示这里有同样的效果,因为第一REPLICATE_DO_DB在第一个声明忽略规则:

CHANGE REPLICATION FILTER    REPLICATE_DO_DB = (db1, db2), REPLICATE_DO_DB = (db3, db4);CHANGE REPLICATION FILTER    REPLICATE_DO_DB = (db3, db4);
注意安全

这种行为不同于的--replicate-*过滤选项,指定相同的选项多次导致多个过滤规则的创建。

表不包含任何特殊字符,数据库名称不需要引用。值的使用REPLICATION_WILD_TABLE威德的复制品是字符串表达式,可能含有(特殊)的通配符,所以必须引用。这是下面的示例报表显示:

CHANGE REPLICATION FILTER
    REPLICATE_WILD_DO_TABLE = ('db1.old%');

CHANGE REPLICATION FILTER
    REPLICATE_WILD_IGNORE_TABLE = ('db1.new%', 'db2.new%');

值的使用REPLICATE_REWRITE_DB代表数据库名称;每个值必须用括号括起来。下面的语句重写发生在数据库语句db1在主数据库db2在奴隶:

CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB = ((db1, db2));

上面的语句包含两套括号,一个封闭的数据库名称的配对,和其他封闭整个列表。这也许是在下面的例子中更容易看到,这两个rewrite-db一个重写规则,数据库DBAdbB,和一个重写数据库DBCdbD

CHANGE REPLICATION FILTER  REPLICATE_REWRITE_DB = ((dbA, dbB), (dbC, dbD));

这个CHANGE REPLICATION FILTER语句替换复制过滤规则只为滤波器类型和复制通道的声明的影响,和叶的其他规则和渠道不变。如果你想消除所有过滤器的一个给定的类型,设置过滤器的值显式空列表,如图所示,它将删除所有现有的复制的REPLICATE_IGNORE_DB规则

CHANGE REPLICATION FILTER    REPLICATE_DO_DB = (), REPLICATE_IGNORE_DB = ();

设置一个过滤空这样将删除所有现有的规则,不创建任何新的,并没有恢复任何规则设置在启动mysqld使用--replicate-*在命令行或在配置文件选项。

这个RESET SLAVE ALL语句删除信道特定复制过滤器,设置由语句删除通道。当删除通道或通道的重现,对奴隶的指定任何全球复制过滤器复制他们,没有特定渠道复制过滤器的应用。

有关更多信息,参见第17.2.5,“服务器如何评价复制过滤规则”

13.4.2.3 master_pos_wait()语法

SELECT MASTER_POS_WAIT('master_log_file', master_log_pos [, timeout][, channel])

这实际上是一个函数,不是一个声明。它是用来确保奴隶具有读取和执行的事件到了主人的二进制日志位置。看到12.22节,“多功能”这是一个完美的描述

从语法13.4.2.4复位

RESET SLAVE [ALL] [channel_option]

channel_option:
    FOR CHANNEL channel

RESET SLAVE使奴隶忘记在主人的二进制日志复制的位置。这句话是用来为一个全新的开始:它清除主信息和中继日志信息库,删除所有的中继日志文件,并开始一个新的中继日志文件。它还重置为0的复制延迟指定的master_delay选项CHANGE MASTER TORESET SLAVE不改变值gtid _ executedgtid_purged

笔记

所有的中继日志文件被删除,即使他们没有从SQL线程执行完毕。(这是一个条件可能在复制的奴隶存在,如果你已经发布STOP SLAVE声明或如果从高度加载。)

使用RESET SLAVE,从复制的线程必须停止,所以在运行的奴隶使用STOP SLAVE在发行RESET SLAVE。使用RESET SLAVE在一组复制组成员、成员地位必须离线,即插件加载但成员目前不属于任何组。一个组的成员可以通过使用离线STOP GROUP REPLICATION声明

可选FOR CHANNEL channel条款使你名字的声明适用于复制通道。提供一个通道channel条款的适用复位的奴隶声明一个特定的复制通道。结合FOR CHANNEL channel条款与全部选择删除指定的通道。如果没有通道命名并没有额外的渠道存在,该声明适用于默认频道。发行RESET SLAVE ALL声明没有通道channel当多个复制渠道存在删除条款全部复制通道和再现只有默认的通道。看到第17.2.3,“复制通道”更多信息

RESET SLAVE不改变任何复制连接参数,如主机、主端口,主用户,或主密码,并保留在内存中。这意味着,START SLAVE可以不需要发布CHANGE MASTER TOfollowing statementRESET SLAVE

复制连接参数复位RESET SLAVE ALL。在MySQL 8.0.13,如果奴隶mysqld重新启动后立即发放RESET SLAVE(包括服务器崩溃以及故意重启),连接参数进行了设置,如重置所有的奴隶已经习惯了。现在,当master_info_repository=TABLE设置服务器上(这是从MySQL 8的默认值),复制连接参数保存在安全InnoDBmysql.slave_master_info的一部分RESET SLAVE运营在发生服务器崩溃或有意发行重启后立即RESET SLAVE,当START SLAVE发布服务器启动后,连接参数从表中检索。重置连接参数的故意,你需要使用重置所有的奴隶。如果master_info_repository=FILE设置服务器的行为,仍如以前一样。连接参数不保存,你必须发出一个CHANGE MASTER TO语句在服务器开始指定他们。

RESET SLAVE ALL清除ignore_server_ids列表设置CHANGE MASTER TO

RESET SLAVE不改变任何复制过滤器设置(如--replicate-ignore-table受影响的通道)的声明。然而,重置所有的奴隶删除复制过滤器被设置在通道中的语句删除。当删除通道或通道的重现,对奴隶的指定任何全球复制过滤器复制他们,没有特定渠道复制过滤器的应用。更多信息见第17.2.5.4,“复制通道滤波器”

RESET SLAVE原因一个隐式提交一项正在进行的交易。看到13.3.3部分,”声明,因为一个隐含的承诺”

如果从SQL线程是在复制临时表的中间时停了下来,和RESET SLAVE的发布,这些复制的临时表上删除的奴隶。

RESET SLAVE不重置心跳期(Slave_heartbeat_period)或ssl_verify_server_cert

13.4.2.5设置全局sql_slave_skip_counter语法

SET GLOBAL sql_slave_skip_counter = N

这个语句跳过下一个N从硕士开始This is useful for recovering from repeacting stops caused by a statement .

这一声明是有效的只有当奴隶的线程没有运行。否则,它将产生一个错误。

使用此语句时,它是要知道二进制日志实际上是组织成一个序列的群体称为重要事件组。每个项目组由一系列的事件。

  • 事务表,事件组对应的交易。

  • 对于非事务表,事件组对应一个单独的SQL语句。

笔记

一个事务可以包含更改交易和非事务表。

当你使用SET GLOBAL sql_slave_skip_counter跳过事件,结果是在一个组中,奴隶继续跳过事件直到结束小组。然后开始执行下一个事件组。

13.4.2.6开始从语法

START SLAVE [thread_types] [until_option] [connection_options] [channel_option]

thread_types:
    [thread_type [, thread_type] ... ]

thread_type:
    IO_THREAD | SQL_THREAD

until_option:
    UNTIL {   {SQL_BEFORE_GTIDS | SQL_AFTER_GTIDS} = gtid_set
          |   MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos
          |   RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos
          |   SQL_AFTER_MTS_GAPS  }

connection_options:
    [USER='user_name'] [PASSWORD='user_pass'] [DEFAULT_AUTH='plugin_name'] [PLUGIN_DIR='plugin_dir']


channel_option:
    FOR CHANNEL channel

gtid_set:
    uuid_set [, uuid_set] ...
    | ''

uuid_set:
    uuid:interval[:interval]...

uuid:
    hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh

h:
    [0-9,A-F]

interval:
    n[-n]

    (n >= 1)

START SLAVE没有thread_type选择开始的从属线程。I/O线程读取主服务器并将它们存储在中继日志事件。SQL线程读取中继日志事件和执行。START SLAVE要求REPLICATION_SLAVE_ADMINSUPER特权

如果START SLAVE成功启动从线程,则没有任何错误。然而,即使在这种情况下,它可能是从线程启动后停止(例如,因为他们不能够连接到主或读取二进制日志,或者一些其他的问题)。START SLAVE没有警告你这。你必须检查错误消息的线程产生的奴隶的奴隶的错误日志,或者检查他们正在运行令人满意SHOW SLAVE STATUS

START SLAVE原因一个隐式提交一项正在进行的交易。看到13.3.3部分,”声明,因为一个隐含的承诺”

gtid_next必须设置为自动在发布此声明

可选FOR CHANNEL channel条款使你名字的声明适用于复制通道。提供一个通道channel条款的适用开始的奴隶声明一个特定的复制通道。如果没有条款命名并没有额外的渠道存在,该声明适用于默认频道。如果一个START SLAVE声明没有定义一个通道,当使用多个渠道,这一说法开始为所有通道指定的线程。这种说法是不允许的group_replication_recovery频道看到第17.2.3,“复制通道”更多信息

MySQL支持热插拔的用户口令认证START SLAVE用户PASSWORDdefault_authPLUGIN_DIR选项,如下所示:

  • USER用户名称。不能设置为空或空字符串,如果左或撤消密码使用

  • PASSWORD密码:

  • DEFAULT_AUTH插件:名称;默认是MySQL本地认证。

  • PLUGIN_DIR位置:插件

你不能使用SQL_THREAD当指定任何选项用户PASSWORDdefault_auth,或PLUGIN_DIR,除非io_thread还提供了选项

看到第6.3.10,“认证”为更多的信息

如果一个不安全的连接使用任何这些选项,服务器发出警告发送密码以纯文本没有SSL / TLS是极不安全的

START SLAVE ... UNTIL支持另外两个选项使用全局事务标识符(gtids)(见部分下面,“复制与全球事务标识符”)。所有这些需要一组一个或多个全局事务标识符gtid_set作为一个参数(见gtid集,更多信息)

当没有thread_type指定,直到sql_before_gtids开始奴隶导致从SQL线程处理的交易,直到它达到第一交易的gtid列在gtid_set直到sql_after_gtids开始奴隶使奴隶的线程来处理所有的交易直到last交易在gtid_set已由螺纹加工。换句话说,直到sql_before_gtids开始奴隶导致从SQL线程来处理所有的交易发生在第一gtidgtid_set达到,和直到sql_after_gtids开始奴隶使奴隶的线程来处理所有的交易,包括那些gtids发现gtid_set每遇到一个交易,直到其gtid不集的一部分。在SQL _ _ gtidsSQL_AFTER_GTIDS每个支持sql_threadIO_THREAD选项,虽然使用io_thread他们目前没有影响

例如,START SLAVE SQL_THREAD UNTIL SQL_BEFORE_GTIDS = 3E11FA47-71CA-11E1-9E33-C80AA9429562:11-56导致从SQL线程来处理所有的交易从主人的server_uuid3e11fa47 - 71ca - 11e1 - 9e33 - c80aa9429562直到遇到交易具有序列号11;然后没有处理这个交易。换句话说,所有的交易上,包括序列号10的事务处理。执行START SLAVE SQL_THREAD UNTIL SQL_AFTER_GTIDS = 3E11FA47-71CA-11E1-9E33-C80AA9429562:11-56,另一方面,将导致从SQL线程获得刚刚提到的从主所有的交易,包括所有的交易通过56有序列号,然后停下来没有处理任何额外的交易;即,交易有序列号56将是最后的交易由从SQL线程牵强。

当使用多线程的奴隶slave_preserve_commit_order=0集,在已在下列情况下,中继日志执行事务的序列机会差距:

  • 杀死协调线程

  • 在应用线程出现错误后

  • mysqld意外关闭

使用START SLAVE UNTIL SQL_AFTER_MTS_GAPS语句使多线程的奴隶的工作线程只运行直到没有更多的差距是在中继日志中找到,然后停止。这句话可以sql_thread选项,但该声明的影响保持不变。它对奴隶的I/O线程没有效果(不能用IO_THREAD选项)

发行START SLAVE在一个多线程的奴隶在从中继日志执行交易序列的空白,产生一个警告。在这种情况下,该解决方案是使用START SLAVE UNTIL SQL_AFTER_MTS_GAPS,然后发出RESET SLAVE删除任何剩余的中继日志。看到第17.4.1.34,“复制和事务不一致”更多信息

改变一个奴隶失败多线程的单线程模式,可以发出以下系列报表中显示的顺序:

START SLAVE UNTIL SQL_AFTER_MTS_GAPS;

SET @@GLOBAL.slave_parallel_workers = 0;

START SLAVE SQL_THREAD;
笔记

可以查看正在运行的整个文本START SLAVE ...声明,包括任何用户PASSWORD使用的值,在输出SHOW PROCESSLIST。为运行的文字也是如此CHANGE MASTER TO声明,包括任何值,它采用master_userMASTER_PASSWORD

START SLAVE发送一个确认后送给用户的I/O线程和SQL线程已经开始。然而,I/O线程可能尚未连接。因此,一个成功的START SLAVE起因SHOW SLAVE STATUS显示Slave_SQL_Running=Yes,但这并不能保证Slave_IO_Running=Yes(因为Slave_IO_Running=Yes如果I/O线程正在运行连接)。有关更多信息,参见第13.7.6.34,“SHOW SLAVE STATUS语法”,和第17.1.7.1,“检查复制状态”

您可以添加IO_THREADsql_thread选择报表名称的线程启动。这个SQL_THREAD当指定任何选项无效用户PASSWORDdefault_auth,或PLUGIN_DIR,除非io_thread还提供了选项

一个UNTIL条款(until_option在前面的语法),可以添加到指定的奴隶应该启动和运行在SQL线程达到给定的点在主人指定的二进制日志,master_log_pos和master_log_file选项,或一个给定的点在从中继日志,标明RELAY_LOG_POSrelay_log_file选项当SQL线程达到指定的点,它停止。如果SQL_THREAD选择是在语句中指定,它开始只有SQL线程。否则,它开始从线程。如果SQL线程运行的直到条款被忽略并发出警告。你不能使用UNTIL条款与io_thread选项

也有可能与START SLAVE UNTIL指定一个停止点相对于一个给定的gtid或设置使用一个选项gtids在SQL _ _ gtidsSQL_AFTER_GTIDS如本节前面所说的。当使用这些选项,您可以指定sql_threadIO_THREAD,两者,或者两者都不是。如果你只指定sql_thread,那么只有从SQL线程被声明的影响;如果只IO_THREAD使用,那么只有I/O是影响了奴隶。如果两sql_threadIO_THREAD使用,或如果他们不使用,则SQL和I/O线程语句所影响。

这个UNTIL条款不支持多线程的奴隶除了也使用时SQL_AFTER_MTS_GAPS

对于一个UNTIL条款,您必须指定下列任何一:

  • 一个日志文件的名称和文件的位置

  • 无论是属于SQL_BEFORE_GTIDSSQL _后_ gtids

  • SQL_AFTER_MTS_GAPS

不要将主继电器日志选项。不要将日志文件选项gtid选项。

任何UNTIL条件是通过随后的复位STOP SLAVE声明一个START SLAVE声明不包括直到条款,或重新启动服务器。

指定的日志文件位置时,您可以使用IO_THREAD选项开始的奴隶…直到尽管只有SQL线程通过这项声明的影响。这个IO_THREAD选择在这样的情况下忽略。上述限制不适用于使用时的一个选项(gtid在SQL _ _ gtidsSQL_AFTER_GTIDSgtid选项支持的);sql_threadIO_THREAD如本节前面所说的

这个UNTIL条款可以用于调试的复制是有用的,或导致复制继续进行之前,你要避免从复制事件。例如,如果一个不明智的DROP TABLE声明是在主执行,您可以使用直到告诉奴隶执行了这一点但不远。找到什么是事件,使用mysqlbinlog与主人的二进制日志或从中继日志,或使用SHOW BINLOG EVENTS声明

如果你使用的是UNTIL有从进程复制查询部分,建议你开始奴隶与--skip-slave-start选项来防止SQL线程运行时,从服务器开始。这可能是最好的一个选项文件使用这个选项,而不是在命令行上,所以意外重启服务器,不使它被遗忘。

这个SHOW SLAVE STATUS声明包括输出字段显示的当前值直到条件

在很老的版本的MySQL(之前,这种说法被称为回答)SLAVE START。。。。。。。现在,语法产生的误差。

13.4.2.7停止从语法

STOP SLAVE [thread_types]

thread_types:
    [thread_type [, thread_type] ... ]

thread_type: IO_THREAD | SQL_THREAD

channel_option:
    FOR CHANNEL channel

停止线程的奴隶STOP SLAVE要求REPLICATION_SLAVE_ADMINSUPER特权。推荐的最佳实践是执行停止奴隶在奴隶前停止从服务器(见第5.1.15,“服务器关机过程”,更多信息)

使用基于行的日志格式:你应该执行STOP SLAVE停止从sql_thread在奴隶关闭服务器之前,如果你是复制的,使用非事务性存储引擎的表(见笔记在本节稍后)

喜欢START SLAVEThis statement may be used with the .io_threadSQL_THREAD选项名称或线程的线程被阻止。

STOP SLAVE原因一个隐式提交一项正在进行的交易。看到13.3.3部分,”声明,因为一个隐含的承诺”

gtid_next必须设置为自动在发布此声明

你能控制多久STOP SLAVE等待超时设置rpl_stop_slave_timeout系统变量。这可以用来避免死锁之间停止奴隶和其他奴隶的SQL语句中使用不同的客户端连接到奴隶。当超时值达到,发行客户端返回一个错误消息并停止等待,但STOP SLAVE教学效果仍在。一旦从线程不再忙碌的停止奴隶执行语句和从站

一些CHANGE MASTER TO语句也可以从正在运行,根据从SQL状态和I/O线程。然而,使用停止奴隶之前执行CHANGE MASTER TO在这样的情况下,仍然支持。看到第13.4.2.1,“变化掌握语法”,和第17.3.8,“转换大师在故障转移期间”为更多的信息

可选FOR CHANNEL channel条款使你名字的声明适用于复制通道。提供一个通道channel条款的适用停止奴隶声明一个特定的复制通道。如果没有通道命名并没有额外的渠道存在,该声明适用于默认频道。如果一个STOP SLAVE声明没有命名的通道时,使用多通道,这个声明指定线程的所有通道。此语句不能用group_replication_recovery频道看到第17.2.3,“复制通道”更多信息

采用基于语句的复制时:同时具有开放的临时表更改主可能不安全。这是原因之一,基于声明临时表的复制是不推荐。你可以找出是否有任何临时表的奴隶通过检查的价值Slave_open_temp_tables当使用基于语句的复制;,这个值应该是0之前执行改变主。如果有任何临时表打开的奴隶,发行CHANGE MASTER TO后发表声明停止奴隶原因ER_WARN_OPEN_TEMP_TABLES_MUST_BE_ZERO警告

使用多线程时(奴隶slave_parallel_workers是一个非零的值),在从中继日志执行事务的序列有任何间隙关闭,停止辅助线程的一部分。如果从意外停止(例如由于在工作线程,错误或另一个线程发出KILL)而STOP SLAVE执行语句,执行交易,从中继日志的顺序可能不一致。看到第17.4.1.34,“复制和事务不一致”更多信息

如果当前的复制事件组已修改一个或多个非事务表,停止奴隶等待长达60秒的项目组来完成,除非你的问题KILL QUERYKILL CONNECTION对奴隶的SQL线程声明。如果在超时事件组仍不完全,记录错误消息。

控制组的复制13.4.3 SQL语句

本节提供有关用于控制组复制报表信息。

13.4.3.1开始group_replication语法

START GROUP_REPLICATION

星舰集团复制。这句话需要GROUP_REPLICATION_ADMINSUPER特权。如果super_read_only=ON和成员应该加入作为一个主要的,super_read_only是集关闭一次集团复制成功

13.4.3.2停止集团重新复制合成器

STOP GROUP_REPLICATION

集团停止复制。This statement requires theGROUP_REPLICATION_ADMINSUPER特权。一旦你的问题STOP GROUP_REPLICATION的成员设置super_read_only=ON,以确保没有写可以使成员组复制停止。

警告

使用此语句极端谨慎,因为它消除了服务器实例从组,意味着它不再被复制的一致性保证机制保护组。是完全安全的,确保你的应用程序可以不再发行这一说法避免陈旧的读取连接到实例。

13.4.3.3功能配置的组复制模式

以下能够使你控制的模式,复制组运行,单发或多发模式。

集团公司的复制品转换器开关

使用group_replication_switch_to_single_primary_mode()改变一组运行在多主模式单一的基本模式。必须在一个复制组成员发出的多主模式运行。例如:

选择group_replication_switch_to_single_primary_mode()

单一的初级选举的选举权重配置控制。推翻选举过程和配置一个特定成员过程中的主要应用SELECT group_replication_switch_to_single_primary_mode(member_uuid);哪里member_uuid是的server_uuid这应该成为初级会员

集团_复制_开关_ to _ _ _多主模式(语法);

使用group_replication_switch_to_multi_primary_mode()改变一组运行在单一的主模式的多主模式。必须在一个复制组成员发出单原运行模式。例如:

选择group_replication_switch_to_multi_primary_mode()

所有属于该组的成员成为初选。

13.5编写的SQL语句的语法

MySQL 8提供了对服务器端的准备好的语句的支持。这种支持利用高效的客户端/服务器的二进制协议。使用准备好的语句和参数值的占位符有以下好处:

  • 解析语句每次执行开销少。通常,几乎相同的报表数据库应用程序处理大量,与文字或可变的条款如值变化WHERE用于查询和删除,配置更新,和VALUES插入物

  • 防止SQL注入攻击。参数值可以包含转义的SQL报价和分隔符。

编制报表应用程序

您可以使用服务器端的准备好的语句通过客户端编程接口,包括MySQL提供的C API客户端库MySQL连接器/ CC程序,MySQL连接器/ JJava程序,鸭MySQL连接器/网利用网络技术方案。例如,C API提供了一组函数调用,弥补其声明的API。看到第27.7.8,“C API编写的语句”。其他语言的接口,可以提供的准备好的语句,使用二进制协议的客户端连接的C库的支持,一个例子是mysqli扩展,可在PHP 5及以后。

准备好的语句在sql脚本

另一个SQL语句编写的接口是可用的。这个接口不使用二进制协议通过事先准备好的声明API一样有效,但不需要编程,因为它可直接在SQL级:

  • 你可以用它当没有编程接口提供给你。

  • 你可以使用它从任何程序,可以发送SQL语句到服务器来执行,如MySQL客户端程序

  • 你甚至可以如果客户端使用的是旧版本的客户端库使用它,只要你连接到一个服务器上运行MySQL 4.1或更高版本。

为准备好的语句的SQL语法的目的是用于这样的情况:

  • 测试的准备好的语句在你的应用程序的编码工作之前。

  • 使用准备好的语句时,你得不到支持他们的编程API。

  • 以交互方式解决的准备好的语句的应用问题。

  • 创建一个测试案例,再现的准备好的语句有问题,所以你可以提交一个bug报告。

准备和释放,execute,准备报表

为准备好的语句的SQL语法是基于三的SQL语句:

下面的例子显示准备语句,计算一个三角形的斜边鉴于双方长的两个等价的方法。

第一个示例显示如何通过使用一个字符串提供声明全文文本创建一个准备好的声明:

mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql> SET @a = 3;
mysql> SET @b = 4;
mysql> EXECUTE stmt1 USING @a, @b;
+------------+
| hypotenuse |
+------------+
|          5 |
+------------+
mysql> DEALLOCATE PREPARE stmt1;

第二个例子类似,但提供的语句作为一个用户变量文本:

mysql> SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql> PREPARE stmt2 FROM @s;
mysql> SET @a = 6;
mysql> SET @b = 8;
mysql> EXECUTE stmt2 USING @a, @b;
+------------+
| hypotenuse |
+------------+
|         10 |
+------------+
mysql> DEALLOCATE PREPARE stmt2;

这里是另外的一个例子,演示了如何选择在运行时执行的查询的表,存储的表的名称作为一个用户变量:

mysql> USE test;
mysql> CREATE TABLE t1 (a INT NOT NULL);
mysql> INSERT INTO t1 VALUES (4), (8), (11), (32), (80);

mysql> SET @table = 't1';
mysql> SET @s = CONCAT('SELECT * FROM ', @table);

mysql> PREPARE stmt3 FROM @s;
mysql> EXECUTE stmt3;
+----+
| a  |
+----+
|  4 |
|  8 |
| 11 |
| 32 |
| 80 |
+----+

mysql> DEALLOCATE PREPARE stmt3;

一个准备好的声明是特定的会话创建它。如果你终止会话没有释放一个事先准备好的声明中,服务器会自动释放。

一个准备好的声明也是全球会议。如果你创建了一个事先准备好的声明在一个存储程序,它是不会释放存储程序结束时。

防止太多的准备好的语句同时被创造,集max_prepared_stmt_count系统变量。防止使用准备好的语句,将值设置为0。

在准备语句允许SQL语法

下面的SQL语句可以作为编制报表:

ALTER TABLE
ALTER USER
ANALYZE TABLE
CACHE INDEX
CALL
CHANGE MASTER
CHECKSUM {TABLE | TABLES}
COMMIT
{CREATE | DROP} INDEX
{CREATE | RENAME | DROP} DATABASE
{CREATE | DROP} TABLE
{CREATE | RENAME | DROP} USER
{CREATE | DROP} VIEW
DELETE
DO
FLUSH {TABLE | TABLES | TABLES WITH READ LOCK | HOSTS | PRIVILEGES
  | LOGS | STATUS | MASTER | SLAVE | USER_RESOURCES}
GRANT
INSERT
INSTALL PLUGIN
KILL
LOAD INDEX INTO CACHE
OPTIMIZE TABLE
RENAME TABLE
REPAIR TABLE
REPLACE
RESET {MASTER | SLAVE}
REVOKE
SELECT
SET
SHOW {WARNINGS | ERRORS}
SHOW BINLOG EVENTS
SHOW CREATE {PROCEDURE | FUNCTION | EVENT | TABLE | VIEW}
SHOW {MASTER | BINARY} LOGS
SHOW {MASTER | SLAVE} STATUS
SLAVE {START | STOP}
TRUNCATE TABLE
UNINSTALL PLUGIN
UPDATE

与SQL标准符合性,即诊断报表不可,MySQL不支持如下的准备好的语句:

  • SHOW WARNINGS显示计数(*)警告

  • SHOW ERRORS显示计数(*)的错误

  • 包含的任何参考报表warning_counterror_count系统变量

其他语句不在MySQL 8的支持。

一般来说,语句不允许在SQL语句编写的也不允许在存储程序。例外的是注意第1,“限制存储的程序”

元数据更改表或视图被准备语句检测导致语句自动复配时,下一个执行。有关更多信息,参见8.10.3节,“缓存的准备好的语句和存储的程序”

占位符可以用于的争论LIMIT当使用预处理语句的子句。看到第13.2.10,选择“语法”

在制备CALLstatements used withPREPAREEXECUTE占位符的支持,INOUT参数是在MySQL 8中可用的开始。看到第13.2.1,“调用语法”,例如,解决早期版本。占位符可以用于IN无论版参数

为准备好的语句的SQL语法不可嵌套的方式。这是一个声明,通过PREPARE自己不能成为一个PREPAREEXECUTE,或DEALLOCATE PREPARE声明

为准备好的语句的SQL语法不同于使用事先准备好的声明的API调用。例如,您不能使用mysql_stmt_prepare()C API函数编写PREPAREEXECUTE,或DEALLOCATE PREPARE声明

为准备好的语句的SQL语法可以在存储过程中使用,但不能在存储函数或触发器。然而,光标不能用于动态语句的准备和执行PREPAREEXECUTE。一个游标的语句是在光标创建时间检查,这样的声明不能动。

为准备好的语句的SQL语法不支持多语句(即多个声明一个字符串分隔内;字符)

写C程序使用CALLSQL语句执行存储包含语句编写的程序,client_multi_results国旗必须启用。这是因为每个CALL返回一个结果显示呼叫状态,除了可能在程序执行的语句返回的结果集。

CLIENT_MULTI_RESULTS可以使你打电话时mysql_real_connect(),直接通过client_multi_results标志本身,或隐式地通过CLIENT_MULTI_STATEMENTS(这也使client_multi_results)。For Additional Information,see第13.2.1,“调用语法”

13.5.1准备表

PREPARE stmt_name FROM preparable_stmt

这个PREPARE声明准备SQL语句,它指定一个名字,stmt_name,所指声明后。该声明是执行EXECUTE和发布DEALLOCATE PREPARE。例如,看13.5节,“编写SQL语句语法”

表名不区分大小写preparable_stmt是一个字符串或用户变量包含SQL语句的文本。文本必须代表一个语句,语句不多。在声明,可以使用的字符参数标记表示数据值都被绑定到查询后当你执行它。这个?人物不应该包含在引号中,即使你打算将它们绑定到字符串值。参数标记可以用在数据值应该出现,不是SQL关键字,标识符,等等。

如果一个准备好的声明与已经存在的名字,它是隐含在新释放报表准备。这意味着,如果新的声明包含错误和不准备,返回一个错误并没有声明具有给定名称的存在。

一个准备好的声明的范围内它是创建会话,这几方面的含义:

  • 一个准备好的声明在一个会话中创建的不可用其他会话。

  • 当会议结束时,无论是正常或异常,其编制报表不再存在。如果自动重新启用,客户不通知的连接丢失。为此,客户可能希望禁用自动重新连接。看到第27.7.24,“C API自动重联控制”

  • 一个准备好的声明在一个存储程序继续程序执行完毕,可以执行外部程序后存在了。

  • 声明编写的存储程序的上下文不能引用存储过程或函数的参数和局部变量,因为他们超出范围的程序结束时,将无法被声明在以后执行外部程序。作为一种变通方法,指的不是用户定义的变量,也看到会话范围;9.4节,“用户定义的变量

13.5.2执行语法

EXECUTE stmt_name
    [USING @var_name [, @var_name] ...]

在准备的声明PREPARE,你执行一个EXECUTE声明,指的是事先准备好的声明的名字。如果事先准备好的声明中包含的任何参数标记,您必须提供使用子句列出用户变量包含的值绑定到参数。参数值只能由用户变量提供,和USING条款必须具体名称多个变量在声明中的参数标记数。

你可以执行一个给定的声明多次,通过不同的变量或设置变量不同的值在每次执行。

例如,看13.5节,“编写SQL语句语法”

13.5.3释放准备表

{DEALLOCATE | DROP} PREPARE stmt_name

释放一个准备好的声明中产生PREPARE,使用DEALLOCATE PREPARE声明,指的是事先准备好的声明的名字。试图在释放它导致错误执行一个事先准备好的声明。如果太多的准备好的语句而不释放任何释放准备声明或会议结束的时候,你可能会遇到的上限执行的max_prepared_stmt_count系统变量

例如,看13.5节,“编写SQL语句语法”

13.6复合语句语法

本节描述的语法BEGIN ... END复合语句与其他语句可用于存储程序的主体:存储过程和函数、触发器和事件。这些对象在SQL代码定义存储在以后调用服务器(见23章,存储程序和视图

复合语句是一块可以包含其他块;声明变量、条件处理,以及游标;流量控制构造如循环和条件测试。

13.6.1开始…端复合语句语法

[begin_label:] BEGIN
    [statement_list]
END [end_label]

BEGIN ... END语法是用来写字的复合语句,可出现在程序存储(存储过程、函数、触发器、事件)。复合语句可以包含多条语句,包围开始END关键词statement_list表示一个或多个语句,每个终止一个分号()语句分隔符。thestatement_list本身是可选的,所以空的复合语句(开始结束)是合法的

BEGIN ... END块可以嵌套

使用多个报表要求客户端能够发送语句字符串包含;分隔符表。在theMySQL命令行客户端,这是处理的delimiter命令。改变语句结束符(例如,对//许可证)要使用一个程序体。例如,看23.1节,“定义存储的程序”

BEGIN ... END块可以标记。看到第13.6.2,”声明标签语法”

可选[NOT] ATOMIC条款是不支持的。这意味着任何事务的保存点设置在指令块的开始和开始在这种情况下使用的条款已经对当前的交易没有影响。

笔记

在所有的存储程序,解析器将BEGIN [WORK]构象的研究BEGIN ... END块。在这样的背景下开始交易,使用START TRANSACTION相反

13.6.2 syntax语言标签

[begin_label:] BEGIN
    [statement_list]
END [end_label]

[begin_label:] LOOP
    statement_list
END LOOP [end_label]

[begin_label:] REPEAT
    statement_list
UNTIL search_condition
END REPEAT [end_label]

[begin_label:] WHILE search_condition DO
    statement_list
END WHILE [end_label]

标签是允许的BEGIN ... END块的LOOPREPEAT,和WHILE声明.对于那些语句标签使用以下规则:

  • begin_label必须后跟一个冒号

  • begin_label可以不end_label。如果end_label是存在的,它必须是相同的begin_label

  • end_label不能没有begin_label

  • 在同一级别上的标签必须清晰。

  • 标签可以有16个字符长。

引用在标记构建一个标签,使用ITERATELEAVE声明。下面的示例使用这些语句继续或终止循环迭代:

CREATE PROCEDURE doiterate(p1 INT)BEGIN  label1: LOOP    SET p1 = p1 + 1;    IF p1 < 10 THEN ITERATE label1; END IF;    LEAVE label1;  END LOOP label1;END;

一块标签的范围不包括块内声明的处理代码。详情见第13.6.7.2,”声明…异常处理的语法”

13.6.3声明的语法

这个DECLARE声明用于定义各种项目的本地程序:

DECLARE只有在一个允许的BEGIN ... END复合语句必须在它的开始,在任何其他语句。

声明必须遵循一定的顺序。游标声明必须出现在处理程序声明。变量和条件的声明必须出现在光标或处理程序声明。

13.6.4变量中存储的程序

系统变量和用户定义的变量可用于存储程序,正如他们可以在存储程序中使用。此外,存储的程序可以使用DECLARE定义局部变量和存储程序(过程和函数)可以宣布采取沟通价值的日常与客户之间的参数。

关于局部变量的作用域信息和MySQL如何解决模糊的名字,看第13.6.4.2,“局部变量的范围和分辨率”

不允许指定值DEFAULT在存储过程或函数的参数或程序存储局部变量(例如与配置var_name= DEFAULT声明)。在MySQL 8中,这样的结果是一个语法错误。

13.6.4.1局部变量声明的语法

DECLARE var_name [, var_name] ... type [DEFAULT value]

这条语句声明的局部变量中存储的程序。提供一个变量的默认值,包括DEFAULT条款.该值可以指定为一个表达;它不需要是一个常数。如果默认条款缺失,初始值NULL

局部变量当作存储程序参数对数据类型和溢出检查。看到第13.1.15,创建过程和创建函数的语法”

变量声明必须出现在光标前或处理程序声明。

局部变量名不区分大小写。允许的字符和举证规则同其他标识符相同,如9.2节,“架构对象名称”

局部变量的范围是BEGIN ... END块中声明它。变量可以被称为块嵌套声明块,除了那些块,声明一个变量具有相同的名字。

在变量声明的例子,看第13.6.4.2,“局部变量的范围和分辨率”

13.6.4.2局部变量的范围和分辨率

局部变量的范围是BEGIN ... END块中声明它。变量可以被称为块嵌套声明块,除了那些块,声明一个变量具有相同的名字。

因为局部变量的范围只在存储程序执行,对它们的引用不在的准备好的语句在存储程序创建允许。事先准备好的声明范围是当前会话,而不是存储程序,这样的语句可以被程序结束后执行的,在这一点上的变量不再范围。例如,SELECT ... INTO local_var不能作为一个事先准备好的声明。这种限制也适用于存储过程和函数的参数。看到第13.5.1”准备,语法”

局部变量不应该作为一个表的列名称相同。如果一个SQL语句,如SELECT ... INTO声明中,包含一个参考一柱和声明同名的局部变量,MySQL目前解释参考作为变量的名字。考虑下面的程序定义:

CREATE PROCEDURE sp1 (x VARCHAR(5))BEGIN  DECLARE xname VARCHAR(5) DEFAULT 'bob';  DECLARE newname VARCHAR(5);  DECLARE xid INT;  SELECT xname, id INTO newname, xid    FROM table1 WHERE xname = xname;  SELECT newname;END;

MySQL的解释xnameSELECT声明了一个可供参考的expr变量而不是xname专栏。因此,当程序sp1()叫的新名称变量的返回值'bob'不论其价值表1专栏

同样,在下面的过程中光标定义包含一个SELECT声明指expr。MySQL将这作为一个参考的那个名字的变量而不是列参考。

CREATE PROCEDURE sp2 (x VARCHAR(5))
BEGIN
  DECLARE xname VARCHAR(5) DEFAULT 'bob';
  DECLARE newname VARCHAR(5);
  DECLARE xid INT;
  DECLARE done TINYINT DEFAULT 0;
  DECLARE cur1 CURSOR FOR SELECT xname, id FROM table1;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

  OPEN cur1;
  read_loop: LOOP
    FETCH FROM cur1 INTO newname, xid;
    IF done THEN LEAVE read_loop; END IF;
    SELECT newname;
  END LOOP;
  CLOSE cur1;
END;

参见第1,“限制存储的程序”

13.6.5流控制语句

MySQL支持IFCASEITERATELEAVELOOPWHILE,和REPEAT在存储程序流程控制结构。它也支持RETURN在存储功能

许多这些结构包含其他报表,由以下部分的语法规范说明。这样的结构可以嵌套。例如,一个IF语句可能包含WHILE环,它本身包含了一个CASE声明

MySQL不支持FOR

13.6.5.1 Case语法

CASE case_value
    WHEN when_value THEN statement_list
    [WHEN when_value THEN statement_list] ...
    [ELSE statement_list]
END CASE

CASE
    WHEN search_condition THEN statement_list
    [WHEN search_condition THEN statement_list] ...
    [ELSE statement_list]
END CASE

这个CASE用于存储程序语句实现复杂条件的构建。

笔记

也有一个CASE表达这是什么?CASE陈述这里描述的。看到12.4节,“控制流”功能。这个CASE语句不能有其他的空条款,并终止END CASE而不是结束

for the first表,case_value是一种表达。这个值是相对于when_value表达在每个什么时候直到他们中的一个条款是平等的。当一个平等的when_value被发现,相应的然后条款statement_list执行。如果没有when_value是平等的其他的条款statement_listexecutes,if there is one。

这个语法不能用于对平等与测试NULL因为NULL = NULL是错误的。看到第3.3.4.6,“空值”

第二语法,每个WHEN条款search_condition表达式求值直到一个是真的,在这一点上,其相应的然后条款statement_list执行。如果没有search_condition是平等的其他的条款statement_listexecutes,if there is one。

如果没有when_valuesearch_condition匹配值测试和CASE语句不包含其他的条款,一案例没有发现case语句错误的结果

每个statement_list由一个或多个SQL语句;空statement_list是不允许的

处理的情况下,没有任何价值匹配WHEN条款,使用其他的包含一个空BEGIN ... END块,如图所示。(压痕用在这里其他的目的明确的条款是唯一的,是不重要的。)

DELIMITER |

CREATE PROCEDURE p()
  BEGIN
    DECLARE v INT DEFAULT 1;

    CASE v
      WHEN 2 THEN SELECT v;
      WHEN 3 THEN SELECT 0;
      ELSE
        BEGIN
        END;
    END CASE;
  END;
  |

如果13.6.5.2语法

IF search_condition THEN statement_list
    [ELSEIF search_condition THEN statement_list] ...
    [ELSE statement_list]
END IF

这个IF用于存储程序语句实现一个基本条件建设。

笔记

也有一个IF()功能这是什么?IF陈述这里描述的。看到12.4节,“控制流”功能。这个IF语句可以有然后ELSE,和条款,并终止END IF

如果search_condition计算结果为true,相应的然后ELSEIF条款statement_list执行。如果没有search_condition比赛的其他的条款statement_list执行

每个statement_list由一个或多个SQL语句;空statement_list是不允许的

一个IF ... END IF块,像所有其他流量控制模块内部存储的程序使用,必须以分号结束,如本例所示:

DELIMITER //CREATE FUNCTION SimpleCompare(n INT, m INT)  RETURNS VARCHAR(20)  BEGIN    DECLARE s VARCHAR(20);    IF n > m THEN SET s = '>';    ELSEIF n = m THEN SET s = '=';    ELSE SET s = '<';    END IF;    SET s = CONCAT(n, ' ', s, ' ', m);    RETURN s;  END //DELIMITER ;

与其他流程控制结构,IF ... END IF块可以嵌套在其他流量控制结构,包括其他IF声明.每个IF必须通过自己的终止最后如果其次是一个分号。你可以使用压痕使嵌套的流量控制块更容易阅读的人(虽然这并不需要MySQL),如下所示:

DELIMITER //

CREATE FUNCTION VerboseCompare (n INT, m INT)
  RETURNS VARCHAR(50)

  BEGIN
    DECLARE s VARCHAR(50);

    IF n = m THEN SET s = 'equals';
    ELSE
      IF n > m THEN SET s = 'greater';
      ELSE SET s = 'less';
      END IF;

      SET s = CONCAT('is ', s, ' than');
    END IF;

    SET s = CONCAT(n, ' ', s, ' ', m, '.');

    RETURN s;
  END //

DELIMITER ;

在这个例子中,内IF如果只计算N不等于m

13.6.5.3 iterate语法

ITERATE label

ITERATE只能出现在LOOPREPEAT,和WHILE声明.ITERATE方法再次启动回路

例如,看第13.6.5.5,“循环语法”

13.6.5.4把语法

LEAVE label

这个语句是用来出口的流量控制结构,具有特定的标签。如果标签是最外层的存储程序块,LEAVE退出程序

LEAVE可以用在BEGIN ... END或循环结构(LOOPREPEATWHILE

例如,看第13.6.5.5,“循环语法”

13.6.5.5循环语句的语法

[begin_label:] LOOP
    statement_list
END LOOP [end_label]

LOOP实现了一个简单的循环结构,使中的语句重复执行,其中包含一个或多个语句,每个终止一个分号()语句分隔符。内循环语句重复直到循环终止。通常,这是通过一个LEAVE声明。在存储函数,RETURN也可以使用,其功能完全退出。

不包括终止循环语句的结果在一个无限循环。

LOOP语句可以标记。关于标签的使用规则,看第13.6.2,”声明标签语法”

例子:

CREATE PROCEDURE doiterate(p1 INT)
BEGIN
  label1: LOOP
    SET p1 = p1 + 1;
    IF p1 < 10 THEN
      ITERATE label1;
    END IF;
    LEAVE label1;
  END LOOP label1;
  SET @x = p1;
END;

13.6.5.6重复语法

[begin_label:] REPEAT
    statement_list
UNTIL search_condition
END REPEAT [end_label]

在语句表REPEAT语句重复直到search_condition表达的是真的。因此,一个REPEAT总是进入循环至少一次。statement_list包含一个或多个语句,每个终止一个分号(页:1

REPEAT语句可以标记。关于标签的使用规则,看第13.6.2,”声明标签语法”

例子:

mysql> delimiter //

mysql> CREATE PROCEDURE dorepeat(p1 INT)
    -> BEGIN
    ->   SET @x = 0;
    ->   REPEAT
    ->     SET @x = @x + 1;
    ->   UNTIL @x > p1 END REPEAT;
    -> END
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> CALL dorepeat(1000)//
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @x//
+------+
| @x   |
+------+
| 1001 |
+------+
1 row in set (0.00 sec)

13.6.5.7返回语法

RETURN expr

这个RETURN语句终止执行和存储函数返回值expr给函数的调用者。必须有至少一个RETURN在存储函数声明。如果函数有多个退出点不止一个。

这种说法是不使用存储过程,触发器或事件。这个LEAVE语句可用于退出存储这些类型的程序。

13.6.5.8而句法

[begin_label:] WHILE search_condition DO
    statement_list
END WHILE [end_label]

在语句表WHILE语句重复只要search_condition表达的是真的statement_list由一个或多个SQL语句,终止一个分号(页:1

WHILE语句可以标记。关于标签的使用规则,看第13.6.2,”声明标签语法”

例子:

CREATE PROCEDURE dowhile()
BEGIN
  DECLARE v1 INT DEFAULT 5;

  WHILE v1 > 0 DO
    ...
    SET v1 = v1 - 1;
  END WHILE;
END;

13.6.6 cursors

MySQL支持内部存储的程序的光标。在嵌入式SQL的语法是。游标有这些特性:

  • 敏感:服务器可能或不可能复制其结果表

  • 只读:不可更新的

  • 非滚动:可以穿越只在一个方向,不能跳过的行

游标声明必须出现在声明变量和条件处理后的声明。

例子:

CREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR(16);
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES (a,b);
    ELSE
      INSERT INTO test.t3 VALUES (a,c);
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;

13.6.6.1光标接近语法

CLOSE cursor_name

这一声明关闭先前打开的游标。例如,看第13.6.6,“光标”

如果光标不开发生错误。

如果没有显式关闭,光标在结束BEGIN ... END块,它被宣布

13.6.6.2游标声明的语法

DECLARE cursor_name CURSOR FOR select_statement

这条语句声明游标并将其与SELECT语句检索行将走过的光标。行获取后,使用FETCH声明。《retrieved列数的SELECT声明必须匹配输出变量中指定的号码FETCH声明

这个SELECT语句不能有条款.

游标声明必须出现在声明变量和条件处理后的声明。

一个存储程序可能包含多个指针的声明,但每个游标声明在一个给定的块必须有一个唯一的名称。例如,看第13.6.6,“光标”

信息可以通过SHOW语句,用光标与获得同等的信息在许多情况下,它是可能的information_schema

13.6.6.3 cursor fetch语法

FETCH [[NEXT] FROM] cursor_name INTO var_name [, var_name] ...

这个语句获取下一行的SELECT声明指定游标关联(它必须是开放的),并提出了光标指针。如果行存在,读取的列存储在命名变量。检索的列数SELECT声明必须匹配输出变量中指定的号码FETCH声明

如果没有更多的行是可用的,一个没有数据的条件下发生的SQLSTATE值'02000'。为了检测这种情况下,你可以为它设置一个程序(或一个没有找到条件)。例如,看第13.6.6,“光标”

要知道一个操作,如SELECT或另一个,也可能会导致处理器执行相同的条件下,通过提高。如果有必要区分操作提出的条件,将运行在它自己的BEGIN ... END块,它可以与自己的处理程序关联。

13.6.6.4光标打开语法

OPEN cursor_name

这句话打开以前声明的游标。例如,看第13.6.6,“光标”

13.6.7条件处理

存储程序执行过程中产生的,需要特殊处理的可能条件,如退出当前程序块或继续执行。处理程序可以为一般条件如警告或例外规定,或特定条件下,如一个特定的错误代码。具体情况可指定名称和简称的方式在处理程序。

名称的条件下,使用DECLARE ... CONDITION声明。声明一个处理程序,使用DECLARE ... HANDLER声明。看到第13.6.7.1,”声明…条件语法”,和第13.6.7.2,”声明…异常处理的语法”。关于服务器如何选择处理信息时的情况,看第13.6.7.6,“范围规则处理”

提高的情况下,使用SIGNAL声明。两个修改状态信息在A是使用空调,RESIGNAL。看到第13.6.7.1,”声明…条件语法”,和第13.6.7.2,”声明…异常处理的语法”

从诊断区域检索信息,使用GET DIAGNOSTICS声明(见第13.6.7.3,“诊断学语法”)。关于诊断方面的信息,看第13.6.7.7,“MySQL诊断区”

13.6.7.1声明…条件语法

DECLARE condition_name CONDITION FOR condition_value

condition_value:
    mysql_error_code
  | SQLSTATE [VALUE] sqlstate_value

这个DECLARE ... CONDITION语句声明一个命名的错误条件,将一个名字与条件,需要特定的处理。该名称可以是指在随后的DECLARE ... HANDLER声明(见第13.6.7.2,”声明…异常处理的语法”

条件声明必须出现在光标或处理程序声明。

这个condition_valueDECLARE ... CONDITION表示特定条件或类条件与条件名副。它可以采取下列形式:

  • mysql_error_code:整数表示一个MySQL错误代码。

    不要使用MySQL错误代码0,表示成功而不是一个错误条件。在一系列的MySQL错误码,看第三,“服务器错误代码和消息”

  • [价值]的SQLSTATEsqlstate_value:5个字符的字符串表示的SQLSTATE值。

    不要用SQLSTATE值开头'00'因为那些指示成功,而不是一个错误条件。在一系列的SQLSTATE值,见第三,“服务器错误代码和消息”

条件名称简称SIGNAL或使用RESIGNAL语句必须用SQLSTATE值有关,不是MySQL错误代码。

使用名称的条件可以使程序代码更清晰。例如,该处理程序将试图删除不存在的表,但这是明显的只有你知道1051是MySQL的错误代码未知的表

DECLARE CONTINUE HANDLER FOR 1051
  BEGIN
    -- body of handler
  END;

通过对条件声明一个名称,该处理程序的目的是更容易看到:

DECLARE no_such_table CONDITION FOR 1051;
DECLARE CONTINUE HANDLER FOR no_such_table
  BEGIN
    -- body of handler
  END;

这里是一个命名为相同的条件,但基于相应的SQLSTATE值而不是MySQL错误代码:

DECLARE no_such_table CONDITION FOR SQLSTATE '42S02';
DECLARE CONTINUE HANDLER FOR no_such_table
  BEGIN
    -- body of handler
  END;

13.6.7.2宣布…表处理程序

DECLARE handler_action HANDLER
    FOR condition_value [, condition_value] ...
    statement

handler_action:
    CONTINUE
  | EXIT
  | UNDO

condition_value:
    mysql_error_code
  | SQLSTATE [VALUE] sqlstate_value
  | condition_name
  | SQLWARNING
  | NOT FOUND
  | SQLEXCEPTION

这个DECLARE ... HANDLER语句指定处理器与一个或多个条件的交易。如果这些条件发生时,指定的statement执行statement可以是一个简单的语句,如配置var_name=value复合语句,或用开始END(见第13.6.1,”开始…端复合语句语法”

处理程序声明必须出现在声明变量或条件。

这个handler_action值指示处理程序以处理程序语句执行后,采取什么样的行动:

  • CONTINUE:当前程序继续执行

  • EXIT终止执行的:BEGIN ... END在复合语句的处理程序声明。即使情况发生在一个块内这是真的。

  • UNDO:不支持

这个condition_valueDECLARE ... HANDLER表示特定条件或条件激活处理程序类。它可以采取下列形式:

  • mysql_error_code:整数表示一个MySQL错误代码,如1051指定未知的表

    DECLARE CONTINUE HANDLER FOR 1051
      BEGIN
        -- body of handler
      END;
    

    不要使用MySQL错误代码0,表示成功而不是一个错误条件。在一系列的MySQL错误码,看第三,“服务器错误代码和消息”

  • [价值]的SQLSTATEsqlstate_value:5个字符的字符串表示的SQLSTATE值,如42s01’。”指定未知的表

    DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02'
      BEGIN
        -- body of handler
      END;
    

    不要用SQLSTATE值开头'00'因为那些指示成功,而不是一个错误条件。在一系列的SQLSTATE值,见第三,“服务器错误代码和消息”

  • condition_name一名先前指定的条件:DECLARE ... CONDITION。一个条件名称可以与MySQL错误代码或SQLSTATE值相关联的。看到第13.6.7.1,”声明…条件语法”

  • SQLWARNING:为SQLSTATE值,开始上课速记“01”

    DECLARE CONTINUE HANDLER FOR SQLWARNING
      BEGIN
        -- body of handler
      END;
    
  • NOT FOUND:为SQLSTATE值,开始上课速记“02”。这是有关在游标的语境和用于控制当光标到达数据集的最后。如果没有更多的行是可用的,一个没有数据的条件下发生的SQLSTATE值'02000'。为了检测这种情况下,你可以为它或为设立一个处理程序没有找到条件

    DECLARE CONTINUE HANDLER FOR NOT FOUND
      BEGIN
        -- body of handler
      END;
    

    另一个例子,看第13.6.6,“光标”。这个NOT FOUND条件也适用选择成var_list语句检索没有行

  • SQLEXCEPTION:对于不开始SQLSTATE值班速记“00”'01',或“02”

    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
      BEGIN
        -- body of handler
      END;
    

关于服务器如何选择处理信息时的情况,看第13.6.7.6,“范围规则处理”

如果发生任何处理器已经宣布,采取的行动取决于条件类:

  • SQLEXCEPTION存储程序的终止条件,在提出的条件语句,如果有出口处理程序。如果程序被另一个存储程序,调用程序处理的情况下使用处理器的选择规则应用到自己的程序。

  • SQLWARNING条件,程序继续执行,好像有一个继续处理程序

  • NOT FOUND的条件,如果条件为正常饲养,动作继续。如果它被SIGNALRESIGNAL,动作出口

下面的示例使用一个处理程序SQLSTATE '23000',出现的重复键错误:

MySQL的&#62;CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));查询好,为受影响的行(0.001秒)MySQL &#62;delimiter //MySQL的&#62;CREATE PROCEDURE handlerdemo ()-&#62;BEGIN-&#62;DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;-&#62;SET @x = 1;-&#62;INSERT INTO test.t VALUES (1);-&#62;SET @x = 2;-&#62;INSERT INTO test.t VALUES (1);-&#62;SET @x = 3;-&#62;END;-&#62;//查询好,为受影响的行(0.001秒)MySQL &#62;CALL handlerdemo()//查询好,为受影响的行(0.001秒)MySQL &#62;SELECT @x//------ | @ X | ------ | 3 | ------ 1行集(0秒)

注意:@x程序执行后,发现错误后继续执行程序的发生。如果DECLARE ... HANDLER声明已经不存在,MySQL会采取默认动作(出口)之后的第二INSERT由于未能主键约束,和SELECT @x会回来的

忽略一个条件,申报CONTINUE处理它,将它与一个空的块。例如:

声明继续sqlwarning开始结束处理程序;

一块标签的范围不包括块内声明的处理代码。因此,一个处理程序无法使用有关的声明ITERATELEAVE参考块,将处理程序声明标签。考虑下面的例子,其中REPEAT块都有一个标签重试

CREATE PROCEDURE p ()
BEGIN
  DECLARE i INT DEFAULT 3;
  retry:
    REPEAT
      BEGIN
        DECLARE CONTINUE HANDLER FOR SQLWARNING
          BEGIN
            ITERATE retry;    # illegal
          END;
        IF i < 0 THEN
          LEAVE retry;        # legal
        END IF;
        SET i = i - 1;
      END;
    UNTIL FALSE END REPEAT;
END;

这个retry标签是在范围之内的IF块内的语句。它不在范围之内的继续处理程序,所以参考有无效和错误的结果:

ERROR 1308 (42000): LEAVE with no matching label: retry

为了避免在处理外部标签的引用,使用这些策略:

  • 离开块,使用EXIT处理程序。如果没有块的清理是必须的,BEGIN ... END处理体可以是空的:

    宣布退出处理程序sqlwarning开始结束;

    否则,把清理报表处理程序体:

    DECLARE EXIT HANDLER FOR SQLWARNING
      BEGIN
        block cleanup statements
      END;
    
  • 继续执行,在一组状态变量CONTINUE处理程序可以检查在封闭块判断处理程序被调用。下面的示例使用变量完成为了这个目的:

    CREATE PROCEDURE p ()
    BEGIN
      DECLARE i INT DEFAULT 3;
      DECLARE done INT DEFAULT FALSE;
      retry:
        REPEAT
          BEGIN
            DECLARE CONTINUE HANDLER FOR SQLWARNING
              BEGIN
                SET done = TRUE;
              END;
            IF done OR i < 0 THEN
              LEAVE retry;
            END IF;
            SET i = i - 1;
          END;
        UNTIL FALSE END REPEAT;
    END;
    

13.6.7.3获得诊断的语法

GET [CURRENT | STACKED] DIAGNOSTICS
{
    statement_information_item
    [, statement_information_item] ...
  | CONDITION condition_number
    condition_information_item
    [, condition_information_item] ...
}

statement_information_item:
    target = statement_information_item_name

condition_information_item:
    target = condition_information_item_name

statement_information_item_name:
    NUMBER
  | ROW_COUNT

condition_information_item_name:
    CLASS_ORIGIN
  | SUBCLASS_ORIGIN
  | RETURNED_SQLSTATE
  | MESSAGE_TEXT
  | MYSQL_ERRNO
  | CONSTRAINT_CATALOG
  | CONSTRAINT_SCHEMA
  | CONSTRAINT_NAME
  | CATALOG_NAME
  | SCHEMA_NAME
  | TABLE_NAME
  | COLUMN_NAME
  | CURSOR_NAME

condition_number, target:
    (see following discussion)

SQL语句产生的诊断信息,诊断区域填充。这个GET DIAGNOSTICS语句使应用程序能够检查此信息。(你也可以用SHOW WARNINGSSHOW ERRORS看情况或错误。)

没有特权的要求执行GET DIAGNOSTICS

关键词CURRENT意味着从目前的诊断区域检索信息。关键词堆叠意味着从第二诊断区域检索信息,这是只有当前的上下文条件处理程序可用。如果没有关键字,默认是使用当前诊断区。

这个GET DIAGNOSTICS语句通常用于处理程序在存储程序。这是一个mysql扩展GET [CURRENT] DIAGNOSTICS是允许在处理上下文检查任何SQL语句的执行。例如,如果你调用MySQL客户端程序,你可以在提示符下输入这些语句:

mysql> DROP TABLE test.no_such_table;
ERROR 1051 (42S02): Unknown table 'test.no_such_table'
mysql> GET DIAGNOSTICS CONDITION 1
    ->   @p1 = RETURNED_SQLSTATE, @p2 = MESSAGE_TEXT;
mysql> SELECT @p1, @p2;
+-------+------------------------------------+
| @p1   | @p2                                |
+-------+------------------------------------+
| 42S02 | Unknown table 'test.no_such_table' |
+-------+------------------------------------+

这个扩展只适用于当前的诊断区。它不适用于第二诊断地区因为GET STACKED DIAGNOSTICS如果仅仅是当前上下文是一个条件处理程序允许。如果不是这样的话,一个得到诊断时不主动处理堆叠错误发生

为说明诊断区,看到第13.6.7.7,“MySQL诊断区”。简而言之,它包含两种信息:

  • 语句的信息,如发生的条件或受影响的行数。

  • 状态信息,如错误代码和错误信息。如果一个语句引发多个条件,这部分的诊断领域的每一个条件的地区。如果一个语句不提出条件,这部分的诊断区域是空的。

一个语句产生的条件,诊断区域包含的语句和条件这样的信息:

Statement information:
  row count
  ... other statement information items ...
Condition area list:
  Condition area 1:
    error code for condition 1
    error message for condition 1
    ... other condition information items ...
  Condition area 2:
    error code for condition 2:
    error message for condition 2
    ... other condition information items ...
  Condition area 3:
    error code for condition 3
    error message for condition 3
    ... other condition information items ...

GET DIAGNOSTICS可以获得任何声明或状态信息,但不在同一个声明:

  • 获取报表信息,检索所需的报表项目为目标变量。这一实例GET DIAGNOSTICS分配可用的条件和受影响的行数的用户变量的数目@ P1@p2

    GET DIAGNOSTICS @p1 = NUMBER, @p2 = ROW_COUNT;
  • 获取状态信息,指定条件数和检索所需的条件项目为目标变量。这一实例GET DIAGNOSTICS将SQLSTATE值和错误信息给用户变量@ P3@p4

    GET DIAGNOSTICS CONDITION 1  @p3 = RETURNED_SQLSTATE, @p4 = MESSAGE_TEXT;

检索列表中指定一个或多个target = item_name作业,以逗号分隔。每个分配一个目标变量和一个名字statement_information_item_namecondition_information_item_name指示器,取决于语句检索语句或条件信息。

有效target用于存储项目信息指示器可以存储过程或函数的参数,程序存储局部变量声明DECLARE,或用户定义的变量

有效condition_number指示器可以存储过程或函数的参数,程序存储局部变量声明DECLARE,用户定义的变量,系统变量,或文字。一个字符可以包括_charset介绍人。如果条件数不在范围从1到条件地区有信息数出现的警告。在这种情况下,警告添加到诊断区域没有清理它。

当一个情况发生时,MySQL不填充所有条件项目的认可GET DIAGNOSTICS。。。。。。。例如:

MySQL的&#62;GET DIAGNOSTICS CONDITION 1-&#62;@p5 = SCHEMA_NAME, @p6 = TABLE_NAME;MySQL的&#62;SELECT @p5, @p6;??????@ @ | | P5 P6 |????????????| | |

在标准的SQL,如果有多个条件,第一个条件涉及的SQLSTATE返回值为以前的SQL语句。在MySQL,这是没有保证的。得到的主要错误,你不能这样做:

GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO;

相反,检索条件数第一,然后使用它指定的检验条件数:

GET DIAGNOSTICS @cno = NUMBER;
GET DIAGNOSTICS CONDITION @cno @errno = MYSQL_ERRNO;

关于允许的语句和条件信息项的信息,哪些是居住在条件发生时,看到第13.6.7.7.2,“诊断区信息项”

这里有一个例子,使用GET DIAGNOSTICS在存储过程中进行插入操作的结果异常处理程序。如果插入成功,程序使用GET DIAGNOSTICS获取受影响的行数。这表明,你可以使用GET DIAGNOSTICS多次检索有关声明,只要当前诊断领域没有明确的信息。

CREATE PROCEDURE do_insert(value INT)BEGIN  -- Declare variables to hold diagnostics area information  DECLARE code CHAR(5) DEFAULT '00000';  DECLARE msg TEXT;  DECLARE rows INT;  DECLARE result TEXT;  -- Declare exception handler for failed insert  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION    BEGIN      GET DIAGNOSTICS CONDITION 1        code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;    END;  -- Perform the insert  INSERT INTO t1 (int_col) VALUES(value);  -- Check whether the insert was successful  IF code = '00000' THEN    GET DIAGNOSTICS rows = ROW_COUNT;    SET result = CONCAT('insert succeeded, row count = ',rows);  ELSE    SET result = CONCAT('insert failed, error = ',code,', message = ',msg);  END IF;  -- Say what happened  SELECT result;END;

假设t1.int_col是一个整数列声明为不为空。该程序产生的结果时,调用插入非—NULL无效的值,分别:

mysql> CALL do_insert(1);
+---------------------------------+
| result                          |
+---------------------------------+
| insert succeeded, row count = 1 |
+---------------------------------+

mysql> CALL do_insert(NULL);
+-------------------------------------------------------------------------+
| result                                                                  |
+-------------------------------------------------------------------------+
| insert failed, error = 23000, message = Column 'int_col' cannot be null |
+-------------------------------------------------------------------------+

当一个条件处理后,推到堆栈发生诊断区:

  • 第一个(目前的)诊断领域成为第二(堆叠)诊断区和新诊断的地区是它的一个副本。

  • GET [CURRENT] DIAGNOSTICSGET STACKED DIAGNOSTICS可以在处理程序用来访问当前和堆叠的诊断方面的内容。

  • 最初,诊断区返回相同的结果,因此有可能从目前的诊断条件,激活区的处理得到的信息,只要你执行没有语句内的处理程序,改变当前的诊断区。

  • 然而,语句的执行在处理程序可以修改当前的诊断领域,结算和按正常规则设置的内容(见第13.6.7.7.3,“如何诊断区域填充”

    获取有关处理激活状态信息的一个更可靠的方法是使用堆叠的诊断领域,不能用在处理程序除了修改语句的执行RESIGNAL。关于在当前诊断区域设置和清除,看第13.6.7.7,“MySQL诊断区”

下面的例子显示了如何GET STACKED DIAGNOSTICS可以在处理程序用于获得有关异常处理的信息,甚至在目前的诊断方面已处理报表的修改。

在一个存储过程p(),我们尝试将两值插入表中文字不空专栏第一个值是一个非—NULL字符串和第二无效的。列禁止NULL值,所以首先插入成功但二导致异常。该程序包括异常处理程序映射试图插入无效的为空字符串插入:

DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 TEXT NOT NULL);
DROP PROCEDURE IF EXISTS p;
delimiter //
CREATE PROCEDURE p ()
BEGIN
  -- Declare variables to hold diagnostics area information
  DECLARE errcount INT;
  DECLARE errno INT;
  DECLARE msg TEXT;
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    -- Here the current DA is nonempty because no prior statements
    -- executing within the handler have cleared it
    GET CURRENT DIAGNOSTICS CONDITION 1
      errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
    SELECT 'current DA before mapped insert' AS op, errno, msg;
    GET STACKED DIAGNOSTICS CONDITION 1
      errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
    SELECT 'stacked DA before mapped insert' AS op, errno, msg;

    -- Map attempted NULL insert to empty string insert
    INSERT INTO t1 (c1) VALUES('');

    -- Here the current DA should be empty (if the INSERT succeeded),
    -- so check whether there are conditions before attempting to
    -- obtain condition information
    GET CURRENT DIAGNOSTICS errcount = NUMBER;
    IF errcount = 0
    THEN
      SELECT 'mapped insert succeeded, current DA is empty' AS op;
    ELSE
      GET CURRENT DIAGNOSTICS CONDITION 1
        errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
      SELECT 'current DA after mapped insert' AS op, errno, msg;
    END IF ;
    GET STACKED DIAGNOSTICS CONDITION 1
      errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;
    SELECT 'stacked DA after mapped insert' AS op, errno, msg;
  END;
  INSERT INTO t1 (c1) VALUES('string 1');
  INSERT INTO t1 (c1) VALUES(NULL);
END;
//
delimiter ;
CALL p();
SELECT * FROM t1;

当处理程序启动,一份当前诊断区推到诊断区叠加。处理程序首先显示当前和堆叠的诊断方面的内容,既有相同的开始:

+---------------------------------+-------+----------------------------+
| op                              | errno | msg                        |
+---------------------------------+-------+----------------------------+
| current DA before mapped insert |  1048 | Column 'c1' cannot be null |
+---------------------------------+-------+----------------------------+

+---------------------------------+-------+----------------------------+
| op                              | errno | msg                        |
+---------------------------------+-------+----------------------------+
| stacked DA before mapped insert |  1048 | Column 'c1' cannot be null |
+---------------------------------+-------+----------------------------+

语句执行后GET DIAGNOSTICS语句可以重置当前诊断区。语句可以重置当前诊断区。例如,该处理程序映射无效的插入一个空字符串插入和显示结果。新插入成功,清除当前诊断等领域,但叠诊断面积不变的情况下,仍有活性的处理信息:

+----------------------------------------------+
| op                                           |
+----------------------------------------------+
| mapped insert succeeded, current DA is empty |
+----------------------------------------------+

+--------------------------------+-------+----------------------------+
| op                             | errno | msg                        |
+--------------------------------+-------+----------------------------+
| stacked DA after mapped insert |  1048 | Column 'c1' cannot be null |
+--------------------------------+-------+----------------------------+

当条件处理程序结束,目前的诊断是从堆栈中弹出并堆放在存储过程中诊断区成为目前诊断区。

手术后的回报,该表包含两行。空排结果从尝试插入NULL这是映射到一个空的字符串插入:

---------- | C1 | ---------- |字串1 | | | ----------

在前面的示例中,第一个GET DIAGNOSTICS语句内的条件处理,检索信息从当前和堆叠的诊断领域返回相同的值。这不会发生如果语句重置当前诊断地区执行此前在处理程序。假设p()被改写的地方DECLARE在处理程序定义语句而不是它之前:

CREATE PROCEDURE p ()BEGIN  DECLARE EXIT HANDLER FOR SQLEXCEPTION  BEGIN    -- Declare variables to hold diagnostics area information    DECLARE errcount INT;    DECLARE errno INT;    DECLARE msg TEXT;    GET CURRENT DIAGNOSTICS CONDITION 1      errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;    SELECT 'current DA before mapped insert' AS op, errno, msg;    GET STACKED DIAGNOSTICS CONDITION 1      errno = MYSQL_ERRNO, msg = MESSAGE_TEXT;    SELECT 'stacked DA before mapped insert' AS op, errno, msg;...

在这种情况下,结果是依赖版本:

  • 在MySQL 5.7.2,DECLARE不改变目前的诊断领域,所以前两GET DIAGNOSTICS语句返回相同的结果,只是在原来的版本p()

    在MySQL 5.7.2,所做的工作是确保所有的非诊断性陈述在诊断领域,每个SQL标准。DECLARE就是其中之一,所以在5.7.2高,DECLARE语句执行的处理程序开始清除当前诊断区和GET DIAGNOSTICS报表产生不同的结果:

    --------------------------------- ------- ------ | OP | errno |味精| --------------------------------- ------- ------ |电流大之前插入空|空|映射| --------------------------------- ------- ------ --------------------------------- ------- ---------------------------- | OP | errno |味精| --------------------------------- ------- ---------------------------- |堆叠的大前插入1048 |映射|列“C1”不能为空| --------------------------------- ------- ----------------------------

为了避免这个问题,在一个条件处理程序时,寻求获得有关条件,激活处理程序的信息,请访问叠诊断区,不是当前的诊断区。

13.6.7.4区域语法

RESIGNAL [condition_value]
    [SET signal_information_item
    [, signal_information_item] ...]

condition_value:
    SQLSTATE [VALUE] sqlstate_value
  | condition_name

signal_information_item:
    condition_information_item_name = simple_value_specification

condition_information_item_name:
    CLASS_ORIGIN
  | SUBCLASS_ORIGIN
  | MESSAGE_TEXT
  | MYSQL_ERRNO
  | CONSTRAINT_CATALOG
  | CONSTRAINT_SCHEMA
  | CONSTRAINT_NAME
  | CATALOG_NAME
  | SCHEMA_NAME
  | TABLE_NAME
  | COLUMN_NAME
  | CURSOR_NAME

condition_name, simple_value_specification:
    (see following discussion)

RESIGNAL通过对所内的一个存储过程或函数,复合语句的执行条件处理程序触发在可用的错误状态信息,或事件。RESIGNAL可能会改变一些或所有之前将它传递信息。RESIGNAL有关SIGNAL,而是起源于一个条件SIGNAL做,RESIGNAL继电器存在的状态信息,可能在修改它。

RESIGNAL能够同时处理错误并返回错误信息。否则,通过执行SQL语句的处理程序,导致程序的激活信息被破坏。RESIGNAL也可以做一些程序更短的如果一个给定的处理器可以处理的情况,然后通过条件上线另一个处理程序

没有特权的要求执行的RESIGNAL声明

所有形式的RESIGNAL要求当前上下文是一个条件处理。否则,RESIGNAL是非法的,当处理不活跃区域错误发生

从诊断区域检索信息,使用GET DIAGNOSTICS声明(见第13.6.7.3,“诊断学语法”)。关于诊断方面的信息,看第13.6.7.7,“MySQL诊断区”

condition_valuesignal_information_item,定义和规则是相同的RESIGNAL至于SIGNAL。例如,在condition_value可以是一个SQLSTATE价值和价值可以显示错误、警告或没有找到更多信息,参见第13.6.7.5,“信号语法”

这个RESIGNAL声明以condition_value配置的条款,都是可选的。这导致了几种可能的用途:

  • RESIGNAL独自一人:

    区域;
  • RESIGNAL《信号与信息:

    区域设置signal_information_item【,signal_information_item]…;
  • RESIGNAL有条件的价值和可能的新的信号信息:

    区域condition_value配置signal_information_item【,signal_information_item]…];

这些用例都会改变的诊断条件的地区:

  • 一个诊断区包含一个或多个条件的地区。

  • 有条件的地区包含状态信息的项目,如SQLSTATE价值,mysql errno _,或MESSAGE_TEXT

有一堆诊断领域。当一个处理器控制,它推动了一个诊断区到堆栈的顶部,所以有两个诊断领域中处理程序执行:

  • 第一个(目前的)诊断领域,开始一份最后的诊断,但会通过改变现行的诊断领域的处理程序的第一个语句被覆盖。

  • 最后(堆叠)诊断区,有条件的地区,建立了前处理程序控制。

在诊断区条件的地区的最大数量是由价值决定的max_error_count系统变量。见第13.6.7.7.5,“诊断区域相关的系统变量”

13.6.7.4.1区域单独

一个简单的RESIGNAL孤独意味着通过对误差没有变化它恢复的最后诊断区,使得目前诊断区。那是,它持久性有机污染物诊断区的栈

在一个条件处理程序捕获的条件,运用的一个RESIGNAL孤独是执行一些其他的动作,然后把没有改变原来的状态信息(进入处理程序之前存在的信息)。

例子:

DROP TABLE IF EXISTS xx;
delimiter //
CREATE PROCEDURE p ()
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    SET @error_count = @error_count + 1;
    IF @a = 0 THEN RESIGNAL; END IF;
  END;
  DROP TABLE xx;
END//
delimiter ;
SET @error_count = 0;
SET @a = 0;
CALL p();

假设DROP TABLE xx语句失败。诊断区的堆栈看起来像这样:

Da 1 .错误:未知(1051 42s02表“XX”)

然后执行进入EXIT处理程序。它开始通过推动诊断区到堆栈的顶部,它现在看起来像这样:

Da 1 .错误1051(442):UNknown Table &#39; XX &#39; da 2。错误1051(442):

在这一点上,第一次的内容(电流)和第二(堆叠)诊断方面是相同的。第一诊断的地区可以通过报表执行随后在处理程序修改。

通常一个程序语句清除第一诊断区。BEGIN是一个例外,它不清楚,它没有。配置也不例外,它清除,执行操作,并产生一个结果成功诊断区的堆栈现在看起来像这样:

DA 1. ERROR 0000 (00000): Successful operation
DA 2. ERROR 1051 (42S02): Unknown table 'xx'

在这一点上,如果@a = 0RESIGNALPOPs诊断区的堆栈,它现在看起来像这样:

Da 1 .错误:未知(1051 42s02表“XX”)

这是什么人看到

如果@a不是0,处理简单的结束,这意味着目前诊断地区不再使用(已处理),所以它可以扔掉,造成叠诊断区域再次成为当前诊断区。诊断区的堆栈看起来像这样:

DA 1. ERROR 0000 (00000): Successful operation

细节使它看起来复杂,但最终的结果是非常有用的:处理程序可以不破坏,造成处理激活状态信息执行。

13.6.7.4.2区域新的信号信息

RESIGNAL用一个配置条款提供了新的信息,那么意味着通过对误差的变化

RESIGNAL SET signal_information_item [, signal_information_item] ...;

RESIGNAL独自一人,这个想法是流行的诊断区叠加使原有的信息将出去。不像RESIGNAL一个人,在任何指定的配置条款的变化

例子:

DROP TABLE IF EXISTS xx;
delimiter //
CREATE PROCEDURE p ()
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    SET @error_count = @error_count + 1;
    IF @a = 0 THEN RESIGNAL SET MYSQL_ERRNO = 5; END IF;
  END;
  DROP TABLE xx;
END//
delimiter ;
SET @error_count = 0;
SET @a = 0;
CALL p();

还记得以前的讨论RESIGNAL结果在诊断区栈这样:

Da 1 .错误:未知(1051 42s02表“XX”)

这个RESIGNAL SET MYSQL_ERRNO = 5这堆中语句的结果相反,这是什么人看到:

1。错误:未知(5 42s02表“XX”)

换句话说,它改变了错误的号码,别的什么都没有。

这个RESIGNAL语句可以改变任何或所有的信号信息,使诊断区的第一条件的地区看起来很不同。

13.6.7.4.3区域与条件值和可选的新的信号信息

RESIGNAL有条件的价值按条件到目前的诊断区。如果SET子句,也改变了错误信息。

区域condition_value配置signal_information_item【,signal_information_item]…];

这种形式的RESIGNAL还原上次诊断区域,使得目前的诊断区。那是,它持久性有机污染物诊断区的堆栈,这是多么简单的一RESIGNAL一个人会做的。然而,它也改变了诊断区根据条件值或信号信息。

例子:

DROP TABLE IF EXISTS xx;
delimiter //
CREATE PROCEDURE p ()
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    SET @error_count = @error_count + 1;
    IF @a = 0 THEN RESIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=5; END IF;
  END;
  DROP TABLE xx;
END//
delimiter ;
SET @error_count = 0;
SET @a = 0;
SET @@max_error_count = 2;
CALL p();
SHOW ERRORS;

这是类似于前面的例子,和的作用是一样的,但如果RESIGNAL发生,当前条件的地区最后看起来不同。(条件补充而不是取代现有条件的原因是一个条件值。使用)

这个RESIGNAL包括在表值(weather conditionSQLSTATE的45000的),所以它增加了一个新的条件,导致诊断区堆栈看起来像这样:

DA 1. (condition 2) ERROR 1051 (42S02): Unknown table 'xx'
      (condition 1) ERROR 5 (45000) Unknown table 'xx'

结果CALL p()SHOW ERRORS在这个例子中是:

MySQL的&#62;CALL p();错误5(45000):未知的表xx&#39;mysql &#62;SHOW ERRORS;------- ------ ---------------------------------- |水平|代码|消息| ------- ------ ---------------------------------- |误差| 1051 |未知表&#39;XX&#39; | |误差| 5 |未知表&#39;XX&#39; | ------- ------ ----------------------------------
13.6.7.4.4区域要求条件处理上下文

所有形式的RESIGNAL要求当前上下文是一个条件处理。否则,RESIGNAL是非法的,当处理不活跃区域错误发生。例如:

mysql> CREATE PROCEDURE p () RESIGNAL;
Query OK, 0 rows affected (0.00 sec)

mysql> CALL p();
ERROR 1645 (0K000): RESIGNAL when handler not active

这里是一个更难的例子:

delimiter //
CREATE FUNCTION f () RETURNS INT
BEGIN
  RESIGNAL;
  RETURN 5;
END//
CREATE PROCEDURE p ()
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @a=f();
  SIGNAL SQLSTATE '55555';
END//
delimiter ;
CALL p();

RESIGNAL发生在存储功能f()。虽然f()本身是调用的上下文内出口处理程序,在执行f()有自己的背景,这是不处理上下文。因此,区域在内部f()结果在一个处理不积极误差

13.6.7.5信号语法

SIGNAL condition_value
    [SET signal_information_item
    [, signal_information_item] ...]

condition_value:
    SQLSTATE [VALUE] sqlstate_value
  | condition_name

signal_information_item:
    condition_information_item_name = simple_value_specification

condition_information_item_name:
    CLASS_ORIGIN
  | SUBCLASS_ORIGIN
  | MESSAGE_TEXT
  | MYSQL_ERRNO
  | CONSTRAINT_CATALOG
  | CONSTRAINT_SCHEMA
  | CONSTRAINT_NAME
  | CATALOG_NAME
  | SCHEMA_NAME
  | TABLE_NAME
  | COLUMN_NAME
  | CURSOR_NAME

condition_name, simple_value_specification:
    (see following discussion)

SIGNAL是的方式退货一个错误SIGNAL一个处理程序提供了错误的信息,为应用程序的外部部分,或对客户。同时,它提供了对误差的特性控制(错误数,SQLSTATE值,message)。没有SIGNAL,有必要采取变通方法,如故意指的是一个不存在的表使程序返回一个错误。

没有特权的要求执行的SIGNAL声明

从诊断区域检索信息,使用GET DIAGNOSTICS声明(见第13.6.7.3,“诊断学语法”)。关于诊断方面的信息,看第13.6.7.7,“MySQL诊断区”

这个condition_value在一个SIGNAL声明表示要返回的错误值。它可以是一个SQLSTATE价值(5个字符的字符串)或condition_name这是一个命名的条件已定义DECLARE ... CONDITION(见第13.6.7.1,”声明…条件语法”

一个SQLSTATE值可以显示错误、警告或没有找到该值的第一个字符显示其错误类,讨论第13.6.7.5.1,“信号状态信息项”。一些信号值导致语句终止;看第13.6.7.5.2,“信号处理效果的游标,并声明”

这个SQLSTATE值的一SIGNAL声明不应该开始“00”因为这些值表示成功而不是信号错误是有效的。这是否是真的SQLSTATE价值是直接指定SIGNAL声明或在一个指定的条件中提到的声明。如果该值是无效的,一坏的SQLSTATE错误发生

信号一般SQLSTATE值,使用“45000”,这意味着未经处理的用户自定义异常。

这个SIGNAL声明中包括一个可选的配置子句包含多个信号的项目,在一个逗号分隔的列表condition_information_item_name=simple_value_specification作业.

每个condition_information_item_name也许只有一次在指定的配置ClauseOtherwise,aDuplicate condition information item错误发生

有效simple_value_specification指示器可以使用存储过程或函数的参数指定,程序存储局部变量声明DECLARE,用户定义的变量,系统变量,或文字。一个字符可以包括_charset介绍人

关于允许的condition_information_item_name值,见第13.6.7.5.1,“信号状态信息项”

下面的过程信号错误或警告取决于价值pval,其输入参数:

CREATE PROCEDURE p (pval INT)BEGIN  DECLARE specialty CONDITION FOR SQLSTATE '45000';  IF pval = 0 THEN    SIGNAL SQLSTATE '01000';  ELSEIF pval = 1 THEN    SIGNAL SQLSTATE '45000'      SET MESSAGE_TEXT = 'An error occurred';  ELSEIF pval = 2 THEN    SIGNAL specialty      SET MESSAGE_TEXT = 'An error occurred';  ELSE    SIGNAL SQLSTATE '01000'      SET MESSAGE_TEXT = 'A warning occurred', MYSQL_ERRNO = 1000;    SIGNAL SQLSTATE '45000'      SET MESSAGE_TEXT = 'An error occurred', MYSQL_ERRNO = 1001;  END IF;END;

如果pval0,p()因为一个警告信号SQLSTATE值开始“01”信号在警告类。警告不终止程序,可以看到SHOW WARNINGS手术后返回

如果pval1,p()信号的误差和集MESSAGE_TEXT环境信息项目。错误终止程序,并返回错误信息文本。

如果pval2、同样的错误信号,虽然SQLSTATE价值是使用命名在这种情况下,指定的条件。

如果pval是什么,p()第一信号警告,设置消息文本和错误数条件的项目信息。这一警告不终止程序,所以继续执行,p()然后信号错误。错误并终止程序。消息文本和错误号的警告是由错误的价值观所取代,这是返回的错误信息。

SIGNAL通常在存储程序中使用,但它是一个MySQL的扩展,它允许外部程序上下文。例如,如果你调用MySQL客户端程序,你可以输入任何这些语句在提示:

mysql> SIGNAL SQLSTATE '77777';
mysql> CREATE TRIGGER t_bi BEFORE INSERT ON t
    -> FOR EACH ROW SIGNAL SQLSTATE '77777';
mysql> CREATE EVENT e ON SCHEDULE EVERY 1 SECOND
    -> DO SIGNAL SQLSTATE '77777';

SIGNAL按下列规定执行:

如果SIGNAL示意图SQLSTATE价值,价值是用来指定信号的条件。例子:

CREATE PROCEDURE p (divisor INT)
BEGIN
  IF divisor = 0 THEN
    SIGNAL SQLSTATE '22012';
  END IF;
END;

如果SIGNAL语句中使用命名的条件,条件必须在一定范围内宣布,适用于SIGNAL声明,必须定义使用SQLSTATEMySQL错误数的值,而不是。例子:

CREATE PROCEDURE p (divisor INT)
BEGIN
  DECLARE divide_by_zero CONDITION FOR SQLSTATE '22012';
  IF divisor = 0 THEN
    SIGNAL divide_by_zero;
  END IF;
END;

如果指定的条件不存在的范围SIGNAL声明一个未定义的条件错误发生

如果SIGNAL指的是一个命名的条件,是与一个MySQL错误数而不是一个定义SQLSTATE价值,一个SIGNAL/RESIGNAL can only use a CONDITION defined with SQLSTATE错误发生。以下语句导致错误因为命名的条件是一个MySQL错误数有关:

no_such_table申报条件1051;信号no_such_table;

如果一个具有给定名称的条件是在不同的范围声明多次,与大多数地方的声明适用范围。考虑下面的程序:

CREATE PROCEDURE p (divisor INT)
BEGIN
  DECLARE my_error CONDITION FOR SQLSTATE '45000';
  IF divisor = 0 THEN
    BEGIN
      DECLARE my_error CONDITION FOR SQLSTATE '22012';
      SIGNAL my_error;
    END;
  END IF;
  SIGNAL my_error;
END;

如果divisor0、第一SIGNALexecutes statement。innermost the我的错误条件声明适用,提高SQLSTATE“22012”

如果divisor不是0,第二SIGNAL执行任务。最糟糕的我的错误条件声明适用,提高SQLSTATE“45000”

关于服务器如何选择处理信息时的情况,看第13.6.7.6,“范围规则处理”

信号可以在异常处理程序提出:

CREATE PROCEDURE p ()
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION
  BEGIN
    SIGNAL SQLSTATE VALUE '99999'
      SET MESSAGE_TEXT = 'An error occurred';
  END;
  DROP TABLE no_such_table;
END;

CALL p()到达DROP TABLE声明。没有表命名no_such_table错误处理程序被激活,所以。错误处理程序破坏了原来的错误(没有这样的表)和进行新的误差SQLSTATE“99999”和消息An error occurred

13.6.7.5.1信号状态信息

下表列出了诊断区域条件信息项目,可以设置在一个名字SIGNAL(或RESIGNAL)声明。所有的项目都是标准的SQL除了mysql errno _这是一个mysql扩展。关于这些项目的更多信息见第13.6.7.7,“MySQL诊断区”

Item Name             Definition
---------             ----------
CLASS_ORIGIN          VARCHAR(64)
SUBCLASS_ORIGIN       VARCHAR(64)
CONSTRAINT_CATALOG    VARCHAR(64)
CONSTRAINT_SCHEMA     VARCHAR(64)
CONSTRAINT_NAME       VARCHAR(64)
CATALOG_NAME          VARCHAR(64)
SCHEMA_NAME           VARCHAR(64)
TABLE_NAME            VARCHAR(64)
COLUMN_NAME           VARCHAR(64)
CURSOR_NAME           VARCHAR(64)
MESSAGE_TEXT          VARCHAR(128)
MYSQL_ERRNO           SMALLINT UNSIGNED

设置项目的特点是gb3212字符。

它是非法转让NULL一种信息项在SIGNAL声明

SIGNAL语句总是指定一个SQLSTATE价值,直接或间接通过一个命名的条件定义的SQLSTATE价值。一个第一个字符SQLSTATE价值是其阶级和阶级决定的条件信息项的默认值:

  • Class ='00'(成功)

    非法SQLSTATE值开始“00”表明成功和无效SIGNAL

  • Class ='01'(警告)

    MESSAGE_TEXT = 'Unhandled user-defined warning condition';MYSQL_ERRNO =ER_SIGNAL_WARN
  • Class ='02'(未找到)

    MESSAGE_TEXT = 'Unhandled user-defined not found condition';MYSQL_ERRNO =ER_SIGNAL_NOT_FOUND
  • '02'(例外)

    MESSAGE_TEXT = 'Unhandled user-defined exception condition';MYSQL_ERRNO =ER_SIGNAL_EXCEPTION

法律类、其他条件的项目信息如下:

CLASS_ORIGIN = SUBCLASS_ORIGIN = '';
CONSTRAINT_CATALOG = CONSTRAINT_SCHEMA = CONSTRAINT_NAME = '';
CATALOG_NAME = SCHEMA_NAME = TABLE_NAME = COLUMN_NAME = '';
CURSOR_NAME = '';

误差值后,可SIGNAL执行是SQLSTATE值的提出的SIGNAL声明和_文字消息MYSQL_ERRNO项目这些值可从C API:

从SQL,从输出SHOW WARNINGSSHOW ERRORS表明mysql errno _MESSAGE_TEXT中的值代码Message专栏

从诊断区域检索信息,使用GET DIAGNOSTICS声明(见第13.6.7.3,“诊断学语法”)。关于诊断方面的信息,看第13.6.7.7,“MySQL诊断区”

信号处理程序,13.6.7.5.2影响游标,并陈述

信号语句的执行依赖于信号的类的不同影响。这类决定如何严重的错误。MySQL忽略的价值sql_mode系统变量;特别是,严格的SQL模式并不重要。MySQL也忽视了忽略:the intent ofSIGNAL是提高用户产生的误差信号明确,所以不能忽视。

在他们的描述中未经处理的意味着没有处理的信号SQLSTATE价值被定义DECLARE ... HANDLER

  • Class ='00'(成功)

    非法SQLSTATE值开始“00”表明成功和无效SIGNAL

  • Class ='01'(警告)

    的价值warning_count系统变量上SHOW WARNINGS显示信号sqlwarning处理程序捕获信号。如果信号在一个函数处理,报表不结束。

  • Class ='02'(未找到)

    NOT FOUND处理程序捕获信号。在游标没有影响。如果信号在一个函数处理,语句结束。

  • '02'(例外)

    SQLEXCEPTION处理程序捕获信号。如果信号在一个函数处理,语句结束。

  • Class ='40'

    作为一个普通的例外

例子:

mysql> delimiter //
mysql> CREATE FUNCTION f () RETURNS INT
    -> BEGIN
    ->   SIGNAL SQLSTATE '01234';  -- signal a warning
    ->   RETURN 5;
    -> END//
mysql> delimiter ;
mysql> CREATE TABLE t (s1 INT);
mysql> INSERT INTO t VALUES (f());

结果是,一行5插入表t。警告信号可以被视为与SHOW WARNINGS

13.6.7.6范围规则的处理程序

一个存储程序可能包括处理程序被调用时,一定条件下发生在程序。每个处理程序的适用性取决于它的位置在程序的定义和对其处理情况:

  • Handler declared in aBEGIN ... END块范围只在块处理程序声明的SQL语句。如果处理器本身提出了一个条件,它不能处理的情况,也没有任何其他处理程序声明块中。在下面的示例中,处理程序H1H2在提出的条件范围的陈述stmt1stmt2。但无论H1也没有H2在范围为体内提出的条件H1H2

    开始——外块宣布退出处理程序…;——处理H1宣布退出处理程序;--处理H2…stmt1stmt2;结束;
  • 处理范围仅为定义它的块,不能是发生在那块条件激活。在下面的示例中,处理程序H1在范围stmt1块内,但不stmt2在外块:

    开始-开始-外挡块内声明退出处理程序;--处理H1…stmt1;结束;stmt2;结束;
  • 一个处理器可以是一个特定的或一般的。一个特定的处理程序是一个MySQL错误代码,SQLSTATE价值,或条件名称。一般的程序是在一个条件sqlwarningSQLEXCEPTION,或没有找到类条件的特异性是条件优先关系,为后面介绍。

多个处理程序可以在不同的范围和不同的特异性声明。例如,可能有一个特定的MySQL错误代码处理程序在外块,和一般的SQLWARNING在一个模块的内部处理程序。或者可能有一个特定的MySQL错误代码处理和一般sqlwarning在同一块类

无论是处理活性不仅取决于自身的条件和范围值,但在其他处理器是什么礼物。在存储程序发生的条件时,在当前范围内适用的处理程序服务器搜索(电流BEGIN ... END块)。如果没有适用的处理程序,搜索继续向外与处理在每个连续的包含范围(块)。当服务器发现一个或多个应用程序在一个给定的范围,选取其中基于条件优先:

  • 一个MySQL错误代码处理优先于一SQLSTATE值的处理

  • 一个SQLSTATE价值优先于一般处理程序sqlwarningSQLEXCEPTION,或没有找到处理程序

  • 一个SQLEXCEPTION处理优先于一sqlwarning处理程序

  • 这是可能具有相同的优先级,具有多种应用程序。例如,一个语句可以产生不同的错误代码的多个警告,其中的每一个特定的错误处理程序存在。在这种情况下,选择哪种处理器的服务器激活是不确定的,可以根据不同情况下的条件发生变化。

该处理器的选择规则的一个含义是,如果多个应用程序出现在不同的范围,与大多数地方范围处理优先于外部作用域的处理,即使在那些更具体的条件。

如果没有适当的处理,当情况发生时,采取的行动取决于条件的类:

  • SQLEXCEPTION存储程序的终止条件,在提出的条件语句,如果有出口处理程序。如果程序被另一个存储程序,调用程序处理的情况下使用处理器的选择规则应用到自己的程序。

  • SQLWARNING条件,程序继续执行,好像有一个继续处理程序

  • NOT FOUND的条件,如果条件为正常饲养,动作继续。如果它被SIGNALRESIGNAL,动作出口

下面的示例演示如何将处理MySQL选择规则。

这个过程包含两个处理器,一个特定的SQLSTATE(value42s02’。”)发生的试图删除一个不存在的表,和一个一般的SQLEXCEPTION

创建程序p1()开始宣布继续为SQLSTATE”42s02 &#39;选择&#39;激活&#39; SQLSTATE处理处理味精;宣布继续不选择“不处理处理程序被激活的味精;表t;结束测试;

两处理在同一块声明具有相同的范围。然而,SQLSTATE操作者优先SQLException处理,所以如果表t不存在的DROP TABLE声明提出了一个条件,激活SQLSTATE汉德勒:

mysql> CALL p1();
+--------------------------------+
| msg                            |
+--------------------------------+
| SQLSTATE handler was activated |
+--------------------------------+

这个过程包含两个相同的处理程序。但这一次,这DROP TABLE声明和SQLException处理程序内块相对于SQLSTATE汉德勒:

创建程序p2()开始——外块宣布继续为SQLSTATE”42s02 &#39;选择&#39;激活&#39; SQLSTATE处理处理味精;开始——块内声明继续不选择“不处理处理程序被激活的味精;跌落台试验。T;--发生在块内端;端;

在这种情况下,处理器,更多的是当地的地方发生优先条件。这个SQLEXCEPTION处理程序被激活,即使它是更一般比SQLSTATE汉德勒:

mysql> CALL p2();
+------------------------------------+
| msg                                |
+------------------------------------+
| SQLEXCEPTION handler was activated |
+------------------------------------+

在这一过程中,一个处理器是一个街区的范围内宣布DROP TABLE声明:

创建程序p3()开始——外块宣布继续不选择“不处理处理程序被激活的味精;开始——块内声明继续SQLSTATE”42s02 &#39;选择&#39;激活&#39; SQLSTATE处理处理味精;结束;跌落台试验。T;--发生在外blockend;

只有SQLEXCEPTION处理程序将因为另一个不在范围之内提出的条件DROP TABLE

MySQL的&#62;CALL p3();------------------------------------ |味精| ------------------------------------ | SQLException处理程序被激活| ------------------------------------

在这一过程中,无论是处理在一个块内的范围声明DROP TABLE声明:

创建程序p4()开始--开始--外块内块宣布继续不选择“不处理处理程序被激活的味精;宣布继续为SQLSTATE”42s02 &#39;选择&#39;激活&#39; SQLSTATE处理处理味精;结束;跌落台试验。T;--发生在外blockend;

不是因为他们不处理适用范围为DROP TABLE。通过声明未处理的和一个错误的程序终止的条件了:

MySQL的&#62;CALL p4();错误1051(未知42s02):表“测试。”

13.6.7.7 MySQL诊断区

SQL语句产生的诊断信息,诊断区域填充。标准SQL有诊断区堆栈,包含每一个嵌套的执行上下文诊断区。标准的SQL也支持GET STACKED DIAGNOSTICS参照第二诊断区域条件处理程序执行期间的语法。MySQL支持堆叠因为MySQL 5.7关键词。

本节介绍了在MySQL诊断区的结构,信息项被MySQL,如何陈述明确诊断领域,以及如何诊断领域推到和从堆栈中弹出。

13.6.7.7.1诊断区域结构

诊断区域包含两种信息:

  • 语句的信息,如发生的条件或受影响的行数。

  • 状态信息,如错误代码和错误信息。如果一个语句引发多个条件,这部分的诊断领域的每一个条件的地区。如果一个语句不提出条件,这部分的诊断区域是空的。

一个语句产生的三个条件,诊断区域包含的语句和条件这样的信息:

Statement information:
  row count
  ... other statement information items ...
Condition area list:
  Condition area 1:
    error code for condition 1
    error message for condition 1
    ... other condition information items ...
  Condition area 2:
    error code for condition 2:
    error message for condition 2
    ... other condition information items ...
  Condition area 3:
    error code for condition 3
    error message for condition 3
    ... other condition information items ...
13.6.7.7.2诊断领域的项目信息

诊断区域包含的语句和条件的项目信息。数字项是整数。设置项目的特点是gb3212字符。没有任何物品可以NULL。如果一个语句或条件的项目不是由声明填充诊断区域,其值为0或空字符串,这取决于项目的数据类型。

诊断区的声明信息部分包含这些项目:

诊断区的状态信息部分包含每个条件条件的地区。条件的地区编号从1到的价值NUMBER条件项目的声明。如果是零,没有条件的地区。

每个条件的地区包含以下列表中的项目。所有的项目都是标准的SQL除了MYSQL_ERRNO这是一个mysql扩展。定义申请条件比其他信号产生的(即,由SIGNALRESIGNAL声明)。对于无信号的情况下,MySQL的填充只有那些条件项目不可谓总是空的。信号在条件区域的影响稍后介绍。

  • CLASS_ORIGIN:字符串的类returned_sqlstateValue。if theRETURNED_SQLSTATE价值从一个SQL标准ISO文件9075-2定义的类价值(第1,SQLSTATE),class_origin'ISO 9075'。否则,class_origin'MySQL'

  • SUBCLASS_ORIGIN:一个包含子类的returned_sqlstate价值。如果CLASS_ORIGIN“ISO 9075”RETURNED_SQLSTATE结束&#39;万&#39;SUBCLASS_ORIGIN“ISO 9075”。否则,SUBCLASS_ORIGIN“MySQL”

  • RETURNED_SQLSTATE一个字符串,表示:SQLSTATEvalue for the条件。

  • MESSAGE_TEXT:一个字符串,显示错误信息的情况。

  • MYSQL_ERRNO:一个整数,表示MySQL错误代码为条件。

  • CONSTRAINT_CATALOGconstraint_schemaCONSTRAINT_NAME:字符串,显示目录,图式,对违反约束的名字。他们总是空的。

  • CATALOG_NAME图式_名称TABLE_NAMEcolumn_name:字符串,显示目录,图式,表,和相关的条件列。他们总是空的。

  • CURSOR_NAME:一个字符串,表示该游标名称。这始终是空的。

对于RETURNED_SQLSTATE_文字消息,和MYSQL_ERRNO对于特定的误差值,见第三,“服务器错误代码和消息”

如果一个SIGNAL(或RESIGNAL)语句填充的诊断领域,其配置条款可以指定任何条件的信息项目除外RETURNED_SQLSTATE任何值的项的数据类型是合法的。SIGNAL还设置了returned_sqlstate值,而不是直接在其SET条款.价值来自SIGNAL陈述SQLSTATE争论

SIGNAL还设置报表信息项。它集1。它集ROW_COUNT对?1错误,否则

13.6.7.7.3如何诊断区域填充

不能确诊的SQL语句填充区域的自动诊断,其内容可设定明确的SIGNALRESIGNAL声明.诊断区可以检查GET DIAGNOSTICS提取的具体项目,或SHOW WARNINGSSHOW ERRORS看情况或错误

SQL语句明确诊断范围如下:

  • 当服务器启动时执行语句解析后,明确诊断为非诊断报表区域。诊断报表不明确诊断区(SHOW WARNINGSSHOW ERRORSGET DIAGNOSTICS

  • 如果一个语句出现状况,诊断区的清除,属于先前的条件。,提出的条件是例外GET DIAGNOSTICSRESIGNAL添加到诊断区域没有清理它。

因此,即使一个声明,通常不明确诊断的地区开始执行时清除它,如果声明中提出了一个条件。

下面的示例显示在诊断领域各种报表的影响,采用SHOW WARNINGS显示条件有关的信息存储在。

DROP TABLE声明明确诊断区域和填充它的条件时发生:

MySQL的&#62;DROP TABLE IF EXISTS test.no_such_table;查询行,0行的影响,1报警(0.01秒)MySQL &#62;SHOW WARNINGS;------- ------ ------------------------------------ |水平|代码|消息| ------- ------ ------------------------------------ |注| 1051 |未知表”测试。no_such_table”| ------- ------ ------------------------------------ 1行集(0秒)

SET语句产生一个错误,所以它清理和填充诊断区:

MySQL的&#62;SET @x = @@x;错误1193(hy000):未知的系统变量的x&#39;mysql &#62;SHOW WARNINGS;------- ------ ----------------------------- |水平|代码|消息| ------- ------ ----------------------------- |误差| 1193 |未知系统变量“X”| ------- ------ ----------------------------- 1行集(0秒)

以前的SET语句产生一个单一的条件,所以1是唯一有效的条件数GET DIAGNOSTICS在这一点上。下面的语句使用2条件数,产生一个警告,添加到诊断区域没有清理它:

MySQL的&#62;GET DIAGNOSTICS CONDITION 2 @p = MESSAGE_TEXT;查询行,0行的影响,1报警(0秒)MySQL &#62;SHOW WARNINGS;------- ------ ------------------------------ |水平|代码|消息| ------- ------ ------------------------------ |误差| 1193 |未知系统变量&#39;XX&#39; | |误差| 1753年|无效的条件数| ------- ------ ------------------------------ 2行集(0.001秒)

目前在诊断区的两个条件,所以同GET DIAGNOSTICS语句成功:

MySQL的&#62;GET DIAGNOSTICS CONDITION 2 @p = MESSAGE_TEXT;查询好,为受影响的行(0.001秒)MySQL &#62;SELECT @p;-------------------------- | @ P | -------------------------- |无效的条件数| -------------------------- 1行集(0.01秒)
13.6.7.7.4如何诊断区叠加的作品

当推到诊断区叠加时,第一个(目前的)诊断领域成为第二(堆叠)诊断区和新诊断的地区是它的一个副本。诊断领域推到和从堆栈中弹出下列情况:

  • 一个存储程序执行

    推发生程序执行和流行发生前后。如果存储程序结束处理程序执行时,可以有一个以上的诊断地区流行;这是由于一个例外,没有适当的处理程序或由于RETURN在处理程序

    任何警告或错误情况发生在存储程序执行然后添加到当前的诊断领域,除此之外,触发器,只增加误差。当存储结束,对方看到其目前的diagonstics地区这些条件。

  • 在存储程序的执行条件处理

    当一个推的结果发生的条件处理活化,堆叠的诊断领域是领域是目前在存储程序推前。新的现在目前的诊断领域是处理当前诊断区。GET [CURRENT] DIAGNOSTICSGET STACKED DIAGNOSTICS可以在处理程序用来访问当前的内容(处理)和堆叠(存储程序)诊断领域。最初,他们返回相同的结果,但声明中执行处理程序修改当前诊断区、结算和按正常规则设置的内容(见第13.6.7.7.3,“如何诊断区域填充”)。堆叠的诊断区域不能通过语句的执行处理程序中的除了修饰RESIGNAL

    如果程序执行成功,目前(处理)诊断区爆堆(存储程序)诊断地区再次成为当前诊断区。条件添加到处理程序诊断区在处理被添加到当前的诊断区。

  • 执行RESIGNAL

    这个RESIGNAL声明将是内储存的程序一个复合语句的条件处理程序执行的过程中提供的错误信息。RESIGNAL可能会改变一些或所有之前将它传递信息,修改堆栈中所描述的诊断第13.6.7.4,“区域语法”

13.6.7.7.5诊断区域相关的系统变量

某些系统变量控制或是诊断区的一些方面:

  • max_error_count控制在诊断区域条件区域的数量。如果不是这发生更多的条件,MySQL悄悄地丢弃多余的条件信息。(条件补充RESIGNAL总是说,旧的条件是必要的让房间丢弃。)

  • warning_count说明发生的条件数。这包括错误、警告和注释。通常,warning_count都是一样的。然而,作为条件产生的数量超过max_error_count,价值warning_count继续上升而仍然限制在max_error_count因为没有附加条件存储在诊断区。

  • error_count表明发生的错误数。此值包括没有找到但例外情况,但不包括警告和说明。喜欢warning_count,其价值超过max_error_count

  • 如果sql_notes系统变量设置为0,票据不储存、不增加warning_count

例子:ifmax_error_count十、诊断区域可以包含最多10条件的地区。假设一个声明中提出了20个条件,其中12是错误的。在这种情况下,诊断区域包含前10个条件,十,warning_count20,和error_count是12

价值的变化max_error_count没有影响到修改诊断领域的下一次。如果诊断区域包含10个条件的地区和max_error_count设置为5,这对诊断区域大小或内容没有直接影响。

13.7数据库管理报表

13.7.1账户管理报表

MySQL帐户信息存储在表mysql系统数据库。这个数据库和访问控制系统广泛的讨论5章,MySQL服务器管理,你应该咨询详情

重要

介绍一些MySQL的版本变化的授权表的结构来添加新的权限或特征。确保你可以利用任何新功能,更新你的授权表有电流结构当你升级MySQL。看到4.4.5“,”mysql_upgrade检查升级MySQL表”

read_only系统变量是启用的,账户管理报表的要求CONNECTION_ADMINSUPER特权,除了任何其他所需的特权。这是因为他们在修改表MySQL系统数据库

账户管理报表是原子碰撞安全。有关更多信息,参见第13.1.1,“原子数据定义语句的支持”

13.7.1.1改变用户语法

ALTER USER [IF EXISTS]
    user [auth_option] [, user [auth_option]] ...
    [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]
    [WITH resource_option [resource_option] ...]
    [password_option | lock_option] ...

ALTER USER [IF EXISTS]
    USER() IDENTIFIED BY 'auth_string' [REPLACE 'current_auth_string']

ALTER USER [IF EXISTS]
    user DEFAULT ROLE
    {NONE | ALL | role [, role ] ...}

user:
    (see Section 6.2.4, “Specifying Account Names”)

auth_option: {
    IDENTIFIED BY 'auth_string' [REPLACE 'current_auth_string']
  | IDENTIFIED WITH auth_plugin
  | IDENTIFIED WITH auth_plugin BY 'auth_string' [REPLACE 'current_auth_string']
  | IDENTIFIED WITH auth_plugin AS 'hash_string'
}

tls_option: {
   SSL
 | X509
 | CIPHER 'cipher'
 | ISSUER 'issuer'
 | SUBJECT 'subject'
}

resource_option: {
    MAX_QUERIES_PER_HOUR count
  | MAX_UPDATES_PER_HOUR count
  | MAX_CONNECTIONS_PER_HOUR count
  | MAX_USER_CONNECTIONS count
}

password_option: {
    PASSWORD EXPIRE [DEFAULT | NEVER | INTERVAL N DAY]
  | PASSWORD HISTORY {DEFAULT | N}
  | PASSWORD REUSE INTERVAL {DEFAULT | N DAY}
  | PASSWORD REQUIRE CURRENT [DEFAULT | OPTIONAL]
}

lock_option: {
    ACCOUNT LOCK
  | ACCOUNT UNLOCK
}

这个ALTER USER语句修改MySQL账户。它使认证作用,SSL / TLS,资源的限制,以及密码管理属性进行修改现有的帐户,并启用账户锁定和解锁。

在大多数情况下,ALTER USER需要全球CREATE USER特权,或UPDATE特权的MySQL系统数据库。例外的是:

  • 任何客户端连接到服务器可以使用匿名帐户,帐户的密码更改。(特别是,你可以改变自己的密码。)看你的帐户服务器认证,调用CURRENT_USER()功能:

    选择current_user();
  • DEFAULT ROLE语法,ALTER USER需要这些特权:

    • 设置为另一个用户的默认角色需要全球CREATE USER特权,或UPDATE特权的mysql.default _角色系统表

    • 为自己设置默认的角色不需要特殊的权限,只要你想要作为默认的角色已经给你。

read_only系统变量是启用,ALTER USER另外需要CONNECTION_ADMINSUPER特权

默认情况下,如果你想修改用户不存在发生错误。如果IF EXISTS条款,声明产生警告每个指定的用户不存在,而不是一个错误。

重要

在某些情况下,ALTER USER可记录在服务器日志或在客户端在历史文件等历史.mysql _ ~,这意味着明文密码可以由任何人具有读访问,读取信息。有关信息的条件下,出现这种服务器日志和如何控制它,看第6.1.2.3,“密码登录”。关于客户端登录类似的信息,参见第4.5.1.3,“MySQL日志”

有几个方面ALTER USER声明,以下所描述的主题:

改变用户概要

对每个受影响的帐户,ALTER USERmodifies the correspondingmysql.user表格行反映在声明中指定的属性。未指定的属性保留其当前值。

每个帐户名称使用的格式描述第6.2.4,“指定的帐户名”。如果省略该帐户名,主机名,默认为'%'。它也可以指定CURRENT_USERCURRENT_USER()指与当前会话关联的帐户。

只有一个语法,可以指定的帐户USER()功能:

修改用户user()经”auth_string&#39;;

这种语法使没有命名你的帐户里面更改自己的密码。

ALTER USER语法允许auth_option价值遵循user价值,auth_option指示如何通过指定账户认证账户认证插件,凭据(例如,密码),或两者。每个auth_option价值应用只有该帐户命名它之前

user规格,声明可以包括选择SSL / TLS、资源限制、密码管理、锁紧性能。所有这些选项全球的声明和申请全部在一份声明中指定账户。

例如:更改帐户密码和终止它。因此,用户必须与指定的密码,选择一个新的人在下一个连接的连接:

ALTER USER 'jeffrey'@'localhost'
  IDENTIFIED BY 'new_password' PASSWORD EXPIRE;

例如:修改账户的使用sha256_password身份验证插件和给定的密码。需要一个新的密码,选择每180天:

改变用户杰夫瑞&#39;@&#39;本地主机&#39;确定&#39; sha256_passwordnew_password“密码过期间隔180天;

例如:锁定或解锁一个帐户:

ALTER USER 'jeffrey'@'localhost' ACCOUNT LOCK;
ALTER USER 'jeffrey'@'localhost' ACCOUNT UNLOCK;

例如:需要一个帐户连接使用SSL和建立一个限制每小时20连接:

ALTER USER 'jeffrey'@'localhost'
  REQUIRE SSL WITH MAX_CONNECTIONS_PER_HOUR 20;

例:这句话改变了两个账户,每个账户指定一些属性和一些全局属性:

ALTER USER
  'jeffrey'@'localhost' IDENTIFIED BY 'new_password',
  'jeanne'@'localhost'
  REQUIRE SSL WITH MAX_USER_CONNECTIONS 2
  PASSWORD HISTORY 5;

这个auth_option值以下杰夫瑞IDENTIFIED BY)只适用于之前的账户,从而改变密码只杰夫瑞。为jeanne,没有账号的价值(因而留下密码不变)。其余的属性适用于全球所有的账户在声明中称,所以这两个帐户:

  • 连接需要使用SSL

  • 帐户可用于两个最大同时连接。

  • 修改密码不能重复使用任何五最新密码。

在一个特定类型的选项的情况下,在这方面的帐户保持不变。例如,没有锁定选项,该帐户的锁定状态不改变。

改变用户认证方案

一个帐号可以跟着一个auth_option身份验证选项指定账户认证插件,凭据,或两者。它还包括一个更换子句指定要取代现有的帐户密码。

  • auth_plugin名称验证插件。插件名称可以引用字符串或一个非上市的名称。插件名称存储在插件列的mysql.user系统表

    auth_option语法不指定一个身份验证插件,插件的默认的值default_authentication_plugin系统变量。为每个插件的描述,参见第6.5.1,验证“插件”

  • 凭据存储在authentication_string列的mysql.user系统表。一个'auth_string'&#39;hash_string&#39;值指定帐户凭据,或者作为一个明文(未加密)字符串或散列在预期的格式与帐户相关的认证插件,分别:

    • 语法使用'auth_string',该字符串是明文,通过认证的插件可能散列。返回结果的插件存储在_认证字符串专栏一个插件可以使用价值的规定,在这种情况下,没有发生哈希。

    • 语法使用'hash_string',字符串被认为是已经通过认证的插件进行散列格式要求。如果哈希格式是不适当的插件,它将无法使用正确的客户端连接的认证不发生。

  • REPLACE 'current_auth_string'条款(可作为MySQL 8.0.13)指定当前帐户的密码被替换为明文(未加密)字符串:

    • 该条款必须如果账户密码修改必须指定当前给密码(验证用户试图做出改变,真的知道当前密码)。

    • 子句是可选的如果账户密码修改可以但不需要指定当前密码。

    • 如果条款给予但不当前密码匹配语句失败,即使子句是可选的。

    • REPLACE可以指定只有转化为当前用户的帐户密码。

    有关密码验证的更多信息通过指定的当前密码,看第6.3.8,“密码管理”

ALTER USER允许这些auth_option语法:

  • IDENTIFIED BY 'auth_string' [REPLACE 'current_auth_string']

    设置插件的默认账户认证插件,通过明文'auth_string'对散列值的插件,并在结果存储mysql.user开户行

    这个REPLACE条款,如果有,指定当前帐户的密码,如本节前面描述的。

  • IDENTIFIED WITH auth_plugin

    设置账户认证插件auth_plugin,清除凭据为空字符串(凭据与老认证插件,并不是新的),并在结果存储mysql.user开户行

    此外,密码是标注过期。用户必须选择一个新的连接时,下一个。

  • IDENTIFIED WITH auth_plugin BY 'auth_string' [REPLACE 'current_auth_string']

    设置账户认证插件auth_plugin,通过明文&#39;auth_string&#39;对散列值的插件,并在结果存储mysql.user开户行

    这个REPLACE条款,如果有,指定当前帐户的密码,如本节前面描述的。

  • IDENTIFIED WITH auth_plugin AS 'hash_string'

    设置账户认证插件auth_plugin和存储的散列&#39;hash_string&#39;价值是在mysql.user开户行。字符串被认为是已经反复推敲的插件所需要的格式。

例1:指定密码为明文;默认插件的使用:

ALTER USER 'jeffrey'@'localhost'
  IDENTIFIED BY 'password';

例2:指定身份验证插件,随着明文密码值:

ALTER USER 'jeffrey'@'localhost'
  IDENTIFIED WITH mysql_native_password
             BY 'password';

例3:如例2,但除此之外,指定当前密码为满足任何要求做出改变的用户知道密码明文值:

ALTER USER 'jeffrey'@'localhost'
  IDENTIFIED WITH mysql_native_password
             BY 'password'
             REPLACE 'current_password';

前面的语句将失败,除非当前用户jeffrey因为更换是只为当前用户密码的修改允许。

例4:指定身份验证插件,随着密码值:

ALTER USER 'jeffrey'@'localhost'
  IDENTIFIED WITH mysql_native_password
             AS '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4';

更多信息关于设置密码和身份验证插件,看第6.3.7,“分配账号密码”,和第6.3.10,“认证”

修改用户的角色选择

ALTER USER ... DEFAULT ROLE定义的角色变得活跃,当用户连接到服务器,认证,或用户执行时SET ROLE DEFAULT在会议上发言

ALTER USER ... DEFAULT ROLE是替代语法SET DEFAULT ROLE(见第13.7.1.9,“设置默认角色的语法”页:1不过ALTER USER对于只有一个用户设置默认值,而SET DEFAULT ROLE可以为多个用户设置默认。另一方面,你可以指定current_user作为用户名称的用户名称ALTER USER声明,而你不能SET DEFAULT ROLE

每个用户帐户名称使用先前描述的格式。

每个角色名称使用的格式描述第6.2.5,“指定角色的名字”。。。。。。。例如:

ALTER USER 'joe'@'10.0.0.1' DEFAULT ROLE administrator, developer;

如果省略的角色名,主机名,默认为'%'

以下条款的DEFAULT ROLE关键词允许这些值:

  • NONE:设置默认(没有作用)

  • ALL:设置默认的帐户授予的所有角色。

  • role [, role ] ...:设置默认的命名的角色,不存在或被授予该帐户的时候ALTER USER ... DEFAULT ROLE执行

user ssl / tles选项

MySQL可以检查除了通常的认证是基于用户名和凭据X509证书属性。在SSL / TLS和MySQL的使用背景信息,看6.4节,“使用加密的连接”

指定SSL / TLS MySQL账户相关的选项,使用REQUIRE子句指定一个或多个tls_option价值观

顺序REQUIRE选择不要紧,但是没有选项可以指定了两次。这个关键词之间是可选的REQUIRE选项

ALTER USER允许这些tls_option价值观:

  • NONE

    显示所有账户的语句命名没有SSL或X509要求。未加密的连接,如果用户名和密码是有效的许可。加密连接可以使用,在客户的选择,如果客户有适当的证书和密钥文件。

    ALTER USER 'jeffrey'@'localhost' REQUIRE NONE;
    

    默认情况下,客户试图建立安全连接。客户有REQUIRE NONE,连接尝试回到一个安全加密的连接如果无法建立连接。需要加密连接,客户端只需要指定--ssl-mode=REQUIRED期权;连接尝试失败如果安全无法建立连接。

  • SSL

    告诉服务器只允许加密连接的所有帐户的语句命名。

    ALTER USER 'jeffrey'@'localhost' REQUIRE SSL;
    

    默认情况下,客户试图建立安全连接。对那些有REQUIRE SSL,连接尝试失败如果安全无法建立连接。

  • X509

    所有帐户的语句命名,要求客户出示有效证件,但确切的证明,发行人,和主题不重要。唯一的要求是,它应该有可能验证其签名的CA证书。使用X509证书总是意味着加密,所以SSL选择在这种情况下是不必要的。

    改变user’杰弗里@ localhost”需要X509;

    为帐户REQUIRE X509,客户必须指定--ssl-key--ssl-cert选择连接。(建议但不要求--ssl-ca也可指定,由服务器提供的公共证书可以验证。)这是真实的发行人SUBJECT因为那些要求期权隐含的要求X509

  • ISSUER 'issuer'

    所有帐户的声明称,要求客户出示有效的X509证书颁发CA'issuer'。如果客户提出了一个有效的证书却有不同的发行人,服务器拒绝连接。使用X509证书总是意味着加密,所以SSL选择在这种情况下是不必要的。

    ALTER USER 'jeffrey'@'localhost'
      REQUIRE ISSUER '/C=SE/ST=Stockholm/L=Stockholm/
        O=MySQL/CN=CA/emailAddress=ca@example.com';
    

    因为ISSUER意味着要求X509,客户必须指定--ssl-key--ssl-cert选择连接。(建议但不要求--ssl-ca也可指定,由服务器提供的公共证书可以验证。)

  • SUBJECT 'subject'

    所有帐户的声明称,要求客户出示有效的X509证书包含的主题subject。如果客户提出了一个有效的证书却有不同的主题,服务器拒绝连接。使用X509证书总是意味着加密,所以SSL选择在这种情况下是不必要的。

    ALTER USER 'jeffrey'@'localhost'
      REQUIRE SUBJECT '/C=SE/ST=Stockholm/L=Stockholm/
        O=MySQL demo client certificate/
        CN=client/emailAddress=client@example.com';
    

    MySQL是一个简单的字符串比较'subject'在证书的价值,所以lettercase和组件的顺序必须完全按照证书。

    因为SUBJECT意味着要求X509clients必备,specify the--ssl-key--ssl-cert选择连接。(建议但不要求--ssl-ca也可指定,由服务器提供的公共证书可以验证。)

  • CIPHER 'cipher'

    所有帐户的声明称,需要特定的密码加密的连接方法。此选项需要确保使用密码和足够强度的密钥长度。如果使用加密可以使用较短的密钥算法是老弱。

    ALTER USER 'jeffrey'@'localhost'
      REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';
    

这个SUBJECT发行人,和CIPHER选项可以组合在要求条款:

ALTER USER 'jeffrey'@'localhost'
  REQUIRE SUBJECT '/C=SE/ST=Stockholm/L=Stockholm/
    O=MySQL demo client certificate/
    CN=client/emailAddress=client@example.com'
  AND ISSUER '/C=SE/ST=Stockholm/L=Stockholm/
    O=MySQL/CN=CA/emailAddress=ca@example.com'
  AND CIPHER 'EDH-RSA-DES-CBC3-SHA';
修改用户的资源限制选项

它有可能将由一个帐户使用服务器资源的限制,如在第6.3.6,“设置账户资源限制”。这样做,使用WITH子句指定一个或多个resource_option价值观

顺序WITH选择并不重要,但如果一个给定的资源限制是多次指定的最后一个实例的优先级。

ALTER USER允许这些resource_option价值观:

  • MAX_QUERIES_PER_HOUR countmax_updates_per_hourcountmax_connections_per_hourcount

    所有帐户的声明称,这些选项限制多少查询,更新,并连接到服务器允许每个帐户在任何给定的一个小时内。如果count(默认值),这意味着该帐户没有限制。

  • MAX_USER_CONNECTIONS count

    所有帐户的声明称,限制同时连接的最大数量的服务器的每个帐户。一个非零的count指定限制的考虑。如果count(默认),服务器确定的同时连接数为帐户的全球价值max_user_connections系统变量。如果max_user_connections也为零,没有限制的帐户。

例子:

ALTER USER 'jeffrey'@'localhost'
  WITH MAX_QUERIES_PER_HOUR 500 MAX_UPDATES_PER_HOUR 100;
修改用户密码管理选项

ALTER USER支持多种password_option密码管理价值:

  • 密码过期选项:你可以将某个帐户的密码,手动建立密码过期策略。政策选择不会过期的密码。相反,他们决定如何服务器应用自动到期基于密码时代的帐户,这是从日期和最近的账户密码更改时间评估。

  • 密码重用选项:你可以限制基于口令的变化,数字密码重用时间,或两者。

  • 密码验证所需的选项:你可以表明是否试图更改帐户密码必须指定的当前密码,验证的用户试图做出改变,真的知道当前密码。

本节描述密码管理选项的语法。关于建立密码管理政策信息,看第6.3.8,“密码管理”

密码管理选项仅适用于存储凭据的帐户内mysql.user系统表(mysql_native_passwordsha256_password,或caching_sha2_password)。对那些使用执行验证外部认证系统插件,密码管理必须处理外部与系统以及。

客户有过期的密码,如果该帐户的密码过期或手动密码年龄是大于其允许的寿命每自动过期策略。在这种情况下,服务器或断开客户端或限制操作允许它(见第6.3.9条,“服务器处理过期的密码”)。操作由一个错误限制客户端的结果直到用户建立新的帐户密码。

ALTER USER允许这些password_option控制密码过期值:

  • PASSWORD EXPIRE

    立即标记所有帐户的密码已过期的语句命名。

    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE;
    
  • PASSWORD EXPIRE DEFAULT

    将所有的账户被声明让全球过期策略适用于指定的default_password_lifetime系统变量

    “杰夫”修改用户的密码默认localhost,呼气;
  • PASSWORD EXPIRE NEVER

    此过期选项重写所有帐户的语句命名的全球政策。对于每一个,它禁用密码过期,密码永不过期。

    ALTER USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER;
    
  • PASSWORD EXPIRE INTERVAL N DAY

    此过期选项重写所有帐户的语句命名的全球政策。一、设置密码的一生N天.下面的语句需要密码要每180天更换一次:

    改变用户的密码是“localhost是Jeffrey expire间隔180天;

ALTER USER允许这些password_option基于需要更改密码的最小数量的以前的密码控制利用的价值:

  • PASSWORD HISTORY DEFAULT

    将所有的账户被声明,关于密码历史长度适用于全球的政策,禁止重复使用的密码在指定的数量变化password_history系统变量

    改变用户的密码是“localhost是Jeffrey历史违约;
  • PASSWORD HISTORY N

    这个历史长度选项重写所有帐户的语句命名的全球政策。一、设置密码历史长度N密码,禁止使用任何的N最近选择的密码。以下声明禁止任何上述6密码重用:

    更改用户的密码。“localhost”的历史。

ALTER USER允许这些password_option基于时间的以前的密码控制利用的价值:

  • PASSWORD REUSE INTERVAL DEFAULT

    将所有的报表指定的帐户这样的全球政策关于时间的应用,禁止使用密码比指定的天数更新password_reuse_interval系统变量

    杰弗里的老用户“localhost密码复用间隔违约;
  • PASSWORD REUSE INTERVAL N DAY

    这个时间选项重写所有帐户的语句命名的全球政策。对每个人来说,这套密码重用区间N天,禁止重复使用密码比很多天更新。以下声明禁止重复使用密码360天:

    杰弗里的老用户“localhost密码复用间隔360天;

ALTER USER允许这些password_option控制是否试图更改帐户密码必须指定当前密码值,验证该用户试图做出改变,真的知道当前密码:

  • PASSWORD REQUIRE CURRENT

    这种验证选项重写所有帐户的语句命名的全球政策。对于每一个,它要求更改密码指定当前密码。

    ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT;
    
  • PASSWORD REQUIRE CURRENT OPTIONAL

    这种验证选项重写所有帐户的语句命名的全球政策。对每个人来说,它并不需要更改密码指定当前密码。(当前密码可以但不必了。)

    ALTER USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT OPTIONAL;
    
  • PASSWORD REQUIRE CURRENT DEFAULT

    将所有的报表指定的帐户,密码验证适用于全球政策、规定的password_require_current系统变量

    “杰夫”修改用户的密码默认使用localhost的电流;

如果一个给定类型的多个密码管理选项(PASSWORD EXPIRE密码历史PASSWORD REUSE INTERVAL密码要求)是指定的,最后一个优先。

笔记

这是可能的重置通过它的电流值的密码。作为一个好的政策,最好是选择一个不同的密码。数据库管理员可以通过建立一个适当的密码重用政策执行非重用。看到密码重用策略

更改用户帐户的锁定选项

MySQL支持帐户锁定和解锁使用ACCOUNT LOCK账户解锁选项,它指定一个帐户的锁定状态。额外的讨论,见第6.3.12,“用户帐户锁定”

如果有多个帐户锁定选项是指定的,最后一个优先。

改变用户的二进制日志

ALTER USER如果它成功的二进制日志写的,但如果它失败了;在这种情况下,回滚时,不进行任何更改。一份声明中写入二进制日志包含所有指定的用户。如果如果存在条款是给定的,这甚至包括用户不存在,并没有改变。

如果原来的语句更改为用户的凭据,声明中写入二进制日志指定用户适用的认证插件,确定如下:

  • 该插件在最初的声明称,如果一个被指定的。

  • 否则,插件与用户帐户的用户是否存在,或默认的身份验证插件,如果用户不存在。(如果语句写入二进制日志必须指定一个用户,特别是认证插件包括在最初的声明。)

如果服务器添加在声明中写入二进制日志中的任何用户的默认身份验证插件,它写入错误日志命名这些用户警告。

13.7.1.2创建角色的语法

CREATE ROLE [IF NOT EXISTS] role [, role ] ...

CREATE ROLE创建一个或多个角色,即集合的特权。使用此语句,你必须有全球CREATE ROLECREATE USER特权。当read_only系统变量是启用,CREATE ROLE另外需要CONNECTION_ADMINSUPER特权

角色创建时被锁定,没有密码,并指定默认的身份验证插件。

CREATE ROLE无论是成功的所有命名的角色或卷有错误发生后并没有影响。默认情况下,如果你试图创造一个角色,已经发生了一个错误。如果如果不存在条款,声明产生每个命名的角色,已经存在一个警告,而不是一个错误。

声明是如果它成功的二进制日志写的,但如果它失败了;在这种情况下,回滚时,不进行任何更改。一份声明中写入二进制日志包括所有命名的角色。如果IF NOT EXISTS条款是给定的,这甚至包括角色已经存在,不创建。

每个角色名称使用的格式描述第6.2.5,“指定角色的名字”。。。。。。。例如:

CREATE ROLE 'administrator', 'developer';
CREATE ROLE 'webapp'@'localhost';

如果省略的角色名,主机名,默认为'%'

角色使用的例子,看第6.3.4,“角色”

13.7.1.3创建用户语法

CREATE USER [IF NOT EXISTS]
    user [auth_option] [, user [auth_option]] ...
    DEFAULT ROLE role [, role ] ...
    [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]
    [WITH resource_option [resource_option] ...]
    [password_option | lock_option] ...

user:
    (see Section 6.2.4, “Specifying Account Names”)

auth_option: {
    IDENTIFIED BY 'auth_string'
  | IDENTIFIED WITH auth_plugin
  | IDENTIFIED WITH auth_plugin BY 'auth_string'
  | IDENTIFIED WITH auth_plugin AS 'hash_string'
}

tls_option: {
   SSL
 | X509
 | CIPHER 'cipher'
 | ISSUER 'issuer'
 | SUBJECT 'subject'
}

resource_option: {
    MAX_QUERIES_PER_HOUR count
  | MAX_UPDATES_PER_HOUR count
  | MAX_CONNECTIONS_PER_HOUR count
  | MAX_USER_CONNECTIONS count
}

password_option: {
    PASSWORD EXPIRE [DEFAULT | NEVER | INTERVAL N DAY]
  | PASSWORD HISTORY {DEFAULT | N}
  | PASSWORD REUSE INTERVAL {DEFAULT | N DAY}
  | PASSWORD REQUIRE CURRENT [DEFAULT | OPTIONAL]
}

lock_option: {
    ACCOUNT LOCK
  | ACCOUNT UNLOCK
}

这个CREATE USER语句创建新的MySQL账户。它使认证作用,SSL / TLS,资源的限制,以及密码管理特性来建立新帐户,帐户和控制是否初步锁定或解锁。

使用CREATE USER,你必须有全球CREATE USER特权,或INSERT特权的MySQL系统数据库。当read_only系统变量是启用,CREATE USER另外需要CONNECTION_ADMINSUPER特权

CREATE USER无论是成功的所有指定用户或卷有错误发生后并没有影响。默认情况下,如果你想创建一个用户已经存在发生错误。如果如果不存在条款,声明产生的每个指定的用户已存在的警告,而不是一个错误。

重要

在某些情况下,CREATE USER可记录在服务器日志或在客户端在历史文件等历史.mysql _ ~,这意味着明文密码可以由任何人具有读访问,读取信息。有关信息的条件下,出现这种服务器日志和如何控制它,看第6.1.2.3,“密码登录”。关于客户端登录类似的信息,参见第4.5.1.3,“MySQL日志”

有几个方面CREATE USER声明,以下所描述的主题:

创建用户概述

每个帐户,CREATE USER创建一个新的行mysql.user系统表。开户行反映在声明中指定的属性。未指定的属性设置为默认值:

  • 认证:指由认证插件default_authentication_plugin系统变量,和空的凭据

  • 默认的角色:NONE

  • SSL / TLS的:NONE

  • 资源限制:无限

  • 密码管理:PASSWORD EXPIRE DEFAULT PASSWORD HISTORY DEFAULT PASSWORD REUSE INTERVAL DEFAULT PASSWORD REQUIRE CURRENT DEFAULT

  • 帐户锁定:ACCOUNT UNLOCK

首次创建时没有权限和默认角色的帐户NONE。分配权限或角色,使用GRANT声明

每个帐户名称使用的格式描述第6.2.4,“指定的帐户名”。。。。。。。例如:

CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'password';

如果省略该帐户名,主机名,默认为'%'

每个user值命名的帐户也可以跟着一个可选auth_option值,指示如何账户认证。这些价值观使账户认证插件和凭据(例如,密码)被指定。每个auth_option价值应用只有该帐户命名它之前

user规格,声明可以包括选择SSL / TLS、资源限制、密码管理、锁紧性能。所有这些选项全球的声明和申请全部在一份声明中指定账户。

例如:创建一个帐户使用的默认身份验证插件和给定的密码。马克密码过期,用户必须选择一个新的人在第一次连接到服务器:

CREATE USER 'jeffrey'@'localhost'
  IDENTIFIED BY 'new_password' PASSWORD EXPIRE;

例如:创建一个帐户使用的sha256_password身份验证插件和给定的密码。需要一个新的密码,选择每180天:

创建用户杰夫瑞&#39;@&#39;本地主机&#39;确定&#39; sha256_passwordnew_password“密码过期间隔180天;

例如:这个语句创建两个账户,每个账户指定一些属性和一些全局属性:

CREATE USER
  'jeffrey'@'localhost' IDENTIFIED WITH mysql_native_password
                                   BY 'new_password1',
  'jeanne'@'localhost' IDENTIFIED WITH sha256_password
                                  BY 'new_password2'
  REQUIRE X509 WITH MAX_QUERIES_PER_HOUR 60
  PASSWORD HISTORY 5
  ACCOUNT LOCK;

每个auth_option价值(确定…由在这种情况下)只适用于账户命名它之前,所以每个账户使用后立即验证插件和密码。其余的属性适用于全球所有的账户在声明中称,所以这两个帐户:

  • 连接必须使用有效的X509证书了。

  • 高达60每小时允许查询。

  • 修改密码不能重复使用任何五最新密码。

  • 帐号锁定最初,所以实际上是一个占位符,不能使用,直到管理员解锁。

创建用户认证

一个帐号可以跟着一个auth_option身份验证选项指定账户认证插件,凭据,或两者:

  • auth_plugin名称验证插件。插件名称可以引用字符串或一个非上市的名称。插件名称存储在插件列的mysql.user系统表

    auth_option语法不指定一个身份验证插件,插件的默认的值default_authentication_plugin系统变量。为每个插件的描述,参见第6.5.1,验证“插件”

  • 凭据存储在authentication_string列的mysql.user系统表。一个'auth_string'&#39;hash_string&#39;值指定帐户凭据,或者作为一个明文(未加密)字符串或散列在预期的格式与帐户相关的认证插件,分别:

    • 语法使用'auth_string',该字符串是明文,通过认证的插件可能散列。返回结果的插件存储在_认证字符串专栏一个插件可以使用价值的规定,在这种情况下,没有发生哈希。

    • 语法使用'hash_string',字符串被认为是已经通过认证的插件进行散列格式要求。如果哈希格式是不适当的插件,它将无法使用正确的客户端连接的认证不发生。

CREATE USER允许这些auth_option语法:

  • IDENTIFIED BY 'auth_string'

    设置插件的默认账户认证插件,通过明文'auth_string'对散列值的插件,并在结果存储mysql.user开户行

  • IDENTIFIED WITH auth_plugin

    设置账户认证插件auth_plugin,清除凭据为空字符串,并在结果存储mysql.user开户行

  • IDENTIFIED WITH auth_plugin BY 'auth_string'

    设置账户认证插件auth_plugin,通过明文&#39;auth_string&#39;对散列值的插件,并在结果存储mysql.user开户行

  • IDENTIFIED WITH auth_plugin AS 'hash_string'

    设置账户认证插件auth_plugin和存储的散列&#39;hash_string&#39;价值是在mysql.user开户行。字符串被认为是已经反复推敲的插件所需要的格式。

例1:指定密码为明文;默认插件的使用:

CREATE USER 'jeffrey'@'localhost'
  IDENTIFIED BY 'password';

例2:指定身份验证插件,随着明文密码值:

CREATE USER 'jeffrey'@'localhost'
  IDENTIFIED WITH mysql_native_password BY 'password';

在每一种情况下,存储在账户行的密码值是明文的价值'password'经过散列与帐户相关的认证插件。

更多信息关于设置密码和身份验证插件,看第6.3.7,“分配账号密码”,和第6.3.10,“认证”

创建用户角色选择

这个DEFAULT ROLE条款定义的角色变得活跃,当用户连接到服务器,认证,或用户执行时SET ROLE DEFAULT在会议上发言

每个角色名称使用的格式描述第6.2.5,“指定角色的名字”。。。。。。。例如:

CREATE USER 'joe'@'10.0.0.1' DEFAULT ROLE administrator, developer;

如果省略的角色名,主机名,默认为'%'

这个DEFAULT ROLE条款允许一个或多个用逗号分隔的角色名称。这些角色不需要同时存在CREATE USER执行

创建使用SSL / TLS选项

MySQL可以检查除了通常的认证是基于用户名和凭据X509证书属性。在SSL / TLS和MySQL的使用背景信息,看6.4节,“使用加密的连接”

指定SSL / TLS MySQL账户相关的选项,使用REQUIRE子句指定一个或多个tls_option价值观

顺序REQUIRE选择不要紧,但是没有选项可以指定了两次。这个关键词之间是可选的REQUIRE选项

CREATE USER允许这些tls_option价值观:

  • NONE

    显示所有账户的语句命名没有SSL或X509要求。未加密的连接,如果用户名和密码是有效的许可。加密连接可以使用,在客户的选择,如果客户有适当的证书和密钥文件。

    CREATE USER 'jeffrey'@'localhost' REQUIRE NONE;
    

    默认情况下,客户试图建立安全连接。客户有REQUIRE NONE,连接尝试回到一个安全加密的连接如果无法建立连接。需要加密连接,客户端只需要指定--ssl-mode=REQUIRED期权;连接尝试失败如果安全无法建立连接。

    NONE是默认如果没有SSL相关要求指定的选项

  • SSL

    告诉服务器只允许加密连接的所有帐户的语句命名。

    CREATE USER 'jeffrey'@'localhost' REQUIRE SSL;
    

    默认情况下,客户试图建立安全连接。对那些有REQUIRE SSL,连接尝试失败如果安全无法建立连接。

  • X509

    所有帐户的语句命名,要求客户出示有效证件,但确切的证明,发行人,和主题不重要。唯一的要求是,它应该有可能验证其签名的CA证书。使用X509证书总是意味着加密,所以SSL选择在这种情况下是不必要的。

    2 . create user &#39; Jeffrey &#39; @ &#39; ilamhost require XIV;

    为帐户REQUIRE X509,客户必须指定--ssl-key--ssl-cert选择连接。(建议但不要求--ssl-ca也可指定,由服务器提供的公共证书可以验证。)这是真实的发行人SUBJECT因为那些要求期权隐含的要求X509

  • ISSUER 'issuer'

    所有帐户的声明称,要求客户出示有效的X509证书颁发CA'issuer'。如果客户提出了一个有效的证书却有不同的发行人,服务器拒绝连接。使用X509证书总是意味着加密,所以SSL选择在这种情况下是不必要的。

    CREATE USER 'jeffrey'@'localhost'
      REQUIRE ISSUER '/C=SE/ST=Stockholm/L=Stockholm/
        O=MySQL/CN=CA/emailAddress=ca@example.com';
    

    因为ISSUER意味着要求X509,客户必须指定--ssl-key--ssl-cert选择连接。(建议但不要求--ssl-ca也可指定,由服务器提供的公共证书可以验证。)

  • SUBJECT 'subject'

    所有帐户的声明称,要求客户出示有效的X509证书包含的主题subject。如果客户提出了一个有效的证书却有不同的主题,服务器拒绝连接。使用X509证书总是意味着加密,所以SSL选择在这种情况下是不必要的。

    CREATE USER 'jeffrey'@'localhost'
      REQUIRE SUBJECT '/C=SE/ST=Stockholm/L=Stockholm/
        O=MySQL demo client certificate/
        CN=client/emailAddress=client@example.com';
    

    MySQL是一个简单的字符串比较'subject'在证书的价值,所以lettercase和组件的顺序必须完全按照证书。

    因为SUBJECT意味着要求X509clients必备,specify the--ssl-key--ssl-cert选择连接。(建议但不要求--ssl-ca也可指定,由服务器提供的公共证书可以验证。)

  • CIPHER 'cipher'

    所有帐户的声明称,需要特定的密码加密的连接方法。此选项需要确保使用密码和足够强度的密钥长度。如果使用加密可以使用较短的密钥算法是老弱。

    CREATE USER 'jeffrey'@'localhost'
      REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';
    

这个SUBJECT发行人,和CIPHER选项可以组合在要求条款:

CREATE USER 'jeffrey'@'localhost'
  REQUIRE SUBJECT '/C=SE/ST=Stockholm/L=Stockholm/
    O=MySQL demo client certificate/
    CN=client/emailAddress=client@example.com'
  AND ISSUER '/C=SE/ST=Stockholm/L=Stockholm/
    O=MySQL/CN=CA/emailAddress=ca@example.com'
  AND CIPHER 'EDH-RSA-DES-CBC3-SHA';
创建用户的资源限制选项

它有可能将由一个帐户使用服务器资源的限制,如在第6.3.6,“设置账户资源限制”。这样做,使用WITH子句指定一个或多个resource_option价值观

顺序WITH选择并不重要,但如果一个给定的资源限制是多次指定的最后一个实例的优先级。

CREATE USER允许这些resource_option价值观:

  • MAX_QUERIES_PER_HOUR countmax_updates_per_hourcountmax_connections_per_hourcount

    所有帐户的声明称,这些选项限制多少查询,更新,并连接到服务器允许每个帐户在任何给定的一个小时内。如果count(默认值),这意味着该帐户没有限制。

  • MAX_USER_CONNECTIONS count

    所有帐户的声明称,限制同时连接的最大数量的服务器的每个帐户。一个非零的count指定限制的考虑。如果count(默认),服务器确定的同时连接数为帐户的全球价值max_user_connections系统变量。如果max_user_connections也为零,没有限制的帐户。

例子:

CREATE USER 'jeffrey'@'localhost'
  WITH MAX_QUERIES_PER_HOUR 500 MAX_UPDATES_PER_HOUR 100;
创建用户密码管理选项

CREATE USER支持多种password_option密码管理价值:

  • 密码过期选项:你可以将某个帐户的密码,手动建立密码过期策略。政策选择不会过期的密码。相反,他们决定如何服务器应用自动到期基于密码时代的帐户,这是从日期和最近的账户密码更改时间评估。

  • 密码重用选项:你可以限制基于口令的变化,数字密码重用时间,或两者。

  • 密码验证所需的选项:你可以表明是否试图更改帐户密码必须指定的当前密码,验证的用户试图做出改变,真的知道当前密码。

本节描述密码管理选项的语法。关于建立密码管理政策信息,看第6.3.8,“密码管理”

密码管理选项仅适用于存储凭据的帐户内mysql.user系统表(mysql_native_passwordsha256_password,或caching_sha2_password)。对那些使用执行验证外部认证系统插件,密码管理必须处理外部与系统以及。

客户有过期的密码,如果该帐户的密码过期或手动密码年龄是大于其允许的寿命每自动过期策略。在这种情况下,服务器或断开客户端或限制操作允许它(见第6.3.9条,“服务器处理过期的密码”)。操作由一个错误限制客户端的结果直到用户建立新的帐户密码。

CREATE USER允许这些password_option控制密码过期值:

  • PASSWORD EXPIRE

    立即标记所有帐户的密码已过期的语句命名。

    CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE;
    
  • PASSWORD EXPIRE DEFAULT

    将所有的账户被声明让全球过期策略适用于指定的default_password_lifetime系统变量

    用户创建的密码是“localhost Jeffrey expire是默认的;
  • PASSWORD EXPIRE NEVER

    此过期选项重写所有帐户的语句命名的全球政策。对于每一个,它禁用密码过期,密码永不过期。

    CREATE USER 'jeffrey'@'localhost' PASSWORD EXPIRE NEVER;
    
  • PASSWORD EXPIRE INTERVAL N DAY

    此过期选项重写所有帐户的语句命名的全球政策。一、设置密码的一生N天.下面的语句需要密码要每180天更换一次:

    用户创建的密码是“localhost是Jeffrey expire间隔180天;

CREATE USER允许这些password_option基于需要更改密码的最小数量的以前的密码控制利用的价值:

  • PASSWORD HISTORY DEFAULT

    将所有的账户被声明,关于密码历史长度适用于全球的政策,禁止重复使用的密码在指定的数量变化password_history系统变量

    用户创建的密码是“localhost是Jeffrey历史违约;
  • PASSWORD HISTORY N

    这个历史长度选项重写所有帐户的语句命名的全球政策。一、设置密码历史长度N密码,禁止使用任何的N最近选择的密码。以下声明禁止任何上述6密码重用:

    用户创建的密码是“localhost是Jeffrey历史6;

CREATE USER允许这些password_option基于时间的以前的密码控制利用的价值:

  • PASSWORD REUSE INTERVAL DEFAULT

    将所有的报表指定的帐户这样的全球政策关于时间的应用,禁止使用密码比指定的天数更新password_reuse_interval系统变量

    Jeffrey:创建用户密码复用间隔localhost违约;
  • PASSWORD REUSE INTERVAL N DAY

    这个时间选项重写所有帐户的语句命名的全球政策。对每个人来说,这套密码重用区间N天,禁止重复使用密码比很多天更新。以下声明禁止重复使用密码360天:

    创建用户密码(Jeffrey“localhost复用间隔360天;

CREATE USER允许这些password_option控制是否试图更改帐户密码必须指定当前密码值,验证该用户试图做出改变,真的知道当前密码:

  • PASSWORD REQUIRE CURRENT

    这种验证选项重写所有帐户的语句命名的全球政策。对于每一个,它要求更改密码指定当前密码。

    CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT;
    
  • PASSWORD REQUIRE CURRENT OPTIONAL

    这种验证选项重写所有帐户的语句命名的全球政策。对每个人来说,它并不需要更改密码指定当前密码。(当前密码可以但不必了。)

    CREATE USER 'jeffrey'@'localhost' PASSWORD REQUIRE CURRENT OPTIONAL;
    
  • PASSWORD REQUIRE CURRENT DEFAULT

    将所有的报表指定的帐户,密码验证适用于全球政策、规定的password_require_current系统变量

    用户创建的密码是“localhost是Jeffrey require默认流;

如果一个给定类型的多个密码管理选项(PASSWORD EXPIRE密码历史PASSWORD REUSE INTERVAL密码要求)是指定的,最后一个优先。

创建用户帐户的锁定选项

MySQL支持帐户锁定和解锁使用ACCOUNT LOCK账户解锁选项,它指定一个帐户的锁定状态。额外的讨论,见第6.3.12,“用户帐户锁定”

如果有多个帐户锁定选项是指定的,最后一个优先。

用户创建的二进制日志

CREATE USER如果它成功的二进制日志写的,但如果它失败了;在这种情况下,回滚时,不进行任何更改。一份声明中写入二进制日志包含所有指定的用户。如果如果不存在条款是给定的,这甚至包括用户已经存在,不创建。

声明中写入二进制日志指定每个用户的身份验证插件,确定如下:

  • 该插件在最初的声明称,如果一个被指定的。

  • Otherwise, the default authentication plugin. 特别是,如果是使用u1已经存在和使用非默认身份验证插件,声明中写入二进制日志如果不存在U1创建用户名称的默认身份验证插件。(如果语句写入二进制日志必须指定一个用户,默认身份验证插件包括在最初的声明。)

如果服务器添加任何不存在的用户在声明中写入二进制日志的默认身份验证插件,它写入错误日志命名这些用户警告。

13.7.1.4删除角色的语法

DROP ROLE [IF EXISTS] role [, role ] ...

DROP ROLE删除一个或多个角色(称为集合的特权)。使用此语句,你必须有全球DROP ROLECREATE USER特权。当read_only系统变量是启用,DROP ROLE另外需要CONNECTION_ADMINSUPER特权

角色命名的mandatory_roles系统变量的值不能下降。

DROP ROLE无论是成功的所有命名的角色或卷有错误发生后并没有影响。默认情况下,发生错误,如果你尝试删除不存在的作用。如果如果存在条款,声明产生每个命名的角色,不存在一个警告,而不是一个错误。

声明是如果它成功的二进制日志写的,但如果它失败了;在这种情况下,回滚时,不进行任何更改。一份声明中写入二进制日志包括所有命名的角色。如果IF EXISTS条款是给定的,这甚至包括角色,不存在没有下降。

每个角色名称使用的格式描述第6.2.5,“指定角色的名字”。。。。。。。例如:

DROP ROLE 'administrator', 'developer';
DROP ROLE 'webapp'@'localhost';

如果省略的角色名,主机名,默认为'%'

一个下降的作用是自动撤销任何用户帐户(或作用)的作用是理所当然的。在任何当前会话的这样一个账户,其权限调整为下表执行。

13.7.1.5滴用户语法

DROP USER [IF EXISTS] user [, user] ...

这个DROP USER语句删除一个或多个MySQL帐户和权限。它消除了所有的帐户权限授权表行。

角色命名的mandatory_roles系统变量的值不能下降。

使用DROP USER,你必须有全球CREATE USER特权,或DELETE特权的MySQL系统数据库。当read_only系统变量是启用,DROP USER另外需要CONNECTION_ADMINSUPER特权

DROP USER无论是成功的所有指定用户或卷有错误发生后并没有影响。默认情况下,发生错误,如果你试图删除一个用户不存在。如果如果存在条款,声明产生警告每个指定的用户不存在,而不是一个错误。

声明是如果它成功的二进制日志写的,但如果它失败了;在这种情况下,回滚时,不进行任何更改。一份声明中写入二进制日志包含所有指定的用户。如果IF EXISTS条款是给定的,这甚至包括用户不存在、不掉。

每个帐户名称使用的格式描述第6.2.4,“指定的帐户名”。。。。。。。例如:

DROP USER 'jeffrey'@'localhost';

如果省略该帐户名,主机名,默认为'%'

重要

DROP USER不自动关闭任何打开的用户会话。相反,如果在一个开放的会议用户掉线,声明不到用户的会话关闭时生效。一旦会话被关闭,用户正在下降,而用户下次尝试登录失败。这是由设计

DROP USER不会自动删除或无效的数据库或对象在他们老用户创建。这包括存储方案或意见,定义者属性名称的用户下降。试图访问这些对象可以定义的安全上下文执行他们产生一个错误。(关于安全上下文信息看,23.6节,“访问控制用于存储程序和视图”。)

格兰特13.7.1.6 syntax

GRANT
    priv_type [(column_list)]
      [, priv_type [(column_list)]] ...
    ON [object_type] priv_level
    TO user_or_role [, user_or_role] ...
    [WITH GRANT OPTION]

GRANT PROXY ON user_or_role
    TO user_or_role [, user_or_role] ...
    [WITH GRANT OPTION]

GRANT role [, role] ...
    TO user_or_role [, user_or_role] ...
    [WITH ADMIN OPTION]

object_type: {
    TABLE
  | FUNCTION
  | PROCEDURE
}

priv_level: {
    *
  | *.*
  | db_name.*
  | db_name.tbl_name
  | tbl_name
  | db_name.routine_name
}

user_or_role: {
    user
  | role
}

user:
    (see Section 6.2.4, “Specifying Account Names”)

role:
    (see Section 6.2.5, “Specifying Role Names”)

这个GRANT语句分配权限和角色MySQL用户账号和角色。有几个方面GRANT声明,以下所描述的主题:

格兰特概述

这个GRANT语句使系统管理员授予的权限和角色,它可以授予用户帐号和角色。这些语法限制:

这个GRANT语句使系统管理员授予的权限和角色,它可以授予用户帐号和角色。这些语法限制:

  • GRANT不能将授予特权和在同一个语句的作用。一个给定的GRANT授予权限或角色或者语言的必备。

  • 这个ON条款区分声明授予特权或角色:

    • ON这是一个重要的因素

    • 没有ONThe statement资助的角色。

    • 它允许指定权限和角色的帐户,但你必须使用单独的GRANT报表,每个语法适当什么是理所当然的。

关于角色的更多信息,参见第6.3.4,“角色”

使用GRANT,你必须有GRANT OPTION特权,你必须拥有你所给予的特权。当read_only系统变量是启用,GRANT另外需要CONNECTION_ADMINSUPER特权

GRANT无论是成功的所有命名的用户和角色或回滚,如果出现任何错误没有影响。声明仅仅是如果它成功的所有命名的用户和角色的二进制日志写。

这个REVOKE声明是有关GRANT并使管理员删除帐户的特权。看到第13.7.1.8,“撤销语法”

每个帐户名称使用的格式描述第6.2.4,“指定的帐户名”。每个角色名称使用的格式描述第6.2.5,“指定角色的名字”。。。。。。。例如:

GRANT ALL ON db1.* TO 'jeffrey'@'localhost';
GRANT 'role1', 'role2' TO 'user1'@'localhost', 'user2'@'localhost';
GRANT SELECT ON world.* TO 'role3';

如果省略该帐户或角色名,主机名,默认为'%'

通常情况下,数据库管理员首先使用CREATE USER创建一个帐户并定义其nonprivilege等特点,它的密码,它是使用安全连接,并对访问服务器资源的限制,然后使用GRANT定义它的特权ALTER USER可以用来改变现有账户nonprivilege特性。例如:

创建用户杰夫瑞&#39;@&#39;本地主机&#39;确定&#39;password&#39;;授予所有在DB1。*杰夫瑞&#39;@&#39;本地主机&#39;;&#39;杰夫瑞格兰特选择db2.invoice &#39;@&#39;本地主机&#39;;改变用户杰夫瑞&#39;@&#39;本地主机&#39;与max_queries_per_hour 90;

MySQL程序,GRANT响应查询好,为受影响的行当执行成功。从操作确定什么特权的结果,使用SHOW GRANTS。看到第13.7.6.21”节目,格兰特的语法”

重要

在某些情况下,GRANT可记录在服务器日志或在客户端在历史文件等历史.mysql _ ~,这意味着明文密码可以由任何人具有读访问,读取信息。有关信息的条件下,出现这种服务器日志和如何控制它,看第6.1.2.3,“密码登录”。关于客户端登录类似的信息,参见第4.5.1.3,“MySQL日志”

GRANT支持主机名称最多60个字符长。用户名称可以有32个字符。数据库,表,列,和常规的名字可以有64个字符。

警告

不要试图改变用户名称的允许长度的改变mysql.user系统表。这样,在不可预知的行为,甚至可能使它不可能为用户登录到MySQL服务器的结果。不改变表的结构MySQL系统数据库以外的任何其他形式的程序描述方法4.4.5“,”mysql_upgrade检查升级MySQL表”

对象引用的指南

几个物体内GRANT须引用引用是可选的,虽然在很多情况下:帐号,角色,数据库,表,列,和常规的名字。例如,如果一个user_namehost_name在一个帐户名的价值是法律作为一个不带引号的标识符,你不需要的话。然而,引号必须指定user_name包含特殊字符的字符串(如),或host_name字符串包含特殊字符或通配符(如%);例如,'test-user'@'%.com'。引用用户名和主机名称。

指定引用值:

  • 引用数据库,表,列,和常规的名字作为标识符。

  • 引用用户名和主机名的标识符或字符串。

  • 股票作为密码的字符串。

字符串引用标识符引用指南,看9.1.1节,“String Literals”,和9.2节,“架构对象名称”

这个_%通配符时允许指定数据库名称GRANT语句在数据库级(授予特权赠款打开(放)db_name*)。这意味着,例如,使用_汉字作为一个数据库名称的一部分,指定它作为\_GRANT声明中,防止用户能够访问其他数据库的通配符模式匹配;例如,赠款在` foo \ _bar `。*…

当一个数据库名称不能用于授予权限在数据库级别,但作为一个特权授予其他对象如表或常规的限定符(例如,GRANT ... ON db_name.tbl_name),通配符被视为正常的字符。

帐户名称

user中的值GRANT声明表示,声明将MySQL账户。为了适应授予从任意主机用户权益,MySQL支持指定的user在形成价值&#39;user_name“@”host_name&#39;

你可以在主机名指定通配符。例如,'user_name'@'%.example.com'适用于user_name在任何主机example.com域,和'user_name'@'198.51.100.%'适用于user_name在任何主机198.51.100C类子网

简单的形式'user_name'是同义词&#39;user_name“”“%”

MySQL不支持用户名通配符。引用一个匿名用户,与空的用户名指定帐户GRANT声明:

授予所有测试。*“&#39;@&#39;本地主机&#39;…;

在这种情况下,任何用户连接与匿名用户密码正确的本地主机将被允许访问,与匿名用户帐户关联的权限。

有关用户名称和帐户名称主机名称值的更多信息,参见第6.2.4,“指定的帐户名”

警告

如果你允许当地匿名用户连接到MySQL服务器,你也应该给予特权所有本地用户'user_name'@'localhost'。。。。。。。否则,“匿名用户账户本地服务器mysql.user系统表时使用命名用户试图登录到MySQL服务器从本地机。详情见第6,访问控制,阶段1:连接验证”

要确定这个问题是否适用于你,请执行以下查询,列出任何匿名用户:

SELECT Host, User FROM mysql.user WHERE User='';

为了避免这一问题只是描述,使用该语句删除本地匿名用户帐户:

DROP USER ''@'localhost';
MySQL的负载模式的权限

下表汇总了允许的静态和动态priv_type可以指定的权限类型GRANTREVOKE报表,和水平在每个权限可以授予。有关每个权限的更多信息,参见6.2.1节”,privileges提供由mysql”。有关静态和动态权限之间的差异信息,看6.2.2、静态与动态的特权”

表13.6允许的静态权限授予和撤销

特权可授予meaning and levels
ALL [PRIVILEGES]授予所有权限在指定的访问级别除外GRANT OPTIONPROXY
ALTER启用ALTER TABLE。全球数据库,表,水平。
ALTER ROUTINE使存储程序被改变或删除。级别:全球数据库,程序。
CREATE使数据库和表的创建。级别:全球数据库,表。
CREATE ROUTINE使存储程序创建。级别:全球数据库。
CREATE TABLESPACE使表空间和日志文件组被创建,修改,或删除。级别:全球。
CREATE TEMPORARY TABLES启用CREATE TEMPORARY TABLE。数据库:全球水平
CREATE USER启用CREATE USERDROP USERRENAME USER,和REVOKE ALL PRIVILEGES。级别:全球
CREATE VIEW使视图被创建或改变。级别:全球数据库,表。
DELETE启用DELETE。。。。。。。级:全球数据库表。
DROP使数据库、表和视图被删除。级别:全球数据库,表。
EVENT启用事件使用事件调度器。级别:全球数据库。
EXECUTE允许用户执行存储过程。级别:全球数据库,表。
FILE用户可以导致服务器读取或写入文件。级别:全球。
GRANT OPTION使权限授予或从其他帐号被删除。级别:全球、数据库、表、程序、代理。
INDEX使索引被创建或删除。级别:全球数据库,表。
INSERT启用INSERT。级别:全球、数据库、表、列。
LOCK TABLES启用LOCK TABLES在桌子上,你有SELECT特权。全球数据库的水平。
PROCESS用户可以看到所有的过程SHOW PROCESSLIST。级别:全球
PROXY启用用户代理。水平:从用户到用户。
REFERENCES使创建外键。级别:全球、数据库、表、列。
RELOAD启用FLUSH操作。全球的水平
REPLICATION CLIENT让用户问,主从服务器。级别:全球。
REPLICATION SLAVE使复制的奴隶从主人读二进制日志事件。级别:全球。
SELECT启用SELECT。级别:全球、数据库、表、列。
SHOW DATABASES使SHOW DATABASES显示所有的数据库。级别:全球。
SHOW VIEW启用SHOW CREATE VIEW。全球数据库,表,水平。
SHUTDOWN启用关闭。级别:全球
SUPER允许使用其他行政业务等CHANGE MASTER TOKILLPURGE BINARY LOGSSET GLOBAL,和mysqladmin DEBUG命令。级别:全球
TRIGGER使触发操作。级别:全球数据库,表。
UPDATE启用UPDATE。级别:全球、数据库、表、列。
USAGE同义词没有特权

表13.7允许动态权限授予和撤销

特权可授予meaning and levels
AUDIT_ADMIN使审计日志配置。级别:全球。
BINLOG_ADMIN启用二进制日志控制。级别:全球。
CONNECTION_ADMIN使连接限制/约束控制。级别:全球。
ENCRYPTION_KEY_ADMIN使InnoDB转动钥匙。级:全球
FIREWALL_ADMIN启用防火墙规则管理,任何用户。级别:全球。
FIREWALL_USER启用防火墙规则管理,自。级别:全球。
GROUP_REPLICATION_ADMIN使集团的复制控制。级别:全球。
REPLICATION_SLAVE_ADMIN使常规的复制控制。级别:全球。
ROLE_ADMIN启用WITH ADMIN OPTION。级别:全球
SET_USER_ID使设置非自DEFINER价值观。级别:全球
SYSTEM_VARIABLES_ADMIN使改性或持续的全球系统变量。级别:全球。
VERSION_TOKEN_ADMIN启用自定义的令牌使用的版本。全球的水平。

触发器与表相关联。创建或删除触发器,你必须TRIGGER表的特权,不触发

进入GRANT报表的ALL [PRIVILEGES]PROXY特权必须命名本身并不能说明与其他特权。ALL [PRIVILEGES]代表所有的特权可以在哪一级的权限被授予除GRANT OPTIONPROXY特权.

MySQL帐户信息存储在表mysql系统数据库。更多细节,请6.2节,“MySQL的权限系统”,讨论mysql系统数据库和访问控制系统广泛。

如果授权表行持有特权包含混合的情况下的数据库或表的名称和lower_case_table_names系统变量设置为非零值,REVOKE不可撤销这些特权。这将是必要的授权表直接操纵。(GRANT不会产生这样的行时lower_case_table_names是集,但这样的行可能已设置该变量之前创建的。这个lower_case_table_names设置只能配置在服务器启动。)

权限可以授予在几个层次,取决于使用的语法ON条款.为REVOKE,同打开(放)语法指定的权限删除

在全球,数据库,表格,和常规水平,GRANT ALL只分配特权,存在于你给予的水平。例如,给予所有db_name*是数据库级的语句,所以它不授予任何全球唯一的特权,如FILE。授予ALL不分配GRANT OPTIONPROXY特权

这个object_type条款,如果存在,应指定为FUNCTION,或程序当下面的对象是一个表,一个存储函数或存储过程。

一个用户对数据库、表、列的权限,或常规形成的逻辑性OR在每一个权限帐户权限。例如,如果一个用户有一个全球SELECT特权,特权不能无特权的数据库,表否定,或列级。特权的检查程序详情第6.2.7,访问控制,阶段2:请求验证”

如果你正在使用的表、列、或日常的特权,甚至一个用户,服务器检查表,列,和所有用户日常的特权和减慢MySQL一点。同样,如果你限制查询,更新的数量,或连接的任何用户,服务器必须监控这些值。

MySQL可以授予权限在数据库或表不存在。表,被授予的权限必须包括CREATE特权此行为是设计,目的是使数据库管理员准备的用户帐户和权限的数据库或表,以后再创造。

重要

MySQL不会自动撤销任何特权,当你删除一个数据库或表。然而,如果你把一个程序,任何程序级权限,程序被撤销。

全局权限

全球的特权是行政或适用于所有数据库在给定的服务器。指定全局权限,使用ON *.*语法:

授予所有*。*”“”“someuser &#39;somehost;查询、插入*。*”“”“someuser &#39;somehost;

这个CREATE TABLESPACECREATE USERFILEPROCESSRELOADREPLICATION CLIENTREPLICATION SLAVESHOW DATABASESSHUTDOWN,和SUPER静态权限管理,只能被授予全球。

动态权限都是全球只能授予全球。

其他的权限可以授予全球或在更具体的层次。

的影响GRANT OPTION授予在全球不同的静态和动态的特权:

  • GRANT OPTION授予任何静态全局权限适用于所有静态全局权限。

  • GRANT OPTION授予任何动态权限仅适用于动态权限。

GRANT ALL在全球层面上授予所有静态全局权限和所有目前注册的动态权限。动态权限注册执行后续赠款语句不授予追溯任何账户。

MySQL存储在全球的特权mysql.user系统表

数据库权限

数据库权限适用于给定数据库中的所有对象。指定数据库级权限,使用ON db_name.*语法:

授予所有操作*”“”“someuser &#39;somehost;查询、插入操作*”“”“someuser &#39;somehost;

如果你使用ON *语法(而不是*是*),权限在默认数据库数据库级分配。如果没有默认数据库发生错误。

这个CREATEDROPEVENTGRANT OPTIONLOCK TABLES,和REFERENCES权限可以在数据库级别指定。表或常规的特权,也可以在数据库级的规定,在这种情况下,它们适用于所有数据库中的表或例程。

MySQL存储数据库中的特权mysql.db系统表

表的权限

表的权限适用于所有列在一个给定的表。指定表级权限,使用ON db_name.tbl_name语法:

给予所有对mydb.mytbl &#39; someuser”@ &#39;somehost”;查询、插入mydb.mytbl &#39; someuser”@ &#39;somehost”;

如果你指定tbl_name而不是db_name.tbl_name,该声明适用于tbl_name在默认的数据库。如果没有默认数据库发生错误。

允许priv_type在表级值ALTERCREATE VIEWCREATEDELETEDROPGRANT OPTIONINDEXINSERTREFERENCESSELECTSHOW VIEWTRIGGER,和UPDATE

表级权限申请表和视图。他们不申请表的创建CREATE TEMPORARY TABLE,即使表名匹配。有关临时表的特权,看第13.1.18.3,“创建临时表的语法”

MySQL存储表的权利mysql.tables_priv系统表

列的权限

列权限申请单柱在一个给定的表。每个权限被授予在列级必须遵循的一列或多列,封闭在括号内。

GRANT SELECT (col1), INSERT (col1, col2) ON mydb.mytbl TO 'someuser'@'somehost';

允许priv_type一列的值(即,当你使用column_list条款)是INSERTREFERENCESSELECT,和UPDATE

MySQL存储列中的特权mysql.columns_priv系统表

存储程序的权限

这个ALTER ROUTINECREATE ROUTINEEXECUTE,和GRANT OPTION权限应用于存储子程序(过程和函数)。他们可以被授予在全球数据库的水平。除了CREATE ROUTINE,这些权限可以授予个人套路的常规水平。

授予创建常规操作*的someuser”@ &#39;somehost”;授予执行程序mydb.myproc &#39; someuser”@ &#39;somehost”;

允许priv_type在常规水平值ALTER ROUTINEEXECUTE,和GRANT OPTIONCREATE ROUTINE不是常规的特权因为你必须有权在全球或数据库水平首先要创建一个常规。

MySQL存储程序中的特权级mysql.procs_priv系统表

代理权限

这个PROXY权限允许一个用户是一个代理的另一。代理用户假冒或以代理用户的身份;那是,它假设代理用户的权限。

格兰特在localuser代理“localhost externaluser somehost“@”;

什么时候PROXY是理所当然的,它必须是唯一的特权中的命名GRANT声明,并仅允许选项WITH GRANT OPTION

代理要求代理用户认证通过一个插件,返回用户的代理服务器的名称时,代理用户连接,并代理用户有PROXY对于代理的用户权限。对细节和例子,看第6.3.11”代理用户”

MySQL存储代理的权利mysql.proxies_priv系统表

授予角色

GRANT语法没有打开(放)条款授予的角色而不是个人的特权。一个角色是一个名叫集合的特权;看第6.3.4,“角色”。。。。。。。例如:

GRANT 'role1', 'role2' TO 'user1'@'localhost', 'user2'@'localhost';

每个角色都是理所当然的存在,以及每个用户帐户或角色,这是理所当然的。

如果GRANT声明:有选项条款,每个指定的用户可以授予命名的角色给其他用户或角色,或者撤销他们从其他用户或角色。这包括使用能力WITH ADMIN OPTION本身

它可以创建循环引用GRANT。。。。。。。例如:

CREATE USER 'u1', 'u2';CREATE ROLE 'r1', 'r2';GRANT 'u1' TO 'u1';   -- simple loop: u1 => u1GRANT 'r1' TO 'r1';   -- simple loop: r1 => r1GRANT 'r2' TO 'u2';GRANT 'u2' TO 'r2';   -- mixed user/role loop: u2 => r2 => u2

圆形格兰特引用是允许的但不再加入新的权限或角色的人因为一个用户或角色既有其特权和角色。

其他帐户的特点

可选WITH条款是用来使一个用户授予权限的其他用户。这个授予期权条款给用户给其他用户的任何权限的用户在指定的权限级别的能力。

授予GRANT OPTION特权的帐户,而不改变其特权,这样做:

使用*格兰特。*”“”“someuser &#39;somehost授予期权;

要小心那些你给的GRANT OPTION因为两特权用户拥有不同的权限可以将权限!

你不能给另一个用户的特权,你自己没有的;GRANT OPTION权限允许你指定只有你自己拥有的特权。

要知道,当你给一个用户GRANT OPTION在一个特定的特权等级的特权,任何特权用户拥有的(或未来可能会给出),也可以由用户授予其他用户。假设你给一个用户INSERT对数据库的权限。如果你给予的SELECT在数据库和指定的特权授予期权,用户可以给其他用户不仅SELECT特权,但也INSERT。如果你当时格兰特theUPDATE权限对数据库用户,用户可以授予INSERTSELECT,和UPDATE

对于一个非管理员用户,你不应该给予ALTER特权或全球范围内的MySQL系统数据库。如果你这样做,用户可以尝试颠覆特权制度通过重命名的表!

有关特定权限相关的安全风险的更多信息,参见6.2.1节”,privileges提供由mysql”

MySQL和SQL版本的补助标准

MySQL和SQL版本之间最大的差异GRANT是:

  • MySQL公司的特权与主机名和用户名,不只有一个用户名称组合。

  • 标准的SQL没有全球或数据库级权限,也不支持MySQL支持所有类型的特权。

  • MySQL不支持标准的SQLUNDER特权

  • 标准SQL权限结构分层的方式。如果你删除一个用户的所有权限,用户被授予被撤销。这也是如此,如果你使用的MySQLDROP USER。看到第13.7.1.5,“降低用户的语法”

  • 在标准的SQL,当你删除一个表,表的所有权限撤销。在标准的SQL,当你撤销特权,所有的特权被授予基于特权也被撤销。在MySQL中,特权可以下降DROP USERREVOKE声明.

  • 在MySQL数据库中,它是可能的INSERT只有一些列表中的特权。在这种情况下,你仍然可以执行INSERT桌上的报表,只要你插入值只为那些列为你的INSERT特权。省略的列如果严格的SQL模式不启用设置为默认值。严格模式,声明如果省略的列没有默认值的拒绝。(标准的SQL需要你有INSERT在所有列的特权。)关于严格的SQL模式和隐式的默认值的信息,看到第5.1.10,”服务器的SQL模式”,和11.7节,“数据类型的默认值”

13.7.1.7重命名用户语法

RENAME USER old_user TO new_user
    [, old_user TO new_user] ...

这个RENAME USER语句重命名现有的MySQL账户。发生错误,旧帐户不存在或已经存在的新帐户。

使用RENAME USER,你必须有全球CREATE USER特权,或UPDATE特权的MySQL系统数据库。当read_only系统变量是启用,RENAME USER另外需要CONNECTION_ADMINSUPER特权

每个帐户名称使用的格式描述第6.2.4,“指定的帐户名”。。。。。。。例如:

RENAME USER 'jeffrey'@'localhost' TO 'jeff'@'127.0.0.1';

如果省略该帐户名,主机名,默认为'%'

RENAME USER由于老用户认为是由新用户持有的特权。然而,RENAME USER不会自动删除或无效的数据库或对象在他们老用户创建。这包括存储方案或意见,定义者属性名老用户。试图访问这些对象可以定义的安全上下文执行他们产生一个错误。(关于安全上下文信息看,23.6节,“访问控制用于存储程序和视图”。)

特权更改生效如第6.2.8,当特权更改生效”

13.7.1.8撤销语法

REVOKE
    priv_type [(column_list)]
      [, priv_type [(column_list)]] ...
    ON [object_type] priv_level
    FROM user_or_role [, user_or_role] ...

REVOKE ALL [PRIVILEGES], GRANT OPTION
    FROM user_or_role [, user_or_role] ...

REVOKE PROXY ON user_or_role
    FROM user_or_role [, user_or_role] ...

REVOKE role [, role ] ...
    FROM user_or_role [, user_or_role ] ...

user_or_role: {
    user
  | role
}

user:
    (see Section 6.2.4, “Specifying Account Names”)

role:
    (see Section 6.2.5, “Specifying Role Names”.

这个REVOKE语句使系统管理员撤消权限和角色,这可以从用户帐号和角色的撤销。

关于角色,看第6.3.4,“角色”

read_only系统变量是启用,REVOKE要求CONNECTION_ADMINSUPER除了其他必需的特权,在下面的讨论中描述的特权。

REVOKE无论是成功的所有命名的用户和角色或回滚,如果出现任何错误没有影响。声明仅仅是如果它成功的所有命名的用户和角色的二进制日志写。

每个帐户名称使用的格式描述第6.2.4,“指定的帐户名”。每个角色名称使用的格式描述第6.2.5,“指定角色的名字”。。。。。。。例如:

REVOKE INSERT ON *.* FROM 'jeffrey'@'localhost';
REVOKE 'role1', 'role2' FROM 'user1'@'localhost', 'user2'@'localhost';
REVOKE SELECT ON world.* FROM 'role3';

如果省略该帐户或角色名,主机名,默认为'%'

在这特权存在的层次细节,允许priv_typepriv_level,和object_type值,用于指定用户和密码的语法,看第13.7.1.6,”格兰特语法”

第一次使用REVOKE语法,你必须GRANT OPTION特权,你必须有你撤销特权。

撤销所有的特权,使用第二语法,这滴所有全局、数据库、表、列、和指定的用户或角色常规的特权:

REVOKE ALL PRIVILEGES, GRANT OPTION
  FROM user_or_role [, user_or_role] ...

REVOKE ALL PRIVILEGES, GRANT OPTION不撤销任何角色

使用这个REVOKE语法,你必须有全球CREATE USER特权,或UPDATE特权的MySQL系统数据库

the syntax for which theREVOKE关键词是由一个或多个角色的名字是条款说明撤销角色的一个或多个用户或角色。

角色命名的mandatory_roles系统变量的值不能被撤销。

被撤销的作用直接影响到任何用户帐户从它被撤销,这样在任何当前会话的账户,其权限调整为下表执行。

撤销作用解除自身的角色,不是它所代表的特权。如果一个帐户被授予角色包含一个给定的权限,并授予权限明确或另一个角色,包括特权的帐户,还被授予特权后的第一个角色是撤销。例如,如果一个帐户被授予角色的每一个包括两SELECT,客户还可以选择要么被撤销后的作用。

REVOKE ALL ON *.*(在全球层面)撤销所有批准的静态全局特权和所有动态权限授予。

从特权和角色要撤销必须存在用户帐号和角色,但角色被撤销不需要现在给他们。

REVOKE删除的权限,但不降mysql.user表条目。要删除用户帐户完全使用DROP USER。看到第13.7.1.5,“降低用户的语法”

如果授权表行持有特权包含混合的情况下的数据库或表的名称和lower_case_table_names系统变量设置为非零值,REVOKE不可撤销这些特权。这将是必要的授权表直接操纵。(GRANT不会产生这样的行时lower_case_table_names是集,但这样的行可能已经设置变量之前创建的。这个lower_case_table_names设置只能配置初始化服务器时。)

当执行成功的从MySQL程序,REVOKE响应查询好,为受影响的行。确定什么特权保持术后使用SHOW GRANTS。看到第13.7.6.21”节目,格兰特的语法”

13.7.1.9设置默认角色的语法

SET DEFAULT ROLE
    {NONE | ALL | role [, role ] ...}
    TO user [, user ] ...

对于每个user命名后立即关键词,这个语句定义的角色变得活跃,当用户连接到服务器,认证,或用户执行时SET ROLE DEFAULT在会议上发言

SET DEFAULT ROLE是替代语法ALTER USER ... DEFAULT ROLE(见第13.7.1.1,“改变用户的语法”页:1不过ALTER USER对于只有一个用户设置默认值,而SET DEFAULT ROLE可以为多个用户设置默认。另一方面,你可以指定current_user当用户的名称ALTER USER声明,而你不能SET DEFAULT ROLE

SET DEFAULT ROLE需要这些特权:

  • 设置为另一个用户的默认角色需要全球CREATE USER特权,或UPDATE特权的mysql.default _角色系统表

  • 为自己设置默认的角色不需要特殊的权限,只要你想要作为默认的角色已经给你。

每个角色名称使用的格式描述第6.2.5,“指定角色的名字”。。。。。。。例如:

SET DEFAULT ROLE administrator, developer TO 'joe'@'10.0.0.1';

如果省略的角色名,主机名,默认为'%'

以下条款的DEFAULT ROLE关键词允许这些值:

  • NONE:设置默认(没有作用)

  • ALL:设置默认的帐户授予的所有角色。

  • role [, role ] ...:设置默认的命名的角色,不存在或被授予该帐户的时候SET DEFAULT ROLE执行

笔记

SET DEFAULT ROLESET ROLE DEFAULT不同的报表:

13.7.1.10设置密码的语法

SET PASSWORD [FOR user] = 'auth_string' [REPLACE 'current_auth_string']

这个SET PASSWORD声明中指定一个密码,MySQL的用户帐户。&#39;auth_string&#39;代表一个明文密码(加密)。

如果给定的REPLACE条款(可作为MySQL 8.0.13),必须要更换指定当前帐户的密码:

  • 该条款必须如果账户密码修改必须指定当前密码,验证的用户试图做出改变,真的知道当前密码。

  • 子句是可选的如果账户密码修改可以但不需要指定当前密码。

  • 如果条款给予但不当前密码匹配语句失败,即使子句是可选的。

  • REPLACE可以指定只有转化为当前用户的帐户密码。

有关密码验证的更多信息通过指定的当前密码,看第6.3.8,“密码管理”

笔记

而不是使用SET PASSWORD ... = 'auth_string'语法,ALTER USER语法是账户变化的优先声明,包括指定密码。例如:

修改用户user经”auth_string&#39;;
重要

在某些情况下,SET PASSWORD可记录在服务器日志或在客户端在历史文件等历史.mysql _ ~,这意味着明文密码可以由任何人具有读访问,读取信息。有关信息的条件下,出现这种服务器日志和如何控制它,看第6.1.2.3,“密码登录”。关于客户端登录类似的信息,参见第4.5.1.3,“MySQL日志”

SET PASSWORD可用于有或没有条款明确名称的用户帐户:

  • 用一个FOR user条款,声明指定的帐户设置密码,它必须存在:

    SET PASSWORD FOR 'jeffrey'@'localhost' = 'auth_string&#39;;
  • 没有FOR user条款,声明为当前用户设置密码:

    SET PASSWORD = 'auth_string&#39;;

    任何客户端连接到服务器可以使用匿名帐户,帐户的密码更改。(特别是,你可以改变自己的密码。)看你的帐户服务器认证,调用CURRENT_USER()功能:

    选择current_user();

如果语句是改变当前用户的密码,这REPLACE条款可以满足任何要求做出改变的用户知道当前密码。如果一个帐户名为但不是当前用户的更换条款不能给予

设置指定帐户的密码(一FOR条款)要求UPDATE特权的MySQL系统数据库。为你自己设定的密码(一个匿名帐户没有FOR条款)不需要特殊的权限。当read_only系统变量是启用,SET PASSWORD要求CONNECTION_ADMINSUPER除了所需的任何其他特权的特权。

如果一个FOR user条款,账户名称使用的格式描述第6.2.4,“指定的帐户名”。。。。。。。例如:

SET PASSWORD FOR 'bob'@'%.example.org' = 'auth_string';

如果省略该帐户名,主机名,默认为'%'

SET PASSWORD将字符串作为明文字符串,通过它与帐户相关的认证插件,并将结果返回在插件mysql.user开户行。(插件有机会哈希值为加密格式预计。插件可以使用价值的规定,在这种情况下,没有哈希的发生。)

更多信息关于设置密码和身份验证插件,看第6.3.7,“分配账号密码”,和第6.3.10,“认证”

13.7.1.11集的句法角色

SET ROLE
    {
        DEFAULT
      | NONE
      | ALL
      | ALL EXCEPT role [, role ] ...
      | role [, role ] ...
    }

SET ROLE修改当前用户的有效权限在当前会话指定其授予的角色是积极的。授予角色包括那些显式授予给用户,这些命名的mandatory_roles系统变量价值

特权用户被授予直接(而不是通过角色)的主动角色的变化不受影响。

每个角色名称使用的格式描述第6.2.5,“指定角色的名字”。。。。。。。例如:

SET ROLE DEFAULT;
SET ROLE 'role1', 'role2';
SET ROLE ALL;
SET ROLE ALL EXCEPT 'role1', 'role2';

如果省略的角色名,主机名,默认为'%'

声明说明符允许这些角色:

  • DEFAULT激活默认账户的作用。默认的角色是那些指定SET DEFAULT ROLE

    当一个用户连接到服务器和认证服务器成功,决定哪个角色为默认角色激活。如果activate_all_roles_on_login系统变量是启用的服务器激活所有授予的角色。否则,服务器执行SET ROLE DEFAULT隐式。服务器激活默认的角色,可以激活。服务器写警告默认角色无法启动的错误日志,但客户没有收到警告。

    如果用户执行SET ROLE DEFAULT在会话期间,如果任何默认的作用不能被激活发生错误(例如,如果它不存在或不授予用户)。在这种情况下,不改变当前的积极作用。

  • NONE设置活动的作用:(没有积极作用)

  • ALL授予:激活帐户的所有角色。

  • ALL EXCEPT role [, role ] ...:激活授予帐户除命名所有的角色。指定的角色不存在或被授予该帐户。

  • role [, role ] ...:激活指定的角色,必须给予考虑。

笔记

SET DEFAULT ROLESET ROLE DEFAULT不同的报表:

13.7.2资源集团管理报表

MySQL支持的资源组的创建和管理,并允许分配的线程运行在服务器上的特定群体,线程执行根据可用的资源组。本节描述了可用的资源组管理的SQL语句。为资源组能力一般的讨论,见第8.12.5,“资源组”

13.7.2.1改变资源组的语法

ALTER RESOURCE GROUP group_name
    [VCPU [=] vcpu_spec [, vcpu_spec] ...]
    [THREAD_PRIORITY [=] N]
    [ENABLE|DISABLE [FORCE]]

vcpu_spec: {N | M - N}

ALTER RESOURCE GROUP用于资源组管理(见第8.12.5,“资源组”)。这句话改变了一个现有的资源组的属性。它要求RESOURCE_GROUP_ADMIN特权

group_name标识要改变资源组。如果组不存在,发生了一个错误。

属性为CPU亲和性,优先级,和组是否启用可修饰ALTER RESOURCE GROUP。这些属性是相同的方式描述CREATE RESOURCE GROUP(见第13.7.2.2,“创建资源组句法”)。只有指定的属性的改变。未指定的属性保留其当前值。

这个FORCE改性剂的使用禁用。它决定了陈述行为如果资源组分配给它的任何线程:

  • 如果FORCE不,在集团现有的线程继续运行,直到结束,但新的线程不能被分配到组。

  • 如果FORCE是给定的,在集团现有的线程被移动到各自的默认组(系统线程失误用户线程,USR_default

的名称和类型属性设置组的创建时间和不能被修改之后ALTER RESOURCE GROUP

实例:

  • 改变一组CPU亲和力:

    ALTER RESOURCE GROUP rg1 VCPU = 0-63;
    
  • 改变一组线程优先级:

    ALTER RESOURCE GROUP rg2 THREAD_PRIORITY = 5;
    
  • 禁用组、移动任何线程分配给它的默认组:

    ALTER RESOURCE GROUP rg3 DISABLE FORCE;
    

资源组管理本地服务器对它发生。ALTER RESOURCE GROUP陈述并非写入二进制日志,则不复制。

13.7.2.2创建资源组的语法

CREATE RESOURCE GROUP group_name
    TYPE = {SYSTEM|USER}
    [VCPU [=] vcpu_spec [, vcpu_spec] ...]
    [THREAD_PRIORITY [=] N]
    [ENABLE|DISABLE]

vcpu_spec: {N | M - N}

CREATE RESOURCE GROUP用于资源组管理(见第8.12.5,“资源组”)。这个语句创建新的资源组分配初始属性值。它要求RESOURCE_GROUP_ADMIN特权

group_name标识创建资源组。如果该组已存在,发生了一个错误。

这个TYPE属性是必需的。它应该是系统一个系统的资源组,USER一个用户资源组。集团型影响允许thread_priority值,为后面介绍

这个VCPU属性指示CPU亲和力;即虚拟设定CPU的组可以使用:

  • 如果VCPU不给,资源组没有CPU的亲和力和可以使用所有可用的CPU。

  • 如果VCPU给出,属性值是一个列表,以逗号分隔的CPU数量或范围:

    • 每一个数必须是整数的范围从0到1的CPU数量?。例如,在64个CPU的系统,数的范围可以从0到63。

    • 一个范围的形式给出M?N,在那里M小于或等于N和两个数字都是在CPU的范围。

    • 如果一个CPU数是整数超出允许范围或不是整数,出现错误。

例子VCPU说明符(这些都是等价的):

VCPU = 0,1,2,3,9,10VCPU = 0-3,9-10VCPU = 9,10,0-3VCPU = 0,10,1,9,3,2

这个THREAD_PRIORITY属性表示分配给该组的线程的优先级:

  • 如果THREAD_PRIORITY没有给出,默认优先级为0。

  • 如果THREAD_PRIORITY给出,属性值必须在范围从20(最高优先级)到19(最低优先级)。系统资源组的优先级必须在范围从20到0。用户资源组的优先级必须在范围从0到19。系统和用户群体的不同范围的使用确保用户线程不会比系统线程优先级更高。

ENABLE禁用指定资源组最初是启用或禁用。如果没有指定,默认是启用的组。一个残疾组不能给它分配的线程。

实例:

  • 创建一个启用的用户组,单CPU和最低优先级:

    CREATE RESOURCE GROUP rg1
      TYPE = USER
      VCPU = 0
      THREAD_PRIORITY = 19;
    
  • 创建一个禁用系统组没有CPU亲和性(可以使用所有的CPU)和最高优先级:

    CREATE RESOURCE GROUP rg2
      TYPE = SYSTEM
      THREAD_PRIORITY = -20
      DISABLE;
    

资源组管理本地服务器对它发生。CREATE RESOURCE GROUP陈述并非写入二进制日志,则不复制。

13.7.2.3滴资源组的语法

DROP RESOURCE GROUP group_name [FORCE]

DROP RESOURCE GROUP用于资源组管理(见第8.12.5,“资源组”)。这一声明滴资源组。它要求RESOURCE_GROUP_ADMIN特权

group_name确定下降,资源组。如果组不存在,发生了一个错误。

这个FORCE改性剂确定陈述行为如果资源组分配给它的任何线程:

  • 如果FORCE没有给出任何线程被分配到组,发生了一个错误。

  • 如果FORCE是给定的,在集团现有的线程被移动到各自的默认组(系统线程失误用户线程,USR_default

实例:

  • 滴一组,不包含任何线程如果组:

    DROP RESOURCE GROUP rg1;
    
  • 滴一组和移动现有的线程的默认组:

    DROP RESOURCE GROUP rg2 FORCE;
    

资源组管理本地服务器对它发生。DROP RESOURCE GROUP陈述并非写入二进制日志,则不复制。

13.7.2.4设置资源组的语法

SET RESOURCE GROUP group_name
    [FOR thread_id [, thread_id] ...]

SET RESOURCE GROUP用于资源组管理(见第8.12.5,“资源组”)。这一声明分配线程的资源组。它要求RESOURCE_GROUP_ADMINRESOURCE_GROUP_USER特权

group_name确定要分配的资源组。任何thread_id值指示线程分配到组。线程ID可以从绩效模式确定threads表如果资源组或任何指定的线程ID不存在,发生了一个错误。

没有FOR条款,声明将当前线程会话资源组。

用一个FOR条款名称的线程ID,声明指定那些线程的资源组。

对于试图分配一个系统线程的用户资源组或用户线程的系统资源组,一个警告出现。

实例:

  • 指定当前会话线程组:

    SET RESOURCE GROUP rg1;
    
  • 分配指定的线程组:

    SET RESOURCE GROUP rg2 FOR 14, 78, 4;
    

资源组管理本地服务器对它发生。SET RESOURCE GROUP陈述并非写入二进制日志,则不复制。

一种替代SET RESOURCE GROUP是的resource_group优化器提示,其个别报表资源组。看到第8.9.2,“优化器提示”

13.7.3表维护报表

13.7.3.1语法分析表

ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]
    TABLE tbl_name [, tbl_name] ...

ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]
    TABLE tbl_name
    UPDATE HISTOGRAM ON col_name [, col_name] ...
        [WITH N BUCKETS]

ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]
    TABLE tbl_name
    DROP HISTOGRAM ON col_name [, col_name] ...

ANALYZE TABLE生成统计表:

  • ANALYZE TABLE没有直方图条款执行密钥分布分析和存储指定的表或表的分布。为MyISAM桌子,ANALYZE TABLE重点分析相当于使用myisamchk -分析

  • ANALYZE TABLE更新直方图条款指定的表列,并将它们存储在数据字典生成直方图统计。只有一个表的名称是这个语法允许。

  • ANALYZE TABLE下降的直方图条款删除指定的表列数据字典直方图统计。只有一个表的名称是这个语法允许。

笔记

如果innodb_read_only系统变量是启用,ANALYZE TABLE可能会失败,因为它不能在数据字典更新统计表,并使用InnoDB。为ANALYZE TABLE操作更新密钥分配,即使操作更新表本身可能出现故障(例如,如果它是一个MyISAM表)。为了获得更新的统计分布,集information_schema_stats_expiry=0

这句话的要求SELECTINSERTprivileges *表。

ANALYZE TABLE作品InnoDBNDB,和MyISAM表它不工作的意见

ANALYZE TABLE是分区表支持,您可以使用修改表…分析分区分析一个或多个分区;有关更多信息,参见第13.1.8,“ALTER TABLE语法”,和第22.3.4,“维护分区”

在分析过程中,桌上一把读锁InnoDBMyISAM

默认情况下,服务器写ANALYZE TABLE报表的二进制日志,复制到复制的奴隶。抑制测井,指定可选no_write_to_binlog关键词或其别名LOCAL

分析表的输出

ANALYZE TABLE返回一个结果集与下表中显示的列。

专栏价值
Table表名
Opanalyze直方图
Msg_typestatus错误info笔记,或warning
Msg_text信息性消息
密钥分配分析

ANALYZE TABLE没有直方图条款执行密钥分布分析和存储表或表的分布。任何现有的直方图统计不受影响。

如果表没有最后关键的分布改变,该表不能再分析。

MySQL使用存储的密钥分配决定的顺序表应该加入到其它事情上,不断的加入。此外,重点分布可以用来决定使用一个特定的表在查询的索引。

有关如何工作的更多信息在密钥分配分析InnoDB,看到第15.6.11.1”配置,持续优化统计参数第15.6.11.3,“估计分析表的复杂性InnoDB表”。也看到了第15.8.1.7”限制,InnoDB表”。特别是,当你使innodb_stats_persistent选项,您必须运行ANALYZE TABLE在加载大量数据为InnoDB表,或创建一个新的指标之一。

检查存储的密钥分配基数,使用SHOW INDEX声明或INFORMATION_SCHEMA.STATISTICS表看到第13.7.6.22,显示指数的语法”,和部分二千四百二十三,“information_schema统计表”

直方图统计分析

ANALYZE TABLE直方图条款使直方图统计管理表列值。关于直方图的统计信息,看第8.9.6,“优化统计”

这些直方图操作都可以:

  • ANALYZE TABLE一个更新直方图条款指定的表列,并将它们存储在数据字典生成直方图统计。只有一个表的名称是这个语法允许。

    可选WITH N BUCKETS条款specifies the number of buckets for the直方图。the value ofN必须是一个整数的范围从-1到1024。如果这一条款被省略,桶的数量为100。

  • ANALYZE TABLE用一个下降的直方图条款删除指定的表列数据字典直方图统计。只有一个表的名称是这个语法允许。

存储直方图管理报表只影响指定的列。考虑到这些语句:

ANALYZE TABLE t UPDATE HISTOGRAM ON c1, c2, c3 WITH 10 BUCKETS;
ANALYZE TABLE t UPDATE HISTOGRAM ON c1, c3 WITH 10 BUCKETS;
ANALYZE TABLE t DROP HISTOGRAM ON c2;

第一个语句更新列的直方图c1C2,和c3,这些列替换现有的直方图。第二个语句更新直方图C1c3,离开C2直方图的影响。第三语句删除的直方图c2,留下那些C1c3不受影响

直方图生成不支持加密的表(避免暴露在统计数据)或TEMPORARY

直方图生成适用于所有的数据类型的列除了几何类型(空间数据)和JSON

直方图可以存储和虚拟生成的列生成。

直方图不能为所覆盖的单柱唯一索引的列生成。

直方图管理报表尝试执行尽可能多的请求的操作,和其余的报告诊断消息。例如,如果一个UPDATE HISTOGRAM声明的名字多个列,但他们中的一些人不存在或不支持的数据类型,直方图是对其他列生成的消息产生了无效的列。

这个histogram_generation_max_mem_size系统变量控制可用直方图生成的最大内存量。全球和会话的值可以在运行时设置。这个SYSTEM_VARIABLES_ADMINSUPER特权是必须的,即使对于会议的价值。

有关内存分配进行直方图生成信息,监控性能模式memory/sql/histograms仪器看到第25.11.15.10,“记忆汇总表”

直方图是由这些DDL语句的影响:

  • DROP TABLE将直方图的列中删除的表。

  • DROP DATABASE将直方图中的任何表下降数据库因为语句删除数据库中的所有表。

  • RENAME TABLE不排除直方图。相反,它重命名为重命名的表与新表名称相关的直方图。

  • ALTER TABLE语句删除或修改列删除该列直方图。

  • ALTER TABLE ... CONVERT TO CHARACTER SET删除字符列的直方图,因为它们是由字符集的变化影响。直方图的字符列不受影响。

13.7.3.2检查表的语法

CHECK TABLE tbl_name [, tbl_name] ... [option] ...

option = {
    FOR UPGRADE
  | QUICK
  | FAST
  | MEDIUM
  | EXTENDED
  | CHANGED
}

CHECK TABLE检查表的错误CHECK TABLE还可以检查意见的问题,如表中引用的视图定义不再存在。

检查表,你必须有一些特权吧。

CHECK TABLE作品InnoDBMyISAMARCHIVE,和CSV

在跑步前CHECK TABLE打开(放)InnoDB表,看检查表的使用InnoDB表注释

CHECK TABLE是分区表支持,您可以使用修改表…检查分区检查一个或多个分区;有关更多信息,参见第13.1.8,“ALTER TABLE语法”,和第22.3.4,“维护分区”

CHECK TABLE忽略了虚拟生成的列没有被索引。

检查表的输出

CHECK TABLE返回一个结果集与下表中显示的列。

专栏价值
Table表名
Op总是check
Msg_typestatus错误info笔记,或warning
Msg_text信息性消息

声明可能产生的每个检查信息表的许多行。最后一排有一个Msg_type价值地位Msg_text通常应好啊Table is already up to date意味着该表的存储引擎,无需查表。

检查版本兼容性

这个FOR UPGRADE选择检查是否指定表与MySQL的当前版本兼容。与升级,服务器检查每个表以确定是否有任何的表的数据类型或指标自表产生任何不兼容的改变。如果没有,检查成功。否则,如果有可能不兼容,服务器运行在桌子上全检查(这可能需要一些时间)。

不可能发生,因为一个数据类型的存储格式或已改变,因为它的排序顺序改变了。我们的目标是避免这些变化,但偶尔也有必要纠正存在的问题,将比之间释放不差。

FOR UPGRADE发现这些不兼容:

检查数据的一致性

下表显示其他选项,可以检查。这些选项传递给存储引擎,可使用或忽视他们。

类型意义
QUICK不扫描行检查错误的链接。适用于InnoDBMyISAM表和视图
FAST只检查没有正确关闭表。忽略InnoDB;仅适用于MyISAM表和视图
CHANGED只检查已自上次检查或未正确关闭变化表。忽略InnoDB;仅适用于MyISAM表和视图
MEDIUM扫描行确认删除链接是否有效。这也算为行校验和验证这一关键计算校验和的钥匙。忽略InnoDB;仅适用于MyISAM表和视图
EXTENDED做为每一行的所有钥匙全键查找。这确保了表100%一致,但需要很长的时间。忽略InnoDB;仅适用于MyISAM表和视图

你可以结合检查选项,如下面的示例,并在桌上快速检查以确定它是否被正确关闭:

CHECK TABLE test_table FAST QUICK;
笔记

如果CHECK TABLE发现了一个表,注明没有问题损坏没有正确关闭CHECK TABLE可以删除标记

如果表损坏,问题很可能出在指标和不在数据部分。上述所有检查类型检查指标彻底从而找到最错误。

检查表,你认为是好的,没有检查选项或使用QUICK选项后者应该是当你在赶时间,能以很小的风险,没有找到数据文件中的错误。(在大多数情况下,正常使用情况下,MySQL应该找到数据文件中的所有错误。如果发生这种情况,表中被标记为损坏不能用直到它被修复。)

FAST改变主要的目的是从一个脚本(例如,被执行cron)定期检查表。在大多数情况下,FAST是要优于改变。(唯一的情况下它是不可取的是当你觉得你已经发现的bugMyISAM代码。)

EXTENDED仅适用于当你运行一个正常的检查,但仍然得到错误从表当MySQL试图更新一行或一行的关键发现。如果一个正常的检查已经成功,这是非常不可能的。

使用CHECK TABLE ... EXTENDED可能会影响查询优化器生成的执行计划。

一些问题的报告CHECK TABLE不能自动校正:

  • Found row where the auto_increment column has the value 0

    这意味着你有一个排在桌上AUTO_INCREMENT索引列包含的值为0。(有可能创建一个行的地方汽车0列是通过显式设置的柱0个UPDATE声明。)

    这不是一个错误的本身,但是如果你决定把表和恢复它或做一个引起麻烦ALTER TABLE上表。在这情况下,汽车列的值改变根据规则AUTO_INCREMENT列,这可能会导致诸如重复键错误的问题。

    摆脱了警告,执行UPDATE语句设置列的其他一些价值超过0。

检查表的使用InnoDB表注释

以下说明适用于InnoDB

  • 如果CHECK TABLE遇到了一个腐败的页面,服务器退出,防止错误传播(bug # 10132)。如果腐败发生在一次索引但表数据的可读性,运行CHECK TABLE还可以使服务器退出

  • 如果CHECK TABLE遇到损坏_ TRX _ DB IDDB_ROLL_PTR聚集索引中的字段,CHECK TABLE可引起InnoDB访问一个无效的撤销日志记录,从而导致MVCC相关的服务器退出

  • 如果CHECK TABLE中遇到的错误InnoDB表或索引,它报告了一个错误,通常标志着指数有时是表损坏,防止进一步使用索引或表。这些错误包括条目数量不正确或不正确的连接在一次索引。

  • 如果CHECK TABLE发现在二级指标条目不正确,则将报告错误但不引起服务器退出或阻止访问文件。

  • CHECK TABLE调查指标的页面结构,然后测量各关键项。它不验证的关键指针聚集记录或跟踪路径BLOB指针

  • 当一个InnoDB表存储在其自己的.ibd文件第三,网页.ibd包含文件头信息而不是表或索引数据。这个CHECK TABLE声明中没有检测到不一致,仅对标题数据。验证的全部内容InnoDB.ibd的文件,使用的innochecksum命令

  • 当运行CHECK TABLE在大InnoDB表,其他线程可能被封锁在CHECK TABLE执行.避免超时、信号量等阈值(600秒)是由2小时延长(7200秒)为CHECK TABLE运营如果InnoDB检测到的信号量等待240秒以上,它开始打印InnoDB监视器输出到错误日志。如果一个锁请求超出阈值信号等,InnoDB流产的过程。为了避免一个信号量等待超时完全的可能性,跑CHECK TABLE QUICK而不是CHECK TABLE

  • CHECK TABLE功能InnoDBSPATIAL指标包括R树的有效性检查和检查以确保索引行计数与聚集索引。

  • CHECK TABLE支持二级指标虚拟生成的列,这是支持的InnoDB

检查表使用MyISAM表注释

以下说明适用于MyISAM

  • CHECK TABLE关键统计数据更新MyISAM

  • 如果CHECK TABLE输出不返回好啊Table is already up to date通常,你应该运行一个修表。看到第7,“MyISAM表的维护和故障恢复”

  • 如果没有的CHECK TABLE选项MEDIUM,或扩展被指定,动态格式的默认检查类型MyISAM介质。这一结果为运行myisamchk中检查tbl_name在桌子上。默认的检查类型也介质静态格式MyISAM表,除非改变FAST指定。在这种情况下,默认是。行扫描跳过CHANGED因为行很少损坏

13.7.3.3校验表的语法

CHECKSUM TABLE tbl_name [, tbl_name] ... [QUICK | EXTENDED]

CHECKSUM TABLE报告校验和对于一个表的内容。你可以用这句话来验证的内容是相同的前一个备份,回滚后,或其他操作的目的是将数据返回到一个已知的状态。

这句话需要SELECT特权的表

这种说法是不支持的观点。如果你运行CHECKSUM TABLE对视图的校验和价值总是NULL,并警告返回

对于一个不存在的表,CHECKSUM TABLE退货无效的并生成一个警告

校验和操作过程中,桌上一把读锁InnoDBMyISAM

业绩考量

默认情况下,整个表读取的行的行和校验和计算。对于大型的表,这可能需要很长的时间,因此你只能偶尔执行此操作。这一排排的计算是你的EXTENDED条款,以InnoDB和所有其他存储引擎以外MyISAM,和MyISAM有没有创建表CHECKSUM=1条款.

MyISAM创建表CHECKSUM=1条款,CHECKSUM TABLECHECKSUM TABLE ... QUICK返回直播表校验,可以恢复很快。如果表不满足这些条件的QUICK方法返回无效的。这个QUICK方法不支持InnoDB表。这第13.1.18,“创建表的语法对语法CHECKSUM条款.

校验值取决于表的行格式。如果行格式的变化,校验也改变。例如,时态类型如存储格式TIMEDATETIME,和TIMESTAMP改变了在MySQL 5.6 MySQL 5.6.5之前,所以如果5.5台升级到MySQL 5.6,校验值可能会改变。

重要

如果两个表校验和不同,那么几乎可以肯定的是,表是在一些不同的方式。然而,因为散列函数的使用CHECKSUM TABLE不能保证无碰撞,有微小的机会,两表不相同,可以产生相同的校验。

13.7.3.4优化表的语法

OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL]
    TABLE tbl_name [, tbl_name] ...

OPTIMIZE TABLE整理表中数据的物理存储和相关指标数据,减少存储空间和提高I/O效率访问表时。为每个表取决于确切的变化存储引擎由表

使用OPTIMIZE TABLE在这些情况下,根据表的类型:

  • 在做大量的插入、更新或删除操作上,InnoDB表,有自己的IBD文件因为它是创造的innodb_file_per_table启用选项。表和索引进行重组,和磁盘空间可以回收使用的操作系统。

  • 在做大量的插入、更新或删除操作,是一列FULLTEXT指数在InnoDB表。设置配置选项innodb_optimize_fulltext_only=1第一保持指数维持期到一个合理的时间,设置innodb_ft_num_word_optimize选项指定多少字更新搜索索引,并运行一个序列优化表报表直到搜索指数是全面更新。

  • 删除一个大的一部分后MyISAM资料库表,或使许多更改为MyISAM资料库可变长度列表(表中有VARCHARVARBINARYBLOB,或TEXT列)。已删除的行保存在一个链表和随后的INSERT业务复用旧行的位置。你可以使用OPTIMIZE TABLE回收未使用的空间和整理数据文件。后一桌的丰富变化,这句话也可以提高报表使用的表,有时明显。

这句话的要求SELECTINSERTprivileges *表。

OPTIMIZE TABLE作品InnoDBMyISAM,和ARCHIVE

默认情况下,OPTIMIZE TABLE工作表创建使用其他存储引擎和返回的结果表明这种缺乏支持。你可以做OPTIMIZE TABLE从其他存储引擎的工作mysqld--skip-new期权。在这房子,OPTIMIZE TABLE只是映射到ALTER TABLE

这份声明没有工作的意见。

OPTIMIZE TABLE是分区表支持。有关使用此表分区表和分区表信息,看第22.3.4,“维护分区”

默认情况下,服务器写OPTIMIZE TABLE报表的二进制日志,复制到复制的奴隶。抑制测井,指定可选no_write_to_binlog关键词或其别名LOCAL

优化表的输出

OPTIMIZE TABLE返回一个结果集与下表中显示的列。

专栏价值
Table表名
Op总是optimize
Msg_typestatus错误info笔记,或warning
Msg_text信息性消息

OPTIMIZE TABLE表接球和投球发生表统计数据从旧的文件复制到新创建的文件时的任何错误。例如.如果对所有者的用户IDMVD.MYI文件是由不同的用户IDmysqld过程,OPTIMIZE TABLE生成一个“文件”的错误不能改变所有权,除非mysqld开始的root用户

InnoDB的细节

InnoDB桌子,OPTIMIZE TABLE映射到ALTER TABLE ... FORCE,并重建表更新聚集索引的索引统计和未使用的空间。这是在输出显示OPTIMIZE TABLE当你运行在一个InnoDB表,如下所示:

mysql> OPTIMIZE TABLE foo;
+----------+----------+----------+-------------------------------------------------------------------+
| Table    | Op       | Msg_type | Msg_text                                                          |
+----------+----------+----------+-------------------------------------------------------------------+
| test.foo | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.foo | optimize | status   | OK                                                                |
+----------+----------+----------+-------------------------------------------------------------------+

OPTIMIZE TABLE使用在线DDL定期和分区InnoDB表,从而降低了并行DML操作的停机时间。表重建引发的OPTIMIZE TABLE行下盖ALTER TABLE ... FORCE完成到位。独占表锁只是被简单在准备阶段和实施阶段的工作。在准备阶段,元数据的更新和中间表的创建。在提交阶段,表的元数据更新。

OPTIMIZE TABLE重建表使用表的复制方法,在以下条件下:

OPTIMIZE TABLE使用在线DDL不支持InnoDB表包含全文指标。表复制的方法代替。

InnoDB存储数据使用的页分配法和不受传统的存储引擎一样的碎片(如MyISAM)将。当考虑是否运行优化,考虑交易,您的服务器将处理的工作量:

MyISAM的细节

MyISAM桌子,OPTIMIZE TABLE工作原理如下:

  1. 如果表已删除或分割行,修表。

  2. 如果索引页没有排序,排序。

  3. 如果表中的数据是不是最新的(和无法修复的分类索引,更新完成)。

其他的考虑

OPTIMIZE TABLE进行在线定期分区InnoDB表。否则,MySQL锁表在时间OPTIMIZE TABLE运行

OPTIMIZE TABLE不按R树索引,如空间索引专栏(错误# 23578)

13.7.3.5修表的语法

REPAIR [NO_WRITE_TO_BINLOG | LOCAL]
    TABLE tbl_name [, tbl_name] ...
    [QUICK] [EXTENDED] [USE_FRM]

REPAIR TABLE修复可能损坏的表,只有特定的存储引擎。

这句话的要求SELECTINSERTprivileges *表。

虽然你通常不应该跑REPAIR TABLE,如果灾难来临,这种说法是回到您的所有数据从一个很有可能的MyISAM表如果你的表已损坏的时候,试图找到它的原因,消除了需要使用REPAIR TABLE。看到第b.5.3.3,“做什么如果MySQL总是死机”,和第16.2.4,“MyISAM表的问题”

REPAIR TABLE检查表是否需要升级。如果是这样的话,它执行升级,遵循同样的规则CHECK TABLE ... FOR UPGRADE。看到第13.7.3.2,“检查表语法”为更多的信息

重要
  • 执行表修复手术前使一个表的备份;在某些情况下的操作可能会导致数据丢失。可能的原因包括但不限于文件系统错误。看到第七章,备份和恢复

  • 如果在服务器崩溃REPAIR TABLE操作,它重新启动后,你的另一个关键是立即执行REPAIR TABLE为表表上执行任何其他操作之前。在最坏的情况下,你可能会有一个新的干净的索引文件没有关于数据文件的信息,然后下一步你做能覆盖数据文件。这是一个不太可能的但可能发生的情况,强调了第一次备份的价值。

  • 如果在一个在主损坏表和你跑REPAIR TABLE上,由此产生的任何改变原来的表传播到奴隶

表的存储引擎和分区支持修复

REPAIR TABLE作品MyISAMARCHIVE,和CSV表为MyISAM表,它具有相同的效果myisamchk -恢复tbl_name默认情况下。这份声明没有工作的意见。

REPAIR TABLE是分区表支持。然而,这使用_ FRM选择cannot be used with this statement我们partitioned表。

你可以使用ALTER TABLE ... REPAIR PARTITION修复一个或多个分区;有关更多信息,参见第13.1.8,“ALTER TABLE语法”,和第22.3.4,“维护分区”

修表的选择
  • NO_WRITE_TO_BINLOG当地

    默认情况下,服务器写REPAIR TABLE报表的二进制日志,复制到复制的奴隶。抑制测井,指定可选no_write_to_binlog关键词或其别名LOCAL

  • QUICK

    如果你使用QUICK选项,REPAIR TABLE试图修复唯一索引文件,而不是数据文件。这种修复是这样做的myisamchk -恢复-快速

  • EXTENDED

    如果你使用EXTENDED选项,MySQL创建指标排排而不是在排序的时间创建一个索引。这种修复是这样做的myisamchk --安全恢复

  • USE_FRM

    这个USE_FRM选项可供使用,如果。我索引文件丢失或如果它的头被损坏。这个选项告诉MySQL不在信任的信息.MYI文件头和重新创建它使用的数据字典信息。这种修复不能做myisamchk

    注意安全

    使用USE_FRM选项只有如果你不能用普通的REPAIR模式。告诉服务器忽略。我文件是重要的表的元数据存储在.MYI无法修复的过程中,会产生有害的后果:

    • 目前AUTO_INCREMENT失去价值

    • 表中删除的记录丢失的链接,这意味着删除记录的自由空间将保持空之后。

    • 这个.MYI头指示表压缩。如果服务器忽略这个信息,它不能告诉一个表被压缩和修复会导致表格内容的改变或丧失。这意味着,使用_ FRM不应使用压缩表。这不应该是必要的,总之:压缩表是只读的,所以他们不应该成为腐败。

    如果你使用USE_FRM一个表是由一个不同版本的MySQL服务器比你目前的运行创造了,REPAIR TABLE不尝试修复表。在这种情况下,返回的结果集REPAIR TABLE包含一行msg_type价值error和一个味精_文本价值Failed repairing incompatible .FRM file

    如果USE_FRM使用,REPAIR TABLE没有检查表是否需要升级。

修表的输出

REPAIR TABLE返回一个结果集与下表中显示的列。

专栏价值
Table表名
Op总是repair
Msg_typestatus错误info笔记,或warning
Msg_text信息性消息

这个REPAIR TABLE声明可能产生每个修理信息表的许多行。最后一排有一个msg_type价值statusmsg_test通常应OK。对于一个MyISAM表,如果你没有得到OK,你应该尝试修复它myisamchk --安全恢复。(REPAIR TABLE不执行所有的选项myisamchk。与myisamchk --安全恢复,你也可以使用选项REPAIR TABLE不支持,如--max-record-length。)

REPAIR TABLE表接球和投球发生表统计数据从旧的损坏的文件复制到新创建的文件时的任何错误。例如.如果对所有者的用户IDMVD.MYI文件是由不同的用户IDmysqld过程,REPAIR TABLE生成一个“文件”的错误不能改变所有权,除非mysqld开始的root用户

修表的考虑

REPAIR TABLE升级一个表如果它包含旧的时间列在pre-5.6.4格式(TIMEDATETIME,和TIMESTAMP没有分数秒精度)和支撑柱avoid_temporal_upgrade系统变差了。如果avoid_temporal_upgrade启用,REPAIR TABLE忽略了老时间列在表而不升级。

升级包含时间列表,禁用avoid_temporal_upgrade在执行之前REPAIR TABLE

你可以增加REPAIR TABLE通过设置某些系统变量的性能。看到8.6.3、优化维修表报表”

13.7.4组件,插件,和用户定义的函数语句

13.7.4.1创建用户定义函数的函数的语法

CREATE [AGGREGATE] FUNCTION function_name
    RETURNS {STRING|INTEGER|REAL|DECIMAL}
    SONAME shared_library_name

一个用户自定义函数(UDF)是一种具有新的功能,就像一个本地扩展MySQL的MySQL等功能(内置)ABS()CONCAT()

function_name是,应使用SQL语句来调用函数的名字。这个退货条款说明函数的返回值的类型。DECIMAL是一个法律价值后退货但目前,DECIMAL函数返回字符串值,应该这样写字符串功能.

shared_library_name是共享库文件包含实现功能的代码库的名字。该文件必须位于插件目录。这个目录是由给定的值plugin_dir系统变量。有关更多信息,参见第28.4.2.5,“UDF编译和安装”

创建一个函数,你必须INSERT特权的MySQL系统数据库。这是必要的因为CREATE FUNCTION增加了一个排的mysql.func系统表记录功能的名称,类型,和共享库的名字。如果你没有这个表,你应该运行mysql_upgrade命令创建它。看到4.4.5“,”mysql_upgrade检查升级MySQL表”

UDF注册使用CREATE FUNCTION在性能模式上市user_defined_functions这表;第25.11.16.4,“user_defined_functions表”

一个积极的作用是加载了CREATE FUNCTION而不是删除DROP FUNCTION。所有活动的功能是加载每次服务器启动,除非你开始mysqld--skip-grant-tables选项在这种情况下,自定义初始化跳过和UDFs都不可用。

在编写自定义函数的说明,见第28.4.2,“添加一个新的用户定义的函数。对于UDF的工作机制、功能必须使用C或C(或另一种语言,可以使用C调用约定),你的操作系统必须支持动态加载,你必须编译mysqld动态(静态)

一个AGGREGATE功能完全像是一个本地的MySQL料(摘要)等功能总和COUNT()。为骨料工作,你mysql.func表必须包含一个类型专栏如果你的mysql.func表中没有这个栏目,你应该运行mysql_upgrade程序创建它(见4.4.5“,”mysql_upgrade检查升级MySQL表”

笔记

升级共享库的UDF相关问题DROP FUNCTION声明,升级共享库,然后发出CREATE FUNCTION声明。如果你升级共享库的先使用DROP FUNCTION5,服务器崩溃

13.7.4.2降功能语法

DROP FUNCTION function_name

这一声明的用户自定义函数(UDF)滴命名function_name

下降的功能,你必须有DELETE特权的MySQL系统数据库。这是因为DROP FUNCTION从中删除一行mysql.func系统表记录功能的名称,类型,和共享库的名字。

笔记

升级共享库的UDF相关问题DROP FUNCTION声明,升级共享库,然后发出CREATE FUNCTION声明。如果你升级共享库的先使用DROP FUNCTION5,服务器崩溃

DROP FUNCTION也用于删除存储功能(见第13.1.26,“下降过程和降功能语法”

13.7.4.3安装组件的语法

INSTALL COMPONENT component_name [, component_name ] ...

这一声明安装一个或多个服务器组件,这成为主动的立即。一个组件提供了可用的服务器和其他组件服务;看5.5节,“MySQL服务器组件”INSTALL COMPONENT要求INSERT特权的mysql.component系统表

例子:

INSTALL COMPONENT 'file://component1', 'file://component2';

组件名称是骨灰开始file://并指出实现组件文件的基名称,位于目录命名的plugin_dir系统变量。组件名称不包括任何平台相关的文件名后缀如。所以.dll。(因为组件名称解释本身是由服务和组件结构使得它可以与其他实现。替换默认的服务实现这些命名细节有所变化)

如果出现任何错误,则语句失败并没有影响。例如,这种情况如果组件名称是错误的,一个叫组件不存在或已经安装,或组件初始化失败。

装载机服务处理加载组件,包括安装组件添加到mysql.component系统表作为一个注册表。随后重新启动服务器,任何组件上市mysql.component加载的加载程序服务的启动序列期间。发生这种情况,即使服务器开始的--skip-grant-tables选项

如果一个组件依赖于服务不在注册表中,你试图也没有安装组件或组件提供它所依赖的服务安装的组件,出现错误:

ERROR 3527 (HY000): Cannot satisfy dependency for service 'component_a'
required by component 'component_b'.

为了避免这个问题,可以安装所有组件在相同的语句,或安装相关组件在安装任何组件所依赖的。

13.7.4.4安装插件的语法

INSTALL PLUGIN plugin_name SONAME 'shared_library_name'

This statement安装了一个伺服器。它需要INSERT特权的mysql.plugin系统表

plugin_name是名称的插件,在插件描述符结构定义中包含的库文件(见第28.2.4.2,”插件数据结构”)。插件名称不区分大小写。最大的兼容性,插件名称应限于ASCII字母,数字和下划线是因为他们使用的C源文件,shell命令行,M4和Bourne shell脚本和SQL环境。

shared_library_name是共享库包含插件代码名称。的名称,包括文件扩展名(例如,libmyplugin.solibmyplugin.dll,或libmyplugin.dylib

共享库必须位于插件目录(目录命名的plugin_dir系统变量)。图书馆必须在插件目录本身,而不是在子目录。默认情况下,plugin_dir是的插件目录命名的目录下pkglibdir配置变量,但可以通过设定值的改变plugin_dir在服务器启动。例如,在一个设定值my.cnf文件:

[mysqld]
plugin_dir=/path/to/plugin/directory

如果价值plugin_dir是一个相对路径名,它是相对于MySQL库目录(的价值basedir系统变量

INSTALL PLUGIN加载并初始化插件代码使插件可供使用。一个插件是通过执行其初始化函数初始化,处理任何设置,插件必须在可执行。当服务器关闭时,它执行deinitialization功能为每个插件加载的插件,有机会进行最后的清理工作。

INSTALL PLUGIN还将该插件添加一行显示插件名称和库文件的名称mysql.plugin表在服务器启动时,服务器加载并初始化任何插件,是列在mysql.plugin表这意味着,一个插件安装INSTALL PLUGIN只有一次,而不是每次服务器启动。插件加载在启动时不如果服务器开始出现--skip-grant-tables选项

一个插件库可以包含多个插件。每个人要安装,使用一个单独的INSTALL PLUGIN声明。每个声明的名称不同的插件,但都指定同一个库的名字。

INSTALL PLUGIN导致服务器读取选项(my.cnf)文件只是在服务器启动。这使插件的文件拿起任何相关的选项。它是可能的甚至在加载插件的选项文件中添加插件的选项(如果loose前缀使用)。它也可以卸载插件,编辑my.cnf,重新安装插件。重新启动插件,这样使它的新选项的值而不需要重新启动服务器。

为控制个人的插件在服务器启动时加载选项,看第5.6.1,“安装和卸载插件”。如果你需要加载一个服务器启动插件时--skip-grant-tables选择了(这告诉服务器不能读取系统表),使用--plugin-load选项看到第5.1.6、“服务器选项”

删除一个插件,使用UNINSTALL PLUGIN声明

关于插件加载的更多信息,参见第5.6.1,“安装和卸载插件”

看看插件安装,使用SHOW PLUGINS表或查询INFORMATION_SCHEMA.PLUGINS

如果你编译一个插件库,需要重新安装,您可以使用下列方法之一:

  • 使用UNINSTALL PLUGIN卸载所有的插件在图书馆,在插件目录中安装新的插件库文件,然后使用INSTALL PLUGIN在图书馆安装所有插件。本程序的优点是,它可用于没有停止服务器。然而,如果插件库包含了很多插件,你必须发出许多INSTALL PLUGINUNINSTALL PLUGIN声明.

  • 停止服务器,在插件目录中安装新的插件库文件,并重新启动服务器。

13.7.4.5卸载组件的语法

UNINSTALL COMPONENT component_name [, component_name ] ...

这一声明停用和卸载一个或多个服务器组件。一个组件提供了可用的服务器和其他组件服务;看5.5节,“MySQL服务器组件”UNINSTALL COMPONENT是补充INSTALL COMPONENT。它要求DELETE特权的mysql.component系统表

例子:

UNINSTALL COMPONENT 'file://component1', 'file://component2';

关于组件命名信息,看第13.7.4.3,“安装组件的语法”

如果出现任何错误,则语句失败并没有影响。例如,这种情况如果组件名称是错误的,一个叫组件没有安装,或者无法卸载,因为其他已安装的组件依赖于它。

装载机服务处理组件卸载,包括从删除卸载组件mysql.component系统表作为一个注册表。作为一个结果,卸载组件没有后续服务器的启动顺序启动时加载。

13.7.4.6卸载插件的语法

UNINSTALL PLUGIN plugin_name

这个语句删除已安装的服务器插件。它要求DELETE特权的mysql.plugin系统表UNINSTALL PLUGIN是补充INSTALL PLUGIN

plugin_name必须有一些插件,在上市的名称mysql.plugin表服务器执行插件的deinitialization功能和删除从插件的行mysql.plugin表,以便以后重新启动服务器将不加载和初始化插件。UNINSTALL PLUGIN不删除插件的共享库文件。

如果你不使用它的任何表打开卸载插件。

插件去除有影响使用的相关的表。例如,如果一个全文解析插件与FULLTEXT在表的索引,卸载插件使表不可用。任何试图访问一个错误的结果。表无法打开,所以你不能删除索引的插件的使用。这意味着,卸载插件是做保健除非你不在乎表的内容。如果你是卸载插件无意重新安装它后,你关心的表的内容,你应该把桌子mysqldump和删除WITH PARSER从倾销条款CREATE TABLE声明这样你可以重新加载表后。如果你不在意的表,DROP TABLE可即使与表相关的任何插件缺失的应用。

关于插件加载的更多信息,参见第5.6.1,“安装和卸载插件”

13.7.5集语法

这个SET声明有几种形式。这些形式是没有一个特定的服务器能力的相关描述出现在本节第:

对于其他形式的描述出现在其他地方,分组的能力帮助他们实施相关的其他报表:

13.7.5.1集语法变量赋值

SET variable_assignment [, variable_assignment] ...

variable_assignment:
      user_var_name = expr
    | param_name = expr
    | local_var_name = expr
    | [GLOBAL | SESSION | PERSIST | PERSIST_ONLY]
        system_var_name = expr
    | [@@global. | @@session. | @@persist. | @@persist_only. | @@]
        system_var_name = expr

SET为变量赋值的语法允许你指定的值类型的不同,会影响服务器或客户端的操作变量:

SET语句分配变量值不写入二进制日志,所以复制方案只影响该主机你执行它。影响所有复制的宿主,对每一个执行语句。

下面的例子说明SET设置变量的语法。他们使用的=赋值操作符,但:=为了这个目的,也允许赋值运算符。

用户变量是书面@var_name并指定一个表达式的值如下:

设置”var_name=expr

实例:

SET @name = 43;
SET @total_tax = (SELECT SUM(tax) FROM taxable_transactions);

这些陈述的证明,expr的范围可以从简单的(一个文本值)到更复杂的(标量子查询返回的值)。

SET适用于参数和局部变量中存储的对象在定义它们。以下步骤使用柜台局部变量作为循环计数器:

CREATE PROCEDURE p()
BEGIN
  DECLARE counter INT DEFAULT 0;
  WHILE counter < 10 DO
    -- ... do work ...
    SET counter = counter + 1;
  END WHILE;
END;

许多系统变量是动态的,可以在运行时改变用SET声明。一个清单,看看第5.1.8.3,动态的“系统变量”。改变系统变量SET,指的是它的名字,或者在前面加一个修饰词:

  • 表示一个变量是全局变量,它的名字之前GLOBAL关键词或@ @全球资格赛:

    SET GLOBAL max_connections = 1000;
    SET @@global.max_connections = 1000;
    

    这个SYSTEM_VARIABLES_ADMINSUPER特权是需要设置全局变量。

  • 另一种方式来设置一个全局变量的名字是领先的PERSIST关键词或@ @坚持资格赛:

    SET PERSIST max_connections = 1000;
    SET @@persist.max_connections = 1000;
    

    SET语法让你在那还坚持在服务器运行时进行配置更改重启。喜欢SET GLOBALSET PERSIST更改运行时变量的值,但也写变量设置一个选项,文件名为mysqld-auto.cnf在数据目录(取代任何现有的变量设置,如果有一个)。在启动时,服务器处理这个文件的所有其他选项文件后。这个SYSTEM_VARIABLES_ADMINSUPER特权必须坚持全局变量。

    对于一个系统变量列表,不能坚持,看第5.1.8.1,“非持久性系统变量”

    笔记

    管理的mysqld-auto.cnf文件应该留给服务器而不是手动执行:

    • 该文件将导致丢失所有坚持设置在下次启动服务器的去除。(如果你的目的是重新配置服务器没有设置。这是允许的)删除所有设置在文件没有删除文件本身,使用此语句:

      RESET PERSIST;
      
    • 该文件手册的变化可能会导致在服务器启动一个语法错误。在这种情况下,服务器报告错误并退出。如果发生此问题,以启动服务器persisted_globals_load系统变残疾或与没有默认值选项另外,去除mysqld-auto.cnf文件,但是,如前所述,除亏损在持续设置该文件的结果。

    一个插件变量可以坚持如果插件安装时SET PERSIST执行。在坚持插件变量赋值生效后重新启动服务器插件是否仍安装。如果插件不再是安装插件变量不存在时,服务器读取mysqld-auto.cnf文件在这种情况下,服务器写入错误日志警告,继续:

    currently unknown variable 'var_name'
    was read from the persisted config file
    
  • 这个PERSIST_ONLY关键词或@ @ persist_only。限定符是相似的PERSIST

    SET PERSIST_ONLY back_log = 1000;SET @@persist_only.back_log = 1000;

    喜欢PERSISTpersist_only将变量设置mysqld-auto.cnf。然而,不像坚持PERSIST_ONLY不修改运行时系统全局变量的值,使其适合配置只读系统变量只能被设置在服务器启动。这个PERSIST_RO_VARIABLES_ADMIN特权是需要使用persist_only

  • 这个mysqld-auto.cnf文件使用这样的格式(略修改):

    {“mysql_server”:{“max_connections”:“99”、“transaction_isolation”:“read-committed”、“mysql_server_static_options”:{“innodb_api_enable_mdl”:“0”、“log_slave_updates”:“1”} } }

    只有坚持使用只读变量PERSIST_ONLY写入“_ MySQL服务器_静态_选项”部分。所有的变量在the present"mysql_server_static_options"部分追加到命令行服务器启动时。所有剩余的持续变量的设置通过执行SET GLOBAL声明

  • 表示一个变量是一个session变量,在它的名字的SESSION关键词或@ @ @ @ @ @ @ @@@资格赛:

    SET SESSION sql_mode = 'TRADITIONAL';SET @@session.sql_mode = 'TRADITIONAL';SET @@sql_mode = 'TRADITIONAL';

    设置会话变量通常不需要特殊的特权,虽然也有例外,要求SYSTEM_VARIABLES_ADMINSUPER特权(如sql_log_bin)。客户可以自己更改会话变量,但不与任何其他客户。

    会议系统变量不能坚持。他们不能设置在服务器启动,所以没有理由把它们列入mysqld-auto.cnf

  • LOCAL@ @本地是同义词SESSION@ @ @ @ @ @ @ @

  • 如果没有改性剂是目前,SET改变会话

  • 发生错误的情况下:

    • 使用SET GLOBAL(或@ @全球),SET PERSIST(或@ @坚持),或SET PERSIST_ONLY(或@ @ persist_only。),设置一个变量,只有一个会话值时:

      mysql> SET GLOBAL sql_log_bin = ON;
      ERROR 1228 (HY000): Variable 'sql_log_bin' is a SESSION
      variable and can't be used with SET GLOBAL
      
    • 省略GLOBAL(或@ @全球),PERSIST(或@ @坚持),或PERSIST_ONLY(或@ @ persist_only。)设置一个变量,只有当全球价值:

      mysql> SET max_connections = 1000;
      ERROR 1229 (HY000): Variable 'max_connections' is a
      GLOBAL variable and should be set with SET GLOBAL
      
    • 使用SET PERSIST(或@ @坚持),或SET PERSIST_ONLY(或@ @ persist_only。),设置一个变量,不能坚持的时候:

      mysql> SET PERSIST port = 3307;
      ERROR 1238 (HY000): Variable 'port' is a read only variable
      mysql> SET PERSIST_ONLY port = 3307;
      ERROR 1238 (HY000): Variable 'port' is a non persistent read only variable
      
    • 使用SET SESSION(或@会话)设置一个变量,只有当全球价值:

      mysql> SET SESSION max_connections = 1000;
      ERROR 1229 (HY000): Variable 'max_connections' is a
      GLOBAL variable and should be set with SET GLOBAL
      

前面的修饰词只适用于系统变量。发生错误,试图将其应用到用户定义的变量,存储过程或函数的参数,或存储程序的局部变量。

SET报表可以包含多个变量赋值,以逗号分隔。这个语句将值赋给一个用户定义的变量和系统变量:

SET @x = 1, SESSION sql_mode = '';

如果你设置了多个系统变量,最近GLOBAL坚持PERSIST_ONLY,或会话在声明中,改性剂是用于以下没有修饰符指定作业。

多变量赋值的例子:

SET GLOBAL sort_buffer_size = 1000000, SESSION sort_buffer_size = 1000000;
SET @@global.sort_buffer_size = 1000000, @@local.sort_buffer_size = 1000000;
SET GLOBAL max_connections = 1000, sort_buffer_size = 1000000;

如果任何一个变量赋值SET语句失败,整个语句失败,没有变量的改变,也不是mysqld-auto.cnf文件更改

如果你改变一个会话的系统变量值仍然有效,在你的会议直到你变为一个不同的值或结束会话。的变化对其他治疗没有效果。

如果你改变了一个全球性的系统变量的值,被用于新会话直到你改变的变量不同的值或服务器退出。变化是任何客户端访问全局变量,可见。然而,变化影响相应的会话变量仅用于客户端连接后的变化。全局变量的变化不会影响任何现有的客户端会话的会话变量(甚至不在其中SET GLOBAL声明发生)

做一个全球性的系统变量设置永久性使其应用在服务器重新启动时,修改它SET PERSISTpersist_only记录在mysqld-auto.cnf文件也可以使用SET GLOBAL手动修改my.cnf文件,但更多的是繁琐的,在手动输入设定错误可能要到后来发现。SET PERSISTpersist_only更为方便和避免畸形设置的可能性。

性能模式persisted_variables表提供的SQL接口mysqld-auto.cnf文件,使其内容可在运行时通过检查SELECT声明.看到第25.11.13.1,“性能模式persisted_variables表”

性能模式variables_info表包含的信息显示在每个用户的系统变量的最近设置。看到第25.11.13.2,“性能模式variables_info表”

设置一个GLOBAL在编译MySQL的默认值或值会话变为相应的电流GLOBAL值,设置变量的值默认。例如,以下语句设置会话的值是相同的max_join_size当前的全球价值:

SET @@session.max_join_size=DEFAULT;SET @@session.max_join_size=@@global.max_join_size;

不是所有的系统变量可以被设置为DEFAULT。在这种情况下,分配默认在一个错误的结果

SET PERSIST(或@ @坚持),设置一个全局变量DEFAULT或其文字默认值指定变量的默认值和添加的变量设置mysqld-auto.cnf。从文件删除的变量,使用RESET PERSIST

一个错误发生试图分配DEFAULT用户定义的变量,存储过程或函数的参数,或存储程序的局部变量。

指在表达系统变量的值,使用其中的@@-修饰者(例外)@ @坚持,这是不允许的表情)。例如,你可以在检索值SELECT这样的陈述:

选择“@global.sql_mode,@ @session.sql_mode,@ @ sql_mode;

一个参考表达式中的系统变量@@var_name(而不是@ @全球@@session.),如果它的存在和全球价值否则MySQL返回会话值。这不同于集@ @var_name=expr,这往往是指会话值

13.7.5.2设置字符集的语法

SET {CHARACTER SET | CHARSET}
    {'charset_name' | DEFAULT}

这一说法图的所有字符串的服务器与客户端之间发送的电流给定的映射。SET CHARACTER SET三套会议系统变量:character_set_clientcharacter_set_results将给定的字符集,和character_set_connection的价值character_set_database。看到10.4节,“连接字符集和Collations”

charset_name可引用或非上市

默认的字符集映射的可利用价值恢复DEFAULT。默认值取决于服务器的配置。

ucs2UTF16,和utf32不能作为客户端的字符集,这意味着他们不工作设置字符集

13.7.5.3集名称的语法

SET NAMES {'charset_name'
    [COLLATE 'collation_name'] | DEFAULT}

这套系统变量声明三届character_set_clientcharacter_set_connection,和character_set_results对给定的字符集。设置character_set_connection_ name的字符集还设置collation_connection默认的排序规则_ name的字符集。看到10.4节,“连接字符集和Collations”

可选COLLATE子句可以指定排序规则明确。如果给定的,整理一个可归类为必须charset_name

charset_namecollation_name可引用或非上市

默认的映射可以通过使用价值的恢复DEFAULT。默认值取决于服务器的配置。

ucs2UTF16,和utf32不能作为客户端的字符集,这意味着他们不工作SET NAMES

13.7.6显示语法

SHOW有很多种形式,提供有关数据库、表、列、或有关服务器的状态信息。本节介绍如下:

{掌握} logsshow显示二进制| binlog事件[”log_name“[从]pos[限制] [offset,]row_count] [显示字符集like_or_where] [显示整理like_or_where] [全部]列显示tbl_name(fromdb_name] [like_or_where]显示创建数据库db_name显示创建事件event_name显示创建函数func_name显示创建程序proc_name显示创建表tbl_name显示创建触发器trigger_name显示创建视图view_name显示数据库[like_or_where]显示引擎engine_name{状态|互斥}显示【贮藏】enginesshow错误[限制[offset,]row_counteventsshow ]显示功能代码func_name显示功能状态[like_or_where]给补助user显示指数tbl_name(fromdb_name]显示主人的statusshow打开的表[db_name] [like_or_wherepluginsshow ]显示程序代码proc_name显示程序状态[like_or_where]显示privilegesshow [全] [ processlistshow简介types[是]查询n] [偏移n[限制]n]显示profilesshow relaylog事件[”log_name“[从]pos[限制] [offset,]row_count]给奴隶hostsshow奴隶地位[通道channel] [会话]显示全球|地位[like_or_where] [显示表状态db_name] [like_or_where] [全部] [显示表db_name] [like_or_where[从]显示触发器db_name] [like_or_where[全球]显示|会话变量[ ]like_or_where[限制] [显示警告offset,]row_count]like_or_where:喜欢的pattern“|哪里expr

如果一个给定的语法SHOW包括,包括LIKE 'pattern'部分,&#39;pattern&#39;是一个字符串,可以包含SQL%_通配符。图案是用于限制报表输出匹配值。

几个SHOW报表也接受哪里条款,提供在指定要显示的行更多的灵活性。看到24.38节,“表达”的扩展

许多MySQL的API(如PHP)使你的治疗结果回来SHOW声明你将结果集从SELECT;见27章,连接器和API,或你的API文档的更多信息。此外,你可以在SQL从表中查询结果的工作INFORMATION_SCHEMA数据库,这是不容易做的结果SHOW声明.看到24章,information_schema表

13.7.6.1显示二进制日志的语法

SHOW BINARY LOGS
SHOW MASTER LOGS

列出服务器上的二进制日志文件。这项声明是作为程序描述部分第13.4.1.1,“清除二进制日志语法”,说明如何确定哪些日志可以清除。

mysql> SHOW BINARY LOGS;
+---------------+-----------+
| Log_name      | File_size |
+---------------+-----------+
| binlog.000015 |    724935 |
| binlog.000016 |    733481 |
+---------------+-----------+

SHOW MASTER LOGS相当于SHOW BINARY LOGS

用户与SUPERREPLICATION CLIENT特权可以执行此语句

13.7.6.2显示binlog事件语法

SHOW BINLOG EVENTS
   [IN 'log_name']
   [FROM pos]
   [LIMIT [offset,] row_count]

显示在二进制日志中的事件。如果你不指定'log_name',第一个二进制日志显示。

这个LIMIT条款具有相同的语法为SELECT声明。看到第13.2.10,选择“语法”

笔记

发行SHOW BINLOG EVENTS没有极限条款可以启动一个非常的时间和资源消耗的过程因为服务器返回给客户端的二进制日志内容完整(包括由服务器执行的所有语句修改数据)。作为一种替代SHOW BINLOG EVENTS,使用mysqlbinlog节约的二进制日志,对以后的考试和分析一个文本文件。看到4.6.8“,”mysqlbinlog用于处理二进制日志文件实用程序”

SHOW BINLOG EVENTS显示以下字段中的每一个事件的二进制日志:

  • Log_name

    那是被列出的文件的名称。

  • Pos

    在该事件发生的位置

  • Event_type

    这是个describes事件标识符的类型。

  • Server_id

    服务器ID的服务器的事件的起源。

  • End_log_pos

    在这一事件开始的位置,这等于Pos加上大小的事件

  • Info

    更多关于事件类型的详细信息。这些信息的格式取决于事件类型。

笔记

关于用户变量和系统变量的设置一些事件不包括在输出SHOW BINLOG EVENTS。在一个二进制日志得到事件的完整报道,使用mysqlbinlog

笔记

SHOW BINLOG EVENTS中继日志文件工作。你可以使用SHOW RELAYLOG EVENTS为了这个目的

13.7.6.3显示字符集的语法

SHOW CHARACTER SET
    [LIKE 'pattern' | WHERE expr]

这个SHOW CHARACTER SET声明显示所有可用的字符集。这个LIKE条款,如果存在,表明该字符集的名称。这个哪里条款可以使用更一般的条件选择行,讨论24.38节,“表达”的扩展。。。。。。。例如:

mysql> SHOW CHARACTER SET LIKE 'latin%';
+---------+-----------------------------+-------------------+--------+
| Charset | Description                 | Default collation | Maxlen |
+---------+-----------------------------+-------------------+--------+
| latin1  | cp1252 West European        | latin1_swedish_ci |      1 |
| latin2  | ISO 8859-2 Central European | latin2_general_ci |      1 |
| latin5  | ISO 8859-9 Turkish          | latin5_turkish_ci |      1 |
| latin7  | ISO 8859-13 Baltic          | latin7_general_ci |      1 |
+---------+-----------------------------+-------------------+--------+

SHOW CHARACTER SET输出具有这些列:

  • Charset

    字符集名称

  • Description

    该字符集的描述

  • Default collation

    默认排序规则的字符集。

  • Maxlen

    需要存储一个字符的最大字节数。

这个filename字符集是仅供内部使用;因此,SHOW CHARACTER SET不显示它

字符集的信息,也可以从INFORMATION_SCHEMACHARACTER_SETS表看到24.1节,“information_schema character_sets表”

13.7.6.4显示整理语法

SHOW COLLATION
    [LIKE 'pattern' | WHERE expr]

这一声明列表排序规则服务器支持的。默认情况下,输出从SHOW COLLATION包括所有可用的小吃。的LIKE条款,如果存在,表明匹配排序规则名。这个哪里条款可以使用更一般的条件选择行,讨论24.38节,“表达”的扩展。。。。。。。例如:

mysql> SHOW COLLATION WHERE Charset = 'latin1';
+-------------------+---------+----+---------+----------+---------+
| Collation         | Charset | Id | Default | Compiled | Sortlen |
+-------------------+---------+----+---------+----------+---------+
| latin1_german1_ci | latin1  |  5 |         | Yes      |       1 |
| latin1_swedish_ci | latin1  |  8 | Yes     | Yes      |       1 |
| latin1_danish_ci  | latin1  | 15 |         | Yes      |       1 |
| latin1_german2_ci | latin1  | 31 |         | Yes      |       2 |
| latin1_bin        | latin1  | 47 |         | Yes      |       1 |
| latin1_general_ci | latin1  | 48 |         | Yes      |       1 |
| latin1_general_cs | latin1  | 49 |         | Yes      |       1 |
| latin1_spanish_ci | latin1  | 94 |         | Yes      |       1 |
+-------------------+---------+----+---------+----------+---------+

SHOW COLLATION输出具有这些列:

  • Collation

    排序规则名称

  • Charset

    名称的字符集与整理相关。

  • Id

    整理的ID

  • Default

    无论是整理是默认的字符集。

  • Compiled

    该字符集是否编译到服务器。

  • Sortlen

    这是所需的字符串在字符集合表示排序的内存量相关。

看到每个字符集的默认排序规则,使用以下语句。Default是一个保留字,所以用它作为标识符,它必须引用等:

MySQL的&#62;SHOW COLLATION WHERE `Default` = 'Yes';--------------------- ---------- ---- --------- ---------- --------- |整理|字符集| ID |默认|编译| sortlen | --------------------- ---------- ---- --------- ---------- --------- | big5_chinese_ci | BIG5 | 1 |是|是| 1 | | dec8_swedish_ci | dec8 | 3 |是|是| 1 | | cp850_general_ci | cp850 | 4 |是|是| 1 | | hp8_english_ci |该| 6 |是|是| 1 | | koi8r_general_ci | koi8r | 7 |是|是| 1 | | latin1_swedish_ci | latin1 | 8 |是|是| 1 |…

整理信息也可从INFORMATION_SCHEMACOLLATIONS表看到24.2节,“information_schema排序表”

13.7.6.5显示列的语法

SHOW [EXTENDED] [FULL] {COLUMNS | FIELDS}
    {FROM | IN} tbl_name
    [{FROM | IN} db_name]
    [LIKE 'pattern' | WHERE expr]

SHOW COLUMNS显示有关信息列在一个给定的表。它也可以用于视图。SHOW COLUMNS显示的信息,只有那些列,你有特权。

MySQL的&#62;SHOW COLUMNS FROM City;------------- ---------- ------ ----- --------- ---------------- |场|型|空|关键|默认|额外| ------------- ---------- ------ ----- --------- ---------------- | ID | int(11)|没有| PRI |空| auto_increment | |名字| char(35)|没有| | | | |国家| char(3)|没有|多| | | |区| char(20)|没有| | | | |人口| int(11)|没有| | 0 | | ------------- ---------- ------ ----- --------- ----------------

一种替代tbl_name FROM db_name语法是db_name.tbl_name。这两个语句是等价的:

从表列的文件;显示列mydb.mytable;

可选EXTENDED关键词使输出包含隐藏列,MySQL在内部使用,无法访问的用户。

可选FULL关键词使输出包括柱整理和评论,以及你的每一列的权限。

这个LIKE条款,如果存在,表明该列的名称。这个哪里条款可以使用更一般的条件选择行,讨论24.38节,“表达”的扩展

数据类型可能不同于你所期望他们是基于CREATE TABLE因为MySQL数据类型声明有时变化当您创建或修改数据表。在何种条件下发生这种情况了第13.1.18.7,“沉默的列规范的变化”

SHOW COLUMNS显示以下值的每个表列:

  • Field

    栏目的名称

  • Type

    *柱过程中的数据类型。

  • Collation

    非二进制字符串列的排序规则,或NULL其他列。这个值只显示如果你使用全部关键词

  • Null

    the column为空性。the value isYES如果无效的值可以存储在列,NO如果不是

  • Key

    列是否有索引:

    • 如果Key是空的,要么是不列的索引或索引只作为一个多柱一次柱,非唯一索引。

    • 如果Key(墨西哥)革命制度党,列为PRIMARY KEY或是一个多柱primary key

    • 如果Key大学,列一列第一UNIQUE指数。(独特索引允许多个NULL值,但是你可以告诉该列是否允许无效的通过检查Null场。)

    • 如果Key穆尔,列是一个非唯一索引中的给定值多出现在列允许第一列。

    如果一个以上的Key值适用于一个给定的表列,钥匙显示一个具有最高优先级,在订单PRI大学MUL

    UNIQUE指标可能会显示(墨西哥)革命制度党如果它不能包含NULL价值观和没有主键在桌子上。一UNIQUE指数可能显示为穆尔如果几个栏目形成复合UNIQUE指数;虽然列的组合是独一无二的,每一列仍然可以保持一个给定值多次出现。

  • Default

    该列的默认值。这是NULL如果列有一个明确的违约无效的,或如果列定义不包括DEFAULT条款.

  • Extra

    任何额外的,是关于一个给定的列的信息。在这些情况下的值为空:

    • auto_increment列有汽车属性

    • on update CURRENT_TIMESTAMPTIMESTAMPDATETIME列有更新current_timestamp属性

    • VIRTUAL GENERATED虚拟存储对于生成的列

    • DEFAULT_GENERATED那有一个默认值的列的表达。

  • Privileges

    你该列的权限。这个值只显示如果你使用FULL关键词

  • Comment

    任何评论,包括在列定义。这个值只显示如果你使用FULL关键词

你也可以从中获得关于表的列信息INFORMATION_SCHEMA,其中包含一个COLUMNS表看到24.4节,“information_schema列表”。扩展信息隐藏列只使用可用SHOW EXTENDED COLUMNS不能得到的;COLUMNS

你可以在一个表中的列的列表MySQLShowdb_nametbl_name命令

这个DESCRIBE语句提供了类似的信息SHOW COLUMNS。看到第13.8.1“describe语法”

这个SHOW CREATE TABLESHOW TABLE STATUS,和SHOW INDEX报告还提供了有关表。看到第13.7.6,“语法”

13.7.6.6显示创建数据库的语法

SHOW CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name

显示CREATE DATABASE语句创建数据库的名称。如果商展声明包括IF NOT EXISTS条款,输出也包括这样一个条款。SHOW CREATE SCHEMA是同义词SHOW CREATE DATABASE

MySQL的&#62;SHOW CREATE DATABASE test\G*************************** 1。行***************************数据库:testcreate数据库:创建数据库`测试` / *!40100默认字符集utf8mb4 * / MySQL &#62;SHOW CREATE SCHEMA test\G*************************** 1。行***************************数据库:testcreate数据库:创建数据库`测试` / *!40100默认字符集utf8mb4 */

SHOW CREATE DATABASE引用的表名和列名的价值sql_quote_show_create选项看到第5.1.7,服务器“系统变量”

13.7.6.7显示创建的事件语法

SHOW CREATE EVENT event_name

This statement显示theCREATE EVENT需要重新创建一个给定事件的声明。它要求EVENT特权的数据库从该事件被显示。例如(使用相同的事件e_daily定义并改变第13.7.6.18,“显示事件的语法”):

mysql> SHOW CREATE EVENT test.e_daily\G
*************************** 1. row ***************************
               Event: e_daily
            sql_mode:
           time_zone: SYSTEM
        Create Event: CREATE EVENT `e_daily`
                        ON SCHEDULE EVERY 1 DAY
                        STARTS CURRENT_TIMESTAMP + INTERVAL 6 HOUR
                        ON COMPLETION NOT PRESERVE
                        ENABLE
                        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
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8mb4_0900_ai_ci

character_set_client是这个会议的价值character_set_client系统变量当事件被创建。粘贴连接是这个会议的价值collation_connection系统变量当事件被创建。collation数据库是整理数据库与这个事件有关。

输出反映事件的现状(ENABLE)而不是创建它的地位。

13.7.6.8显示创建函数的语法

SHOW CREATE FUNCTION func_name

这项声明是相似的SHOW CREATE PROCEDURE但是对于存储功能。看到第13.7.6.9,“显示创建程序的语法”

13.7.6.9显示创建程序的语法

SHOW CREATE PROCEDURE proc_name

这个声明是一个mysql扩展。它返回的字符串,可以用来重新创建指定的存储过程。类似的声明,SHOW CREATE FUNCTION,显示有关存储功能的信息(见第13.7.6.8,“显示创建函数的语法”

使用的语句,你必须有全球SELECT特权

MySQL的&#62;SHOW CREATE PROCEDURE test.simpleproc\G* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 1。行* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * _ simpleproc SQL程序:程序:创建模式:创建程序simpleproc ` `(超时参数int)begin select count(*)为参数。从endcharacter吨;_看到_客户端utf8collation _:连接:utf8 _ _数据库通用词:utf8mb4 collation _ 0900 _艾_ cimysql &#62;SHOW CREATE FUNCTION test.hello\G*************************** 1。行***************************功能:你好sql_mode:创建功能:创建功能`你好`(的char(20))返回char(50)返回concat(你好,&#39;,,&#39;!&#39;)character_set_client:utf8collation_connection:utf8_general_ci数据库排序规则:utf8mb4_0900_ai_ci

character_set_client是这个会议的价值character_set_client系统变量时的常规创建。粘贴连接是这个会议的价值collation_connection系统变量时的常规创建。collation数据库是整理数据库的日常关联。

13.7.6.10显示创建表的语法

SHOW CREATE TABLE tbl_name

显示CREATE TABLE语句创建命名表。使用此语句,你必须有一些特权的表。该声明还与观点。

MySQL的&#62;SHOW CREATE TABLE t\G*************************** 1. row ***************************       Table: tCreate Table: CREATE TABLE `t` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `s` char(60) DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

SHOW CREATE TABLE引用的表名和列名的价值sql_quote_show_create选项看到第5.1.7,服务器“系统变量”

有关CREATE TABLE报表存储在MySQL,看第13.1.18.1,“创建表的语句保留”

13.7.6.11显示创建触发器的语法

SHOW CREATE TRIGGER trigger_name

这句话表明CREATE TRIGGER语句创建名为触发。这一声明要求TRIGGER与触发相关的表的权限。

MySQL的&#62;SHOW CREATE TRIGGER ins_sum\G*************************** 1. row ***************************               Trigger: ins_sum              sql_mode: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTIONSQL Original Statement: CREATE DEFINER=`me`@`localhost` TRIGGER ins_sum                        BEFORE INSERT ON account                        FOR EACH ROW SET @sum = @sum + NEW.amount  character_set_client: utf8  collation_connection: utf8_general_ci    Database Collation: utf8mb4_0900_ai_ci               Created: 2013-07-09 10:39:34.96

SHOW CREATE TRIGGER输出具有以下列:

  • Trigger:触发器名称

  • sql_mode:SQL模式效果触发时执行。

  • SQL Original Statement:theCREATE TRIGGER语句定义触发器

  • character_set_client的会话值:character_set_client系统变量时,触发器的创建。

  • collation_connection的会话值:collation_connection系统变量时,触发器的创建。

  • Database Collation:整理数据库的触发器是相关的。

  • Created:日期和时间时,触发器的创建。这是一个时间戳(2)价值(与小数部分以百分之一秒)触发器。

你也可以从中获得关于触发对象的信息INFORMATION_SCHEMA,其中包含一个TRIGGERS表看到24.30节,“information_schema触发器表”

13.7.6.12显示创建用户语法

SHOW CREATE USER user

这句话表明CREATE USER语句创建命名用户。如果用户不存在发生错误。声明要求SELECT特权的MySQL系统的数据库,除了看信息为当前用户。为当前用户的SELECT特权的mysql.user系统表中显示所需的密码哈希IDENTIFIED AS条款;否则,显示器作为哈希<secret>

姓名的账户,使用的格式描述第6.2.4,“指定的帐户名”。如果省略该帐户名,主机名,默认为'%'。它也可以指定CURRENT_USERCURRENT_USER()指与当前会话关联的帐户。

MySQL的&#62;SHOW CREATE USER 'root'@'localhost'\G*************************** 1。行***************************创造root@localhost用户:创建用户&#39;根&#39;”&#39;localhost&#39;identified &#39; mysql_native_password&#39;as * 2470c0c06dee42fd1618bb99005adca2ec9d1e19&#39;require没有到期默认帐户解锁密码

显示授权帐户的权限,使用SHOW GRANTS声明。看到第13.7.6.21”节目,格兰特的语法”

13.7.6.13显示创建视图的语法

SHOW CREATE VIEW view_name

这句话表明CREATE VIEW语句创建命名视图

MySQL的&#62;SHOW CREATE VIEW v\G*************************** 1. row ***************************                View: v         Create View: CREATE ALGORITHM=UNDEFINED                      DEFINER=`bob`@`localhost`                      SQL SECURITY DEFINER VIEW                      `v` AS select 1 AS `a`,2 AS `b`character_set_client: utf8collation_connection: utf8_general_ci

character_set_client是这个会议的价值character_set_client系统变量当视图创建粘贴连接是这个会议的价值collation_connection系统变量当视图创建

使用SHOW CREATE VIEW要求SHOW VIEW特权,和SELECT对问题的看法的特权

你也可以获得关于视图对象信息INFORMATION_SCHEMA,其中包含一个VIEWS表看到部分差异,“information_schema意见表”

MySQL可以让你用不同的sql_mode设置告诉服务器支持的SQL语法类型。例如,您可以使用ANSIMySQL SQL模式确保正确地解释标准的SQL连接操作符,双杆(| |),在你的查询。如果你创建一个视图,项目,你可能会担心改变sql_mode设置一个值不同ANSI可能导致视图无效。但是这是没有的情况下。无论你如何写一个视图定义、MySQL总是存储方式也相同,在一个规范的形式。这里有一个例子,说明服务器双杆串联运算符更改为CONCAT()功能:

MySQL的&#62;SET sql_mode = 'ANSI';查询好,为受影响的行(0.001秒)MySQL &#62;CREATE VIEW test.v AS SELECT 'a' || 'b' as col1;查询好,为受影响的行(0.01秒)MySQL &#62;SHOW CREATE VIEW test.v\G*************************** 1。行***************************观点:V创建视图:创建视图的“V”作为选择concat(A,B)为“2”…一行集(0.001秒)

在标准形式存储视图定义的优点是修改后的值sql_mode不会影响从查看结果。但是另外一个后果是,评论之前SELECT被剥夺的定义由服务器。

13.7.6.14显示数据库的语法

SHOW {DATABASES | SCHEMAS}
    [LIKE 'pattern' | WHERE expr]

SHOW DATABASES列出MySQL服务器主机的数据库。SHOW SCHEMAS是同义词SHOW DATABASES。这个LIKE条款,如果存在,表明匹配数据库名称。这个哪里条款可以使用更一般的条件选择行,讨论24.38节,“表达”的扩展

你只看到那些数据库,你有这样的特权,除非你有全球SHOW DATABASES特权。你也可以把这个列表的使用MySQLShow命令

如果服务器开始的--skip-show-database选项,你根本无法使用此声明,除非你有SHOW DATABASES特权

MySQL实现了数据库中的数据目录的目录,所以这句话简单地列出目录的位置。然而,输出可能包括目录不符合实际的数据库名称。

13.7.6.15显示引擎语法

SHOW ENGINE engine_name {STATUS | MUTEX}

SHOW ENGINE显示操作信息的存储引擎。它要求PROCESS特权。该声明这些变量:

显示引擎InnoDB引擎InnoDB引擎statusshow mutexshow performance_schema状态

SHOW ENGINE INNODB STATUS从标准的广泛的信息显示InnoDB对状态监测InnoDB存储引擎。有关监测标准和其他信息InnoDB显示器提供的信息InnoDB处理,见15.16节,“InnoDB监视器”

SHOW ENGINE INNODB MUTEX显示器InnoDB互斥RW -锁统计

笔记

InnoDB互斥锁和rwlocks也可以监测中的应用性能模式表看到第15.15.2,“监测InnoDB互斥等使用性能模式”

互斥统计使用下列选项动态配置:

  • 为了使互斥统计收集,运行:

    SET GLOBAL innodb_monitor_enable='latch';
  • 重置互斥统计,运行:

    SET GLOBAL innodb_monitor_reset='latch';
  • 禁用互斥统计收集,运行:

    SET GLOBAL innodb_monitor_disable='latch';

对于互斥量统计SHOW ENGINE INNODB MUTEX也可以通过设置启用innodb_monitor_enable='all',或禁用的设置innodb_monitor_disable='all'

SHOW ENGINE INNODB MUTEX输出具有以下列:

  • Type

    总是InnoDB

  • Name

    对于互斥的Name现场报道只有互斥的名字。对于rwlocks,的姓名现场报道的源文件在rwlock的实施,和文件中的行号,rwlock创建。线数是特定于您的版本的MySQL。

  • Status

    互斥的状态。这场报告的自旋,数量等,并要求。对底层操作系统的互斥锁的统计,这是实施外InnoDB据报道,不

    • spins指示性数字

    • waits表明互斥的数量等

    • calls显示多少次请求互斥

SHOW ENGINE INNODB MUTEX跳过互斥器读写锁属于缓冲池块,作为输出量可以是压倒性的系统与一个大的缓冲池。(有一块16k缓冲池,一个互斥和RW锁有65536块每千兆字节。)SHOW ENGINE INNODB MUTEX也没有列出任何互斥或读写锁,一直等待(os_waits=0)。因此,SHOW ENGINE INNODB MUTEX只能显示互斥锁和读写锁的缓冲池,造成至少一个操作系统的外部信息等待

使用SHOW ENGINE PERFORMANCE_SCHEMA STATUS检查绩效模式代码的内部操作:

MySQL的&#62;SHOW ENGINE PERFORMANCE_SCHEMA STATUS\G*************************** 3。行***************************型:performance_schema名称:events_waits_history.sizestatus:76 *************************** 4。行***************************型:performance_schema名称:events_waits_history.countstatus:10000 *************************** 5。行***************************型:performance_schema名称:events_waits_history.memorystatus:760000…*************************** 57。行***************************型:performance_schema名称:performance_schema.memorystatus:26459600…

本声明的目的是帮助DBA理解,对内存的要求有不同的性能模式选择的影响。

Name价值是由两部分组成,这叫内部缓冲区和缓冲区的属性,分别为。缓冲区的名字解释如下:

  • 一个内部缓冲区是不暴露为表命名在括号内。实例:(pfs_cond_class).size(pfs_mutex_class记忆)。

  • 一个内部缓冲区是暴露在一个表performance_schema数据库是命名的表,没有括号。实例:events_waits_history.sizemutex_instances.count

  • 一个值,适用于性能架构作为一个整体的开始performance_schema。。。。。。。例子:performance_schema.memory

缓冲的属性有这些含义:

  • size通过实施以内部记录的大小,例如表中的一行的大小。大小价值观是无法改变的

  • count是内部的记录数,如表中的行数。计数值可以使用性能模式配置选项改变。

  • 一个表,tbl_name.memory是产品大小count。作为一个整体的性能模式,performance_schema.memory是所有的记忆和使用(其他所有的总和memoryvalues)

在某些情况下,一个性能模式配置参数和有直接的关系SHOW ENGINE价值。例如,events_waits_history_long.count对应于performance_schema_events_waits_history_long_size。在其他情况下,关系更加复杂。例如,events_waits_history.count对应于performance_schema_events_waits_history_size(行数乘以每线程)performance_schema_max_thread_instances(线程数)

13.7.6.16显示引擎的语法

SHOW [STORAGE] ENGINES

SHOW ENGINES显示状态信息的服务器的存储引擎。这是否一个存储引擎的支持是特别有用的,或者看到默认的搜索引擎是什么。

MySQL的&#62;SHOW ENGINES\G*************************** 1。行***************************引擎:档案支持:是的评论:归档存储enginetransactions:没有阿隆索:没有保存点:没有*************************** 2。行***************************引擎:黑洞的支持:是的评论:/dev/null存储引擎(任何你写它消失)交易:没有阿隆索:没有保存点:没有*************************** 3。行***************************引擎:mrg_myisam支持:是的评论:相同的MyISAM tablestransactions收集:没有阿隆索:没有保存点:没有*************************** 4。行***************************引擎:联邦支持:没有评论:联合MySQL存储enginetransactions:空:空:空*************************** XA事务5。行***************************引擎:MyISAM支持:是的评论:MyISAM存储enginetransactions:没有阿隆索:没有保存点:没有*************************** 6。行***************************引擎:performance_schema支持:是的评论:性能schematransactions:没有阿隆索:没有保存点:没有*************************** 7。行***************************引擎:InnoDB支持:默认评论:支持事务,行级锁,外keystransactions:是阿隆索:是保存点:是的*************************** 8。行***************************引擎:内存支持:是的评论:基于哈希的,存储在内存中,用于临时tablestransactions:没有阿隆索:没有保存点:没有*************************** 9。行***************************引擎:CSV支持:是的评论:CSV存储enginetransactions:没有阿隆索:没有保存点:无

从输出SHOW ENGINES可根据使用和其他因素的MySQL版本有所不同。

SHOW ENGINES输出具有以下列:

  • Engine

    该存储引擎的名称

  • Support

    用于存储引擎支持服务器的水平,如下表所示。

    价值意义
    YES发动机支承和活跃
    DEFAULT喜欢YES,加上这是默认的搜索引擎
    NO柴油机是不支持的
    DISABLED引擎支持的但已被禁用

    一个值NO意味着服务器不使用的引擎支持,所以无法启用运行时。

    一个值DISABLED是因为服务器启动的一个选项,关闭发动机,或因为了不是所有的选项需要使它。在后者的情况下,错误日志中应该包含一个理由说明为什么选项被禁用。看到5.4.2部分,“错误日志”

    你也可以看到DISABLED对于一个存储引擎如果服务器被编译成支持它,但开始与-跳过—engine_name选项

    所有的MySQL服务器支持MyISAM表它不可能禁用MyISAM

  • Comment

    一个简短的描述的存储引擎。

  • Transactions

    无论是存储引擎支持事务。

  • XA

    无论是存储引擎支持XA事务。

  • Savepoints

    无论是存储引擎支持保存点。

存储引擎的信息也可以从INFORMATION_SCHEMAENGINES表看到24.7节,“information_schema引擎表”

13.7.6.17显示错误的语法

SHOW ERRORS [LIMIT [offset,] row_count]
SHOW COUNT(*) ERRORS

SHOW ERRORS是一个诊断的声明类似SHOW WARNINGS,除了它只显示错误信息,而不是错误,警告和注释。

这个LIMIT条款具有相同的语法为SELECT声明。看到第13.2.10,选择“语法”

这个SHOW COUNT(*) ERRORS报表显示错误的数量。你也可以从中检索这个号码error_count变量:

显示计数(*)的错误;选择@ @ error_count;

SHOW ERRORSerror_count仅适用于错误、警告或记不。在其他方面,他们是相似的SHOW WARNINGSwarning_count。特别地,SHOW ERRORS以上信息不能显示max_error_count的信息,和error_count可以超过价值max_error_countif the number of errors超过max_error_count

有关更多信息,参见第13.7.6.40,“显示警告语法”

13.7.6.18显示事件的语法

SHOW EVENTS
    [{FROM | IN} schema_name]
    [LIKE 'pattern' | WHERE expr]

这一声明显示有关事件管理事件的信息。它要求EVENT特权的数据库从该事件被显示。

在其最简单的形式,SHOW EVENTS列出当前架构中的事件:

MySQL的&#62;SELECT CURRENT_USER(), SCHEMA();| ---------------- ----------流_ user()()|模式| ---------------- ---------- |乔恩@ ghidora | myschema | ---------------- ---------- 1行集(0秒)在MySQL &#62;SHOW EVENTS\G*************************** 1。行***************************分贝:myschema名称:e_daily定义者:乔恩@姬度拉时区:系统类型:重复执行:空区间值:10区间范围:二开始:2006-02-09 10:41:23结束:零状态:启用鼻祖:0character_set_client:utf8collation_connection:utf8_general_ci数据库排序规则:utf8mb4_0900_ai_ci

看到事件的一个特定的模式,使用FROM条款.例如,看到事件的测试架构,使用以下语句:

SHOW EVENTS FROM test;

这个LIKE条款,如果存在,表明比赛事件名称。这个哪里条款可以使用更一般的条件选择行,讨论24.38节,“表达”的扩展

SHOW EVENTS输出具有以下列:

  • Db:图式(数据库)对该事件的定义。

  • Name“name”事件

  • Time zone:事件时间区,这是用于调度事件的时间区,实际上是在事件的执行。默认值是系统

  • Definer:谁创造了事件的用户账户,在&#39;user_name“@”host_name&#39;格式

  • Type:事件的重复类型,无论是一次or(瞬态)RECURRING(Repeat)

  • Execute At:日期和时间设置执行瞬态事件。显示为DATETIME价值

    对于一个经常性的事件,该列的值总是NULL

  • Interval Value:对于经常性事件,在事件的执行等间隔数。

    一个短暂的事件,该列的值总是NULL

  • Interval Field:用于经常性事件之前等待的时间间隔重复单位。

    一个短暂的事件,该列的值总是NULL

  • Starts:一个重复事件的开始日期和时间。这是显示为DATETIME价值,是无效的如果没有开始的日期和时间对事件的定义。

    一个短暂的事件,此列始终NULL

  • Ends结束的日期和时间。这显示了DATETIME值,默认值为无效的如果没有结束日期和时间对事件的定义。

    一个短暂的事件,此列始终NULL

  • Status在事件的状态。一个启用DISABLED,或slaveside _ disabled

    SLAVESIDE_DISABLED指出,事件发生在另一个创建MySQL服务器作为复制和复制到当前MySQL服务器作为一个奴隶,但事件不是目前正在执行的奴隶。

  • Originator:的MySQL服务器上的事件创建服务器ID。默认值为0。

  • character_set_client是这个会议的价值character_set_client系统变量时的常规创建。粘贴连接是这个会议的价值collation_connection系统变量时的常规创建。数据库的排序规则是整理数据库的日常关联。

为更多的信息关于SLAVE_DISABLED鼻祖柱,看第17.4.1.16”功能,调用“复制

事件动作语句不在输出显示SHOW EVENTS。使用SHOW CREATE EVENTINFORMATION_SCHEMA.EVENTS

时间显示SHOW EVENTS在活动区,如在第23.4.4,事件“元数据”

输出中的列SHOW EVENTS类似,但不相同的列中的INFORMATION_SCHEMA.EVENTS表看到24.8节,“information_schema事件表”

13.7.6.19显示功能代码语法

SHOW FUNCTION CODE func_name

这项声明是相似的SHOW PROCEDURE CODE但是对于存储功能。看到第13.7.6.27,“显示程序代码的语法”

13.7.6.20显示功能语法

SHOW FUNCTION STATUS
    [LIKE 'pattern' | WHERE expr]

这项声明是相似的SHOW PROCEDURE STATUS但是对于存储功能。看到第13.7.6.28,“显示程序状态语法”

13.7.6.21显示补助语法

SHOW GRANTS
    [FOR user_or_role
        [USING role [, role] ...]]

user_or_role: {
    user
  | role
}

这一声明显示特权和角色分配给一个MySQL的用户帐户或角色,在形式GRANT语句必须执行复制的特权和角色分配。

笔记

为MySQL账户显示nonprivilege信息,使用SHOW CREATE USER声明。看到第13.7.6.12,“显示创建用户语法”

SHOW GRANTS要求SELECT特权的MySQL系统的数据库,除了显示当前用户的权限和角色。

姓名的帐户或角色SHOW GRANTS,使用相同的格式为GRANT声明;例如,杰弗里“localhost”

mysql> SHOW GRANTS FOR 'jeffrey'@'localhost';
+------------------------------------------------------------------+
| Grants for jeffrey@localhost                                     |
+------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `jeffrey`@`localhost`                      |
| GRANT SELECT, INSERT, UPDATE ON `db1`.* TO `jeffrey`@`localhost` |
+------------------------------------------------------------------+

主机部分,如果省略,默认为'%'。有关指定帐号和角色名,见第6.2.4,“指定的帐户名”,和第6.2.5,“指定角色的名字”

显示当前用户的权限授予(您使用的是连接到服务器的帐户),您可以使用下列语句:

SHOW GRANTS;
SHOW GRANTS FOR CURRENT_USER;
SHOW GRANTS FOR CURRENT_USER();

如果SHOW GRANTS FOR CURRENT_USER(或等效的语法)是用于定义上下文,如在存储过程执行的定义者而不是调用者权限)的资助,显示那些定义者和不调用。

在MySQL 8相比以前的系列,SHOW GRANTS不再显示ALL PRIVILEGES在其全球特权因为输出的意义ALL PRIVILEGES在全球层面的变化取决于定义了动态权限。相反,SHOW GRANTS显式地列出每个授予全球特权:

MySQL的&#62;SHOW GRANTS FOR 'root'@'localhost';改性|资助换根改性| @本地主机|格兰特select,insert,update,delete,创造,滴,| reload,| shutdown,过程,文件,修改,显示references,索引,数据库,|创建临时表,|超级锁表,execute,斯拉夫| REPLICATION | REPLICATION,客户端,创建秀景,山景,创建例程,例程| |圣坛,创建用户,创建表空间,事件,触发器,| |创建角色,角色由* *到承包承包承包承包与根| @ option | localhost格兰特格兰特| |在线代理是“to”是根是localhost |授予期权与改性

应用过程SHOW GRANTS输出应作相应的调整

在全球层面,GRANT OPTION适用于所有静态全局权限授予如果给予任何人,但单独应用于动态权限授予。SHOW GRANTS显示全局权限这样:

  • 一行列出所有理所当然的静态权限,如果有,包括WITH GRANT OPTION如果适当的

  • 一行列出所有动态权限授予GRANT OPTION是理所当然的,如果有,包括授予期权

  • 一行列出所有动态权限授予GRANT OPTION不是理所当然的,如果有任何不授予期权

与可选的USING条款,SHOW GRANTS使您可以检查用户的角色相关联的特权。每一个角色的名字命名使用条款必须授予用户

假设用户u1分配角色R1r2,如下:

创建角色的R1,R2的选择;格兰特DB1。*“R1”;格兰特插入,更新,删除DB1。*“R2”;创建用户U1 &#39;@&#39;本地主机&#39;确定&#39; u1pass’;格兰特R1,R2为U1的“@ &#39;localhost &#39;;

SHOW GRANTS没有使用显示授予的角色:

mysql> SHOW GRANTS FOR 'u1'@'localhost';
+---------------------------------------------+
| Grants for u1@localhost                     |
+---------------------------------------------+
| GRANT USAGE ON *.* TO `u1`@`localhost`      |
| GRANT `r1`@`%`,`r2`@`%` TO `u1`@`localhost` |
+---------------------------------------------+

添加一个USING条款导致语句也显示每个角色的条款命名相关的特权:

MySQL的&#62;SHOW GRANTS FOR 'u1'@'localhost' USING 'r1';--------------------------------------------- |补助U1 @本地| --------------------------------------------- |授予使用*。* ` U1 ` @ ` localhost ` | |格兰特选择` DB1 `。* ` U1 ` @ ` localhost ` | |格兰特` R1 ` @ ` % `,` R2 ` @ ` % `到` U1 `“` localhost ` | --------------------------------------------- MySQL &#62;SHOW GRANTS FOR 'u1'@'localhost' USING 'r2';------------------------------------------------------------- |赠款是U1的| @本地主机使用在线------------------------------------------------------------- |格兰特*。*”“”“”“|本地U1 |格兰特的INSERT,UPDATE,DELETE,DB1的`在线` ` ` U1。*“localhost”| ` ` ` `格兰特| R1 R2”“%”%“”“,”“localhost”到“U1”&#62;“| ------------------------------------------------------------- MySQLSHOW GRANTS FOR 'u1'@'localhost' USING 'r1', 'r2';--------------------------------------------------------------------- |赠款是U1的| @本地主机使用在线--------------------------------------------------------------------- |格兰特*。*”“”“”“| U1 |本地查询,插入,更新,删除`在线`逻辑`到` U1。*“localhost”| ` ` ` `格兰特| R1 R2的%“”“”“,”` ` `成`对` | U1 --------------------------------------------------------------------- @本地主机
笔记

一个特权授予一个账户一直都在发挥作用,但作用不。一个帐户的积极作用可以在不同的时段,根据不同的价值activate_all_roles_on_login系统变量,默认帐户的角色,以及是否SET ROLE已经在一个会话中执行。

SHOW GRANTS不显示的权限,可以指定帐户,但给予不同的帐户。例如,如果一个匿名帐户存在,指定的帐户可以使用的特权,但SHOW GRANTS无法显示

SHOW GRANTS显示指定的强制作用mandatory_roles系统变量的值如下:

  • SHOW GRANTS没有一个条款显示权限为当前用户,包括强制作用。

  • SHOW GRANTS FOR user显示指定用户的权限,而不包括强制性的角色。

这种行为是对使用输出应用的效益SHOW GRANTS FOR user确定哪些权限授予明确指定的用户。是输出,包括强制性的角色,这将是难以区分从强制显式授予角色用户角色。

当前用户的权限,应用程序可以确定有或无强制作用利用SHOW GRANTSSHOW GRANTS FOR CURRENT_USER,分别

13.7.6.22显示索引的语法

SHOW [EXTENDED] {INDEX | INDEXES | KEYS}
    {FROM | IN} tbl_name
    [{FROM | IN} db_name]
    [WHERE expr]

SHOW INDEX返回表的索引信息。格式类似的sqlstatistics调用ODBC。这一声明要求表中的任何列一些特权。

mysql> SHOW INDEX FROM City\G
*************************** 1. row ***************************
        Table: city
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: ID
    Collation: A
  Cardinality: 4188
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
      Visible: YES
   Expression: NULL
*************************** 2. row ***************************
        Table: city
   Non_unique: 1
     Key_name: CountryCode
 Seq_in_index: 1
  Column_name: CountryCode
    Collation: A
  Cardinality: 232
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
      Visible: YES
   Expression: NULL

一种替代tbl_name FROM db_name语法是db_nametbl_name。这两个语句是等价的:

显示从文件索引表;显示指数从mydb.mytable;

可选EXTENDED关键词使输出包括信息隐藏的指标,MySQL使用内部和不可访问的用户。

这个WHERE条款可以使用更一般的条件选择行,讨论24.38节,“表达”的扩展

SHOW INDEX返回以下领域:

  • Table

    的名称的表

  • Non_unique

    0如果指数不能包含重复的,1如果它能。

  • Key_name

    该指数的名字。如果索引为主键,名称是PRIMARY

  • Seq_in_index

    索引中的列顺序号,从1开始。

  • Column_name

    the column name。see also the description for theExpression专栏

  • Collation

    如何列在索引排序。这可以有价值A(升),D(descending),或NULL(未排序)

  • Cardinality

    索引中的唯一值的数量估计。更新这个数字,跑ANALYZE TABLE或(为MyISAM表格)myisamchk -

    Cardinality基于存储为整数计算统计,所以价值不一定精确甚至小表。基数越高,更大的机会,MySQL使用索引时,加入。

  • Sub_part

    该指数的前缀。那就是,如果仅列部分索引索引的字符数,NULL如果整个编号都是索引。

    笔记

    前缀限制以字节为单位。然而,前缀长度指标规格CREATE TABLEALTER TABLE,和CREATE INDEX语句被解释为非二进制字符串类型的字符数(CHARVARCHARTEXT)和二进制字符串类型的字节数(BINARYVARBINARYBLOB)。考虑到这一点时指定前缀长度为非二进制字符串列使用多字节字符集。

    关于前缀索引的更多信息,参见第8.3.5,“列索引”,和第13.1.14,“创建索引的语法”

  • Packed

    说明关键是包装NULL如果不是

  • Null

    包含YES如果列可能包含无效的价值观和''如果不是

  • Index_type

    用指数法(BTREE全文HASH索引

  • Comment

    关于指数在自己的专栏中没有描述的信息,如disabled如果索引被禁用

  • Index_comment

    任何评论提供的指数与COMMENT属性创建索引时

  • Visible

    无论指数是优化器可见。看到第8.3.12节“隐形反射”

  • Expression

    MySQL 8.0.13高支持功能的关键部分(见功能键部分),这既影响了Column_name表达专栏

    • 一个功能的关键部分,Column_name显示列的索引和关键部分表达NULL

    • 一个功能键部分,Column_name无效的Expression表明关键部分的表达

关于表的索引信息也可从INFORMATION_SCHEMASTATISTICS表看到部分二千四百二十三,“information_schema统计表”。扩展信息隐藏的指标只使用可用SHOW EXTENDED INDEX不能得到的;STATISTICS

你可以用一个表的索引列表mysqlshow Kdb_nametbl_name命令

显示主人的身份13.7.6.23语法

SHOW MASTER STATUS

这一说法提供了关于主的二进制日志文件的状态信息。它需要的SUPERREPLICATION CLIENT特权

例子:

mysql> SHOW MASTER STATUS\G
*************************** 1. row ***************************
             File: master-bin.000002
         Position: 1307
     Binlog_Do_DB: test
 Binlog_Ignore_DB: manual, mysql
Executed_Gtid_Set: 3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5
1 row in set (0.00 sec)

当全球事务ID使用,Executed_Gtid_Set显示为已在主执行交易gtids集。这是因为该值gtid_executed此服务器上的系统变量,以及价值executed_gtid_set在输出SHOW SLAVE STATUS此服务器上的

13.7.6.24显示打开的表的语法

SHOW OPEN TABLES
    [{FROM | IN} db_name]
    [LIKE 'pattern' | WHERE expr]

SHOW OPEN TABLES列出了非—临时表,在表中的当前缓存打开。看到第8.4.3.1,“MySQL如何打开和关闭表”。这个FROM条款,如果存在,制约着证明那些存在于表db_name数据库这个LIKE条款,如果存在的话,表示匹配的表名。这个哪里条款可以使用更一般的条件选择行,讨论24.38节,“表达”的扩展

SHOW OPEN TABLES输出具有以下列:

  • Database

    The database containing the table .

  • Table

    表名

  • In_use

    表锁或有表的锁请求数。例如,如果一个客户机获取锁表的使用LOCK TABLE t1 WRITE在使用_将1。如果从另一个客户LOCK TABLE t1 WRITE而表仍锁,客户端会阻塞等待锁,但锁请求的原因在使用_是2。如果计数为零,该表是开放的而不是目前正在使用的。In_use也增加了HANDLER ... OPEN声明和下降HANDLER ... CLOSE

  • Name_locked

    无论是表名是锁着的。名字锁定用于如删除或重命名表操作。

如果你有一台没有特权,它不会显示在输出SHOW OPEN TABLES

13.7.6.25显示插件的语法

SHOW PLUGINS

SHOW PLUGINS显示有关服务器的插件信息。插件的信息中也可information_schema.plugins表看到部分为,“information_schema插件表”

例子SHOW PLUGINS输出:

MySQL的&#62;SHOW PLUGINS\G*************************** 1。行***************************名称:binlog状态:活跃型:存储enginelibrary:nulllicense:GPL *************************** 2。行***************************名称:CSV状态:活跃型:存储enginelibrary:nulllicense:GPL *************************** 3。行***************************名称:内存状态:活跃型:存储enginelibrary:nulllicense:GPL *************************** 4。行***************************名称:MyISAM状态:活跃型:存储enginelibrary:nulllicense:GPL…

SHOW PLUGINS输出具有以下列:

  • Name:指在诸如插件使用的名称INSTALL PLUGINUNINSTALL PLUGIN

  • Status:插件的状态,一个活动中INACTIVE禁用DELETING,或删除

  • Type:类型的插件,如存储引擎INFORMATION_SCHEMA,或认证

  • Library:插件的共享库文件的名称。这是指在诸如插件文件的名称INSTALL PLUGINUNINSTALL PLUGIN。这个文件位于目录命名的plugin_dir系统变量。If the library name is无效的,插件编写和无法卸载与UNINSTALL PLUGIN

  • License:如何插件是许可的;例如,GPL

为插件的安装INSTALL PLUGIN,的姓名Library值也注册在mysql.plugin

关于插件的数据结构的形式显示的信息为基础的信息SHOW PLUGINS,看到28.2节,“MySQL插件API”

13.7.6.26显示特权的语法

SHOW PRIVILEGES

SHOW PRIVILEGES显示,MySQL服务器支持系统权限列表。特权显示包括所有静态的特权,和所有目前注册的动态权限。

MySQL的&#62;SHOW PRIVILEGES\G*************************** 1。行***************************特权:改变背景:表评论:更改表*************************** 2。行***************************特权:改变常规背景:功能,程序注释:改变或删除存储功能/程序*************************** 3。行***************************特权:创设情境:数据库、表、索引评论:创建新的数据库和表*************************** 4。行***************************特权:创建常规语境:评论:使用数据库创建函数/过程*************************** 5。行***************************特权:创建临时表的数据库上下文:评论:使用创建临时表…

属于一个特定的用户权限以SHOW GRANTS声明。看到第13.7.6.21”节目,格兰特的语法”为更多的信息

13.7.6.27显示程序代码的语法

SHOW PROCEDURE CODE proc_name

这个声明是一个mysql扩展,仅适用于已建服务器调试支持。它显示的命名存储过程内部实现的表示。类似的声明,SHOW FUNCTION CODE,显示有关存储功能的信息(见第13.7.6.19,“显示功能代码语法”

使用的语句,你必须有全球SELECT特权

如果指定的程序是可用的,每个语句的结果集。在结果集中的每一行对应一个指令在常规。第一列是Pos这是一个序号,从0开始。第二列指令,其中包含SQL语句(通常是从原来的来源),或一个指令只需要存储程序处理的意义。

mysql> DELIMITER //
mysql> CREATE PROCEDURE p1 ()
    -> BEGIN
    ->   DECLARE fanta INT DEFAULT 55;
    ->   DROP TABLE t2;
    ->   LOOP
    ->     INSERT INTO t3 VALUES (fanta);
    ->     END LOOP;
    ->   END//
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW PROCEDURE CODE p1//
+-----+----------------------------------------+
| Pos | Instruction                            |
+-----+----------------------------------------+
|   0 | set fanta@0 55                         |
|   1 | stmt 9 "DROP TABLE t2"                 |
|   2 | stmt 5 "INSERT INTO t3 VALUES (fanta)" |
|   3 | jump 2                                 |
+-----+----------------------------------------+
4 rows in set (0.00 sec)

在这个例子中,不可执行BEGIN结束报表已经消失,为DECLARE variable_name声明中,只有可执行部分出现(其中部分默认分配)。每个语句是从源,有一个代码字支撑其次是一种手段(9DROP5、均值INSERT,等等)。最后一行包含一个指令跳2,意义GOTO instruction #2

13.7.6.28显示程序状态语法

SHOW PROCEDURE STATUS
    [LIKE 'pattern' | WHERE expr]

这个声明是一个mysql扩展。它返回一个存储过程的特点,如数据库、名称、类型、创建者、创建和修改日期,和字符集信息。类似的声明,SHOW FUNCTION STATUS,显示有关存储功能的信息(见第13.7.6.20,“显示功能语法”

这个LIKE条款,如果存在,表明匹配过程或函数名。这个哪里条款可以使用更一般的条件选择行,讨论24.38节,“表达”的扩展

mysql> SHOW PROCEDURE STATUS LIKE 'sp1'\G
*************************** 1. row ***************************
                  Db: test
                Name: sp1
                Type: PROCEDURE
             Definer: testuser@localhost
            Modified: 2004-08-03 15:29:37
             Created: 2004-08-03 15:29:37
       Security_type: DEFINER
             Comment:
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8mb4_0900_ai_ci

character_set_client是这个会议的价值character_set_client系统变量时的常规创建。粘贴连接是这个会议的价值collation_connection系统变量时的常规创建。collation数据库是整理数据库的日常关联。

您还可以得到关于存储程序的信息ROUTINESinformation_schema。看到第24.20,“information_schema例程表”

13.7.6.29 SHOW PROCESSLIST语法

SHOW [FULL] PROCESSLIST

SHOW PROCESSLIST显示你的线程正在运行。你也可以从得到这个信息information_schemaPROCESSLIST表或mysqladmin列表命令。如果你有PROCESS特权,你可以看到所有的线程。否则,你只能看到你自己的线程(即螺纹与MySQL帐户,您使用)。如果你不使用全部关键词,只有前100个字符中的每个语句Info

过程信息也可从performance_schema.threads表然而,访问threads不需要一个互斥体和对服务器性能的影响最小。INFORMATION_SCHEMA.PROCESSLISTSHOW PROCESSLIST有负面的绩效后果是因为他们需要一个互斥。threads也对后台线程信息,这INFORMATION_SCHEMA.PROCESSLISTSHOW PROCESSLISTdo not。这件事threads可用于监视活动的其他线程的信息来源不。

这个SHOW PROCESSLIST语句非常有用,如果你得到的太多的连接的错误信息,想看看是怎么回事。一个额外的连接MySQL储备被认为有CONNECTION_ADMINSUPER特权,以确保管理员应该能够连接并检查系统(假设你没有给这个特权,你所有的用户)。

线程可以被杀死的KILL声明。看到第13.7.7.4,“杀语法”

下面是一个例子SHOW PROCESSLIST输出:

MySQL &#62;显示完整的列表*************************** \ G 1。行*************************** ID:1user:系统userhost:DB:nullcommand:connecttime:1030455state:等待主人送EventInfo:空*************************** 2。行*************************** ID:用户:系统userhost:DB:nullcommand:connecttime:1004state:读了中继日志;等待Slave I/O线程更新itinfo:空***************************三。行*************************** ID:3112user:replikatorhost:阿耳忒弥斯:2204db:nullcommand:Binlog DumpTime:2144state:已发送的所有binlog奴隶;等待binlog是updatedinfo:空*************************** 4。行*************************** ID:3113user:replikatorhost:iconnect2:45781db:nullcommand:Binlog DumpTime:2086state:已发送的所有binlog奴隶;等待binlog是updatedinfo:空***************************五。行*************************** ID:3123user:stefanhost:localhostdb:apolloncommand:querytime:0state:nullinfo:显示全processlist5行集(0秒)

由柱SHOW PROCESSLIST具有以下含义:

  • Id

    连接标识符。这是显示在值类型相同ID列的INFORMATION_SCHEMA.PROCESSLIST表的processlist_id的性能架构列threads表,并返回的CONNECTION_ID()功能

  • User

    他发表声明的MySQL用户。如果是这样的system user,它指的是一个非工作线程所酿成的服务器来处理任务的内部。这可能是I/O或SQL线程用于复制的奴隶或延迟行处理。出现认证错误有一个线程在处理客户端的连接,但是该客户端认证尚未完成。event_scheduler指线程监视事件。为系统用户,有指定的任何主机Host专栏

  • Host

    在客户端发出声明的主机名(除system user在没有主机)SHOW PROCESSLIST报告的主机名为TCP/IP连接host_nameclient_port格式,使它更容易确定哪些客户是做什么的。

  • db

    默认的数据库,如果被选中,否则NULL

  • Command

    命令执行线程的类型。对于线程命令的说明,见8.14节,“检查线程的信息”。该列的值对应于COM_xxx的客户端/服务器协议的命令和com_xxx变量。See第5.1.9,“服务器状态变量”

  • Time

    在几秒钟的时间,线程已在其当前状态。一个奴隶的SQL线程,价值是过去的复制事件与下位机的实时时间戳之间的秒数。看到第17.2.2,“复制的实施细则》

  • State

    一个动作、事件或状态指示线程正在做什么。描述State价值观可以发现在8.14节,“检查线程的信息”

    大多数州对应很快行动。如果一个线程保持在一个给定的数秒的状态,有可能是一个需要研究的问题。

    对于SHOW PROCESSLIST声明价值状态NULL

  • Info

    声明线程正在执行,或NULL如果不执行任何语句。声明可能是发送到服务器,或内心的声明如果语句执行其他语句。例如,如果一个呼叫语句执行的存储过程的执行SELECT声明的信息显示值SELECT声明

13.7.6.30显示配置文件的语法

SHOW PROFILE [type [, type] ... ]
    [FOR QUERY n]
    [LIMIT row_count [OFFSET offset]]

type:
    ALL
  | BLOCK IO
  | CONTEXT SWITCHES
  | CPU
  | IPC
  | MEMORY
  | PAGE FAULTS
  | SOURCE
  | SWAPS

这个SHOW PROFILESHOW PROFILES报表显示分析信息,显示当前会话中执行的语句的资源使用情况。

笔记

这些陈述是过时的、将在未来的MySQL版本中删除。使用性能模式这instead;第25.18.1,查询分析使用性能模式”

分析是由profiling会话变量,它的默认值为0(关闭)。分析是启用的设置profiling1或打开(放)

mysql> SET profiling = 1;

SHOW PROFILES显示一个列表发送到服务器的最新声明。列表的大小是由profiling_history_size会话变量,其中有15默认值。最大值为100。设定值0已禁用剖面的实际效果。

所有陈述的异形除外SHOW PROFILESHOW PROFILES,所以你会发现在这些陈述没有配置文件列表。畸形的陈述是异形。例如,显示剖面是一个非法的声明,并发生语法错误如果你试图执行它,但它会显示在列表的分析。

SHOW PROFILE显示有关单个语句的详细信息。没有查询n条款,输出属于最近执行的语句。如果查询n包括,SHOW PROFILE语句的信息n。价值观n对应于query_id值显示SHOW PROFILES

这个LIMIT row_count条款可能会限制输出row_count排.如果极限给出了,OFFSET offset可以添加到开始输出offset排成排的全套

默认情况下,SHOW PROFILE显示器地位Duration专栏这个地位价值观是一样的State值显示SHOW PROCESSLIST,虽然可能有一些状态值两陈述解释一些细微的差别(见8.14节,“检查线程的信息”

可选type值可以指定显示具体信息的其他类型:

  • ALL显示所有信息

  • BLOCK IO显示模块的输入和输出操作数

  • CONTEXT SWITCHES表现为自愿和非自愿的上下文切换数

  • CPU显示用户和系统CPU的使用时间

  • IPC显示重要邮件的发送和接收

  • MEMORY目前未实现

  • PAGE FAULTS显示主要和次要的页面错误数

  • SOURCE显示函数的名字从源代码,加上名字和函数所发生的文件行数

  • SWAPS交换计数显示

启用会话分析。当会议结束时,其剖面信息丢失。

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

mysql> SET profiling = 1;
Query OK, 0 rows affected (0.00 sec)

mysql> DROP TABLE IF EXISTS t1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> CREATE TABLE T1 (id INT);
Query OK, 0 rows affected (0.01 sec)

mysql> SHOW PROFILES;
+----------+----------+--------------------------+
| Query_ID | Duration | Query                    |
+----------+----------+--------------------------+
|        0 | 0.000088 | SET PROFILING = 1        |
|        1 | 0.000136 | DROP TABLE IF EXISTS t1  |
|        2 | 0.011947 | CREATE TABLE t1 (id INT) |
+----------+----------+--------------------------+
3 rows in set (0.00 sec)

mysql> SHOW PROFILE;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| checking permissions | 0.000040 |
| creating table       | 0.000056 |
| After create         | 0.011363 |
| query end            | 0.000375 |
| freeing items        | 0.000089 |
| logging slow query   | 0.000019 |
| cleaning up          | 0.000005 |
+----------------------+----------+
7 rows in set (0.00 sec)

mysql> SHOW PROFILE FOR QUERY 1;
+--------------------+----------+
| Status             | Duration |
+--------------------+----------+
| query end          | 0.000107 |
| freeing items      | 0.000008 |
| logging slow query | 0.000015 |
| cleaning up        | 0.000006 |
+--------------------+----------+
4 rows in set (0.00 sec)

mysql> SHOW PROFILE CPU FOR QUERY 2;
+----------------------+----------+----------+------------+
| Status               | Duration | CPU_user | CPU_system |
+----------------------+----------+----------+------------+
| checking permissions | 0.000040 | 0.000038 |   0.000002 |
| creating table       | 0.000056 | 0.000028 |   0.000028 |
| After create         | 0.011363 | 0.000217 |   0.001571 |
| query end            | 0.000375 | 0.000013 |   0.000028 |
| freeing items        | 0.000089 | 0.000010 |   0.000014 |
| logging slow query   | 0.000019 | 0.000009 |   0.000010 |
| cleaning up          | 0.000005 | 0.000003 |   0.000002 |
+----------------------+----------+----------+------------+
7 rows in set (0.00 sec)
笔记

分析只是部分功能在某些架构。这取决于价值观getrusage()系统调用,无效的在系统如不支持调用Windows返回。此外,分析每个过程并不是每个线程。这意味着活动的线程在服务器内的其他比自己可能影响你看到的时间信息。

你也可以分析信息,从PROFILINGinformation_schema。看到24.17节,“information_schema分析表”。例如,下面的查询生成相同的结果:

SHOW PROFILE FOR QUERY 2;

SELECT STATE, FORMAT(DURATION, 6) AS DURATION
FROM INFORMATION_SCHEMA.PROFILING
WHERE QUERY_ID = 2 ORDER BY SEQ;

13.7.6.31显示配置文件的语法

SHOW PROFILES

这个SHOW PROFILES声明,连同SHOW PROFILE分析表明,显示信息为当前会话中执行的语句的资源使用情况。有关更多信息,参见第13.7.6.30,“显示简介语法”

笔记

这些陈述是过时的、将在未来的MySQL版本中删除。使用性能模式相反;看第25章,MySQL性能模式

13.7.6.32显示relaylog事件语法

SHOW RELAYLOG EVENTS
    [IN 'log_name']
    [FROM pos]
    [LIMIT [offset,] row_count]
    [channel_option]

channel_option:
    FOR CHANNEL channel

显示在一个复制从中继日志事件。如果你不指定'log_name',第一中继日志显示。这句话对主人没有影响。

这个LIMIT条款具有相同的语法为SELECT声明。看到第13.2.10,选择“语法”

笔记

发行SHOW RELAYLOG EVENTS没有极限条款可以启动一个非常的时间和资源消耗的过程因为服务器返回给客户端的中继日志内容完整(包括所有报表的修改已经由从接收到的数据)。

可选FOR CHANNEL channel条款使你名字的声明适用于复制通道。提供一个通道channel条款适用于声明特定复制通道。如果没有通道命名并没有额外的渠道存在,该声明适用于默认频道。

当使用多个复制的渠道,如果SHOW RELAYLOG EVENTS声明没有定义一个通道使用通道channel生成子句错误。看到第17.2.3,“复制通道”更多信息

SHOW RELAYLOG EVENTS显示以下字段中的每一个事件的中继日志:

  • Log_name

    那是被列出的文件的名称。

  • Pos

    在该事件发生的位置

  • Event_type

    这是个describes事件标识符的类型。

  • Server_id

    服务器ID的服务器的事件的起源。

  • End_log_pos

    价值End_log_pos此事件在主人的二进制日志。

  • Info

    更多关于事件类型的详细信息。这些信息的格式取决于事件类型。

笔记

关于用户变量和系统变量的设置一些事件不包括在输出SHOW RELAYLOG EVENTS。在中继日志得到事件的完整报道,使用mysqlbinlog

13.7.6.33显示从主机的语法

SHOW SLAVE HOSTS

显示一个列表复制奴隶目前注册的主人。

SHOW SLAVE HOSTS应该是在一个服务器作为复制执行。声明显示或已连接复制奴隶服务器的信息,每一行对应一个从属服务器的结果,如下所示:

MySQL的&#62;SHOW SLAVE HOSTS;------------ ----------- ------ ----------- -------------------------------------- | server_id |主机|港口| master_id | slave_uuid | ------------ ----------- ------ ----------- -------------------------------------- | 192168010 | iconnect2 | 3306 | 192168011 | 14cb6624-7f93-11e0-b2c0-c80aa9429562 | | 1921680101 |雅典娜| 3306 | 192168011 | 07af4990-f41f-11df-a566-7ac56fdaf645 | ------------ ----------- ------ ----------- --------------------------------------
  • Server_id:的从属服务器唯一的服务器ID,如从服务器的设置文件,或在命令行--server-id=value

  • Host:与从指定的主机名的从属服务器--report-host选项这可以从不同的机器名为配置操作系统。

  • User:从服务器的用户名,在指定的奴隶--report-user选项报表输出包括本栏只有主服务器开始的--show-slave-auth-info选项

  • Password:从服务器的密码,在指定的奴隶--report-password选项报表输出包括本栏只有主服务器开始的--show-slave-auth-info选项

  • Port:在主的从属服务器监听的端口,如在指定的奴隶--report-port选项

    10在本专栏意味着从端口(--report-port)没有设置

  • Master_id:那是复制从服务器从主服务器唯一的服务器ID。这是服务器上的服务器ID显示从主机被执行,所以这个相同的值列中的每一行的结果。

  • Slave_UUID:这个奴隶的全局唯一的ID,生成对奴隶和奴隶的发现auto.cnf文件

13.7.6.34 SHOW SLAVE STATUS语法

SHOW SLAVE STATUS [FOR CHANNEL channel]

这一说法提供了对线程的状态信息从基本参数。它需要的SUPERREPLICATION CLIENT特权

SHOW SLAVE STATUS是非阻塞。当运行的同时STOP SLAVE表明奴隶的身份返回而不等待STOP SLAVE要完成关闭从SQL线程或从I/O线程(或两者)。这允许使用监控等应用中得到立即的反应表明奴隶的身份比确保它返回最新的数据更重要。

如果你发的这个声明中使用MySQL客户端,您可以使用\G语句终止符而不是分号获得更可读的竖向布置:

MySQL的&#62;SHOW SLAVE STATUS\G*************************** 1。行*************************** slave_io_state:等待主人送事件master_host:localhost master_user:REPL master_port:13000 connect_retry:60 master_log_file:master-bin.000002 read_master_log_pos:1307 relay_log_file:slave-relay-bin.000003 relay_log_pos:1508年relay_master_log_file:master-bin.000002 slave_io_running:是的slave_sql_running:是的replicate_do_db:replicate_ignore_db:replicate_do_table:replicate_ignore_table:replicate_wild_do_table:replicate_wild_ignore_table:last_errno:0 last_error:skip_counter:0 exec_master_log_pos:::没有until_condition relay_log_space 1307年until_log_file:until_log_pos:0 master_ssl_allowed:没有master_ssl_ca_file:master_ssl_ca_path:master_ssl_cert:master_ssl_cipher:master_ssl_key:seconds_behind_master:0master_ssl_verify_server_cert:没有last_io_errno:0 last_io_error:last_sql_errno:0 last_sql_error:replicate_ignore_server_ids:master_server_id:1 master_uuid:3e11fa47-71ca-11e1-9e33-c80aa9429562 master_info_file:/无功/ mysqld.2/data/master.info sql_delay:0 sql_remaining_delay:空slave_sql_running_state:阅读从中继日志master_retry_count事件:10 master_bind:last_io_error_timestamp:last_sql_error_timestamp:master_ssl_crl:master_ssl_crlpath:retrieved_gtid_set:3e11fa47-71ca-11e1-9e33-c80aa9429562:1-5 executed_gtid_set:3e11fa47-71ca-11e1-9e33-c80aa9429562:1-5 auto_position:1 replicate_rewrite_db:channel_name:master_tls_version:tlsv1.2 master_public_key_path:public_key.pem get_master_public_key:0

性能架构提供表格,将复制的信息。这是类似于从现有的信息SHOW SLAVE STATUS声明,但表示表。详情见第25.11.11,绩效模式复制表”

下面的列表描述了场返回SHOW SLAVE STATUS。更多信息关于解释其含义,看第17.1.7.1,“检查复制状态”

  • Slave_IO_State

    一个副本的State场的SHOW PROCESSLIST对奴隶的I/O线输出。这告诉你什么是线程做:尝试连接的主人,等待主人的事件,重新连接到主,等等。一个可能状态的列表,参见第8.14.4,“复制从I/O线程状态”

  • Master_Host

    主人主人,奴隶是连接。

  • Master_User

    连接到主机使用的帐户的用户名称。

  • Master_Port

    端口用于连接到主

  • Connect_Retry

    连接重试之间的秒数(默认为60)。这可以设置与CHANGE MASTER TO声明

  • Master_Log_File

    主人的名字二进制日志文件的I/O线程当前正在阅读。

  • Read_Master_Log_Pos

    在目前掌握的二进制日志位置文件的I/O线程读取。

  • Relay_Log_File

    姓名的中继日志文件从SQL线程正在读取和执行。

  • Relay_Log_Pos

    在目前的位置上中继日志文件,SQL线程读取和执行。

  • Relay_Master_Log_File

    大师的二进制日志文件包含由SQL线程执行的最近的事件的名称。

  • Slave_IO_Running

    是I/O线程开始,已经成功地连接到主。在内部,这个线程的状态是由以下三个值表示:

    • mysql_slave_not_run。从I/O线程没有运行。这种状态,Slave_IO_Running

    • mysql_slave_run_not_connect。从I/O线程正在运行,但没有连接到复制。这种状态,Slave_IO_Running连接

    • mysql_slave_run_connect。从I/O线程正在运行,并连接到复制。这种状态,Slave_IO_Running

    的价值Slave_running系统状态变量的对应值。

  • Slave_SQL_Running

    是否SQL线程开始

  • Replicate_Do_DB不知道replicate _ _分贝

    所指定的数据库的名称--replicate-do-db--replicate-ignore-db选项,或CHANGE REPLICATION FILTER声明。如果通道使用条款,具体复制过滤器显示通道。否则,每个复制通道复制过滤器显示。

  • Replicate_Do_Tablereplicate_ignore_tableReplicate_Wild_Do_Tablereplicate_wild_ignore_table

    所指定的任何表名称--replicate-do-table--replicate-ignore-table--replicate-wild-do-table,和--replicate-wild-ignore-table选项,或CHANGE REPLICATION FILTER声明。如果通道使用条款,具体复制过滤器显示通道。否则,每个复制通道复制过滤器显示。

  • Last_Errno最后_错误

    这些列别名Last_SQL_Errnolast_sql_error

    发行RESET MASTERRESET SLAVE在这些列中显示的值重置。

    笔记

    当从SQL线程接收到一个错误,它报告错误,然后停止SQL线程。这意味着在这时间的一个小窗口SHOW SLAVE STATUS显示一个非零的值最后_ SQL _ errno尽管Slave_SQL_Running仍然显示

  • Skip_Counter

    的电流值sql_slave_skip_counter系统变量。见第13.4.2.5,“全球sql_slave_skip_counter语法”

  • Exec_Master_Log_Pos

    位置在当前掌握二进制日志文件的SQL线程读取和执行,标志着未来的交易或事项要处理的开始。您可以使用此值与CHANGE MASTER TO声明的master_log_pos选择从现有的从新的奴隶时,使新奴隶读取这一点。坐标由(Relay_Master_Log_Fileexec_master_log_pos)在主人的二进制日志中对应的坐标(Relay_Log_Filerelay_log_pos在中继日志)

    从中继日志已执行的交易序列不一致导致该值是一个低水位。换句话说,交易出现在位置保证承诺,但交易后的位置可能已犯或不。如果这些差距需要修正,使用START SLAVE UNTIL SQL_AFTER_MTS_GAPS。看到第17.4.1.34,“复制和事务不一致”更多信息

  • Relay_Log_Space

    所有现有的中继日志文件的总大小。

  • Until_Conditionuntil_log_fileUntil_Log_Pos

    在指定的值UNTIL的条款START SLAVE声明

    Until_Condition这些价值观:

    • None如果没有直到指定的条款

    • Master如果从阅读到了主人的二进制日志位置

    • Relay如果从阅读到给定的中继日志的位置

    • SQL_BEFORE_GTIDS如果从SQL线程处理交易,直到它达到第一个事务的gtid列在gtid _看到

    • SQL_AFTER_GTIDS如果从线程处理所有的交易在最后交易gtid _看到已由螺纹加工

    • SQL_AFTER_MTS_GAPS如果一个多线程的奴隶的SQL线程正在运行,直到没有更多的差距是在中继日志发现。

    Until_Log_Fileuntil_log_pos显示日志文件的名称和位置,确定坐标,SQL线程停止执行。

    更多信息UNTIL跨标点,这第13.4.2.6,“开始从语法”

  • Master_SSL_Allowedmaster_ssl_ca_fileMaster_SSL_CA_Path主_ _ SSL证书Master_SSL_Ciphermaster_ssl_crl_fileMaster_SSL_CRL_Path硕士_ SSL _ keyMaster_SSL_Verify_Server_Cert

    这场由奴隶用来连接主SSL参数,如果任何。

    Master_SSL_Allowed这些价值观:

    • Yes如果一个SSL连接到主是允许的

    • No如果一个SSL连接到主是不允许的

    • Ignored如果一个SSL连接是允许的但从服务器没有启用SSL的支持

    其他的SSL相关字段的值对应的值MASTER_SSL_CAmaster_ssl_capathMASTER_SSL_CERT硕士_ SSL _ cipherMASTER_SSL_CRLmaster_ssl_crlpathMASTER_SSL_KEY,和master_ssl_verify_server_cert选择的CHANGE MASTER TO声明。看到第13.4.2.1,“变化掌握语法”

  • Seconds_Behind_Master

    这是一个如何的迹象晚的奴隶:

    • 当奴隶是积极处理更新,此字段显示当前时间戳的奴隶之间的区别和原始时间戳登录事件目前正在处理的奴隶主。

    • 当没有事件正在对奴隶进行处理,这个值是0。

    在本质上,这场措施秒之间的时间差,从SQL线程和从I/O线程。如果主人和奴隶之间的网络连接速度很快,从I/O线程是非常接近的主,所以这场是多么晚从SQL线程相比,主人的一个很好的近似。如果网络速度很慢,这是一个很好的近似;从SQL线程往往会被赶上了慢速阅读从I/O线程,所以Seconds_Behind_Master通常显示的值为0,即使I/O线程是比较晚的主人。换句话说,本栏目仅用来快速网络

    即使主人和奴隶不具有相同的时钟时间,这个时间差计算工作,提供这样的差异,计算当奴隶的I/O线程开始,还是从此不变。任何变化包括NTP更新会导致时钟偏移,可以使计算Seconds_Behind_Master不可靠的

    在MySQL 8中,这场NULL(定义的或未知的)如果从SQL线程没有运行,或如果SQL线程消耗了所有的中继日志和从I/O线程没有运行。(在老版本的MySQL,这场无效的如果从SQL线程或从I/O线程没有运行或者没有连接到主。)如果I/O线程正在运行但中继日志了,Seconds_Behind_Master设置为0

    价值Seconds_Behind_Master基于存储在事件的时间戳,并保存通过复制。这意味着,如果一个掌握M1本身就是一个奴隶M0,M1是从二进制日志源于M0的二进制日志的任何事件的时间戳,M0的事件。这使得MySQL复制TIMESTAMP成功。然而,问题在_硕士_ seconds是,如果M1还接收来自客户直接更新的Seconds_Behind_Master值随机波动有时候从M1的最后事件源自M0和M1有时是直接更新的结果。

    使用多线程的奴隶的时候,你应该记住这个值是基于Exec_Master_Log_Pos,因此可能无法反映最近提交的事务的位置。

  • Last_IO_Errno最后我_ _误差

    导致I/O线程停止最新的错误消息的错误号和错误。0、传递空字符串平均错误数没有错误如果Last_IO_Error价值不是空的,误差值也出现在奴隶的错误日志。

    I/O错误信息包含一个时间戳显示时出现最新的I/O线程错误。该时间戳的使用格式YYMMDD HH:MM:SS,并出现在last_io_error_timestamp专栏

    发行RESET MASTERRESET SLAVE在这些列中显示的值重置。

  • Last_SQL_Errnolast_sql_error

    导致SQL线程停止最新的错误消息的错误号和错误。0、传递空字符串平均错误数没有错误如果Last_SQL_Error价值不是空的,误差值也出现在奴隶的错误日志。

    如果奴隶是多线程的,SQL线程是线程的协调员。在这种情况下,的Last_SQL_Error现场展示什么last_error_message在绩效架构列replication_applier_status_by_coordinator表格显示。字段值的修改建议,有可能在其他线程可以在更多的失败replication_applier_status_by_worker表格显示每个工作线程的状态。如果表不可用,从错误日志可以使用。日志或replication_applier_status_by_worker表也应该用来学习更多关于显示的故障SHOW SLAVE STATUSor the Coordinator Table .

    SQL错误信息包含一个时间戳显示最新的SQL线程时发生错误。该时间戳的使用格式YYMMDD HH:MM:SS,并出现在last_sql_error_timestamp专栏

    发行RESET MASTERRESET SLAVE在这些列中显示的值重置。

    在MySQL 5.0,所有错误代码和消息显示在Last_SQL_Errnolast_sql_error列对应列在误差值第三,“服务器错误代码和消息”。这并不是真的在以前的版本。(错误# 11760365,错误# 52768)

  • Replicate_Ignore_Server_Ids

    任何服务器ID已经指定使用IGNORE_SERVER_IDS期权的CHANGE MASTER TO语句,使奴隶忽略事件从这些服务器。此选项用于圆形或其他多主复制安装时其中一个服务器被删除。如果任何服务器的入侵检测系统已经建立这样一个逗号分隔的一个或多个数据列表显示。如果没有服务器的入侵检测系统已经建立,该字段为空。

    笔记

    这个Ignored_server_ids中的价值slave_master_info表还显示服务器ID被忽视,但作为一个空间分隔的列表,在服务器ID总数被忽视。例如,如果一个CHANGE MASTER TO声明包含IGNORE_SERVER_IDS = (2,6,9)选择已发出告诉奴隶忽视让服务器ID 2, 6,硕士或9,信息会出现如下图所示:

    	Replicate_Ignore_Server_Ids: 2, 6, 9
    
    ignored_server_ids:3, 2, 6,9

    Replicate_Ignore_Server_Ids过滤是通过I/O线程执行,而不是由SQL线程,这意味着过滤事件没有写入中继日志。这不同于过滤操作的服务器选项了--replicate-do-table,适用于SQL线程

    笔记

    从MySQL 8.0.3,折旧,警告如果SET GTID_MODE=ON发出时,任何现有的服务器ID设置通道ignore_server_ids。在开始gtid通过复制、使用SHOW_SLAVE_STATUS检查并清楚服务器的所有忽视服务器ID列表。你可以通过发布一个明确的清单CHANGE MASTER TO声明包含ignore_server_ids一个空的列表选项

  • Master_Server_Id

    这个server_id从主值

  • Master_UUID

    这个server_uuid从主值

  • Master_Info_File

    的位置master.info文件,如果文件不是一台用于奴隶主信息库。

  • SQL_Delay

    那个奴隶主必须延迟秒数。

  • SQL_Remaining_Delay

    什么时候Slave_SQL_Running_State等到主人执行事件后master_delay秒本字段包含,延迟秒数。在其他时候,这场NULL

  • Slave_SQL_Running_State

    的SQL线程的状态(类似于Slave_IO_State)。价值是相同的状态值的SQL线程显示SHOW PROCESSLIST第8.14.5,“SLAVE端状态”,提供了一种可能的状态列表

  • Master_Retry_Count

    时代的奴隶可以尝试重新连接在连接丢失事件的总体数量。这个值可以设置使用MASTER_RETRY_COUNT期权的CHANGE MASTER TO声明(首选)或以上--master-retry-count服务器选项(仍然支持向后兼容)。

  • Master_Bind

    认为奴隶是绑定到网络接口,如果任何。这是一套使用MASTER_BIND选择for theCHANGE MASTER TO声明

  • Last_IO_Error_Timestamp

    一个时间戳YYMMDD HH:MM:SS格式显示在最近的I/O错误发生。

  • Last_SQL_Error_Timestamp

    一个时间戳YYMMDD HH:MM:SS格式显示当最后出现SQL错误。

  • Retrieved_Gtid_Set

    全局事务ID对应的从属收到所有交易设定。如果不使用空gtids。看到gtid集更多信息

    这是一套所有gtids存在或已经存在的中继日志。每个gtid添加等Gtid_log_event收到。这可能会导致部分发送的交易有其gtids纳入集。

    当所有的中继日志是由于执行了RESET SLAVECHANGE MASTER TO,或由于的影响--relay-log-recovery选项,设置是cleared。当relay_log_purge = 1,最新的中继日志总是保持,和设置不清零。

  • Executed_Gtid_Set

    全局事务ID写在二进制日志设置。这是作为全球价值相同gtid_executed此服务器上的系统变量,以及价值executed_gtid_set在输出SHOW MASTER STATUS此服务器上的。如果不使用空gtids。看到gtid集更多信息

  • Auto_Position

    如果是在1 autopositioning使用;否则为0。

  • Replicate_Rewrite_DB

    这个Replicate_Rewrite_DB值显示任何复制的过滤规则,指定。例如,如果下面的复制过滤规则设置:

    CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB=((db1,db2), (db3,db4));

    这个Replicate_Rewrite_DB显示值:

    2 .复制(DB1,DB2),(DB3,DB4)

    有关更多信息,参见第13.4.2.2,“改变复制筛选器语法”

  • Channel_name

    复制通道被显示。总是有一个默认的复制通道,并复制通道可以增加更多的。看到第17.2.3,“复制通道”更多信息

  • Master_TLS_Version

    用在主的TLS版本。TLS的版本信息,看第6.4.6,“加密连接协议和密码”

  • Master_public_key_path

    一种含有一个由RSA密钥对的密码交换所必须掌握的公共密钥从复制文件的路径名。该文件必须在PEM格式。本栏适用于奴隶的鉴定与sha256_passwordcaching_sha2_password身份验证插件

    如果Master_public_key_path给出指定有效的公钥文件,它将优先于get_master_public_key

  • Get_master_public_key

    无论是从主人的RSA密钥对的公钥密码交换所需的基础要求。本栏适用于奴隶的鉴定与caching_sha2_password身份验证插件。这个插件,师傅不发送公钥除非要求。

    如果Master_public_key_path给出指定有效的公钥文件,它将优先于get_master_public_key

13.7.6.35显示状态语法

SHOW [GLOBAL | SESSION] STATUS
    [LIKE 'pattern' | WHERE expr]

SHOW STATUS提供服务器状态信息(见第5.1.9,“服务器状态变量”)。这句话不需要任何特权。它只需要连接到服务器的能力。

状态变量的信息也可以从这些来源:

SHOW STATUS,一个LIKE条款,如果存在的话,表示匹配的变量名。一哪里条款可以使用更一般的条件选择行,讨论24.38节,“表达”的扩展

SHOW STATUS接受一个可选的全球SESSION可变范围修饰符:

  • 用一个GLOBAL改性剂,声明显示全局状态值。一个全局状态变量可能是服务器本身的一些方面的地位(例如,aborted_connects),或聚集状态在所有连接到MySQL(例如,Bytes_receivedbytes_sent)。如果一个变量没有全球价值,会话值显示。

  • 用一个SESSION改性剂,声明显示状态变量的值为当前连接。如果一个变量没有会话值显示,全球价值。当地是同义词SESSION

  • 如果没有修饰符,默认是SESSION

每个状态变量的范围是在上市第5.1.9,“服务器状态变量”

每次调用的SHOW STATUS语句使用内部临时表和增量的全球Created_tmp_tables价值

部分输出如下所示。名称和值的列表可能与您的服务器。每个变量的含义了第5.1.9,“服务器状态变量”

mysql> SHOW STATUS;
+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| Aborted_clients          | 0          |
| Aborted_connects         | 0          |
| Bytes_received           | 155372598  |
| Bytes_sent               | 1176560426 |
| Connections              | 30023      |
| Created_tmp_disk_tables  | 0          |
| Created_tmp_tables       | 8340       |
| Created_tmp_files        | 60         |
...
| Open_tables              | 1          |
| Open_files               | 2          |
| Open_streams             | 0          |
| Opened_tables            | 44600      |
| Questions                | 2026873    |
...
| Table_locks_immediate    | 1920382    |
| Table_locks_waited       | 0          |
| Threads_cached           | 0          |
| Threads_created          | 30022      |
| Threads_connected        | 1          |
| Threads_running          | 1          |
| Uptime                   | 80380      |
+--------------------------+------------+

用一个LIKE条款,声明显示这些变量与该模式匹配的名字才行:

MySQL的&#62;SHOW STATUS LIKE 'Key%';-------------------- ---------- | variable_name |价值| -------------------- ---------- | key_blocks_used | 14955 | | key_read_requests | 96854827 | | key_reads | 162040 | | key_write_requests | 7589728 | | key_writes | 3813196 | -------------------- ----------

13.7.6.36显示表状态语法

SHOW TABLE STATUS
    [{FROM | IN} db_name]
    [LIKE 'pattern' | WHERE expr]

SHOW TABLE STATUS作品喜欢SHOW TABLES,但提供了大量的关于每个非信息—临时表你也可以把这个列表的使用mysqlshow -现状db_name命令。这个LIKE条款,如果存在的话,表示匹配的表名。这个哪里条款可以使用更一般的条件选择行,讨论24.38节,“表达”的扩展

该声明还显示有关的观点。

SHOW TABLE STATUS输出具有以下列:

  • Name

    的名称的表

  • Engine

    该表的存储引擎。看到第十六章,选择存储引擎

  • Version

    这场闲置

  • Row_format

    行存储格式(Fixed动态Compressed冗余Compact)。是MyISAM(桌子,Dynamic对应于什么DVB - myisamchk报告Packed

  • Rows

    行数。某些存储引擎,如MyISAM,商店的确切数目。其他的存储引擎,如InnoDB,这个值是近似的,并可能会有所不同从实际价值高达40到50%。在这种情况下,使用SELECT COUNT(*)为了获得准确的计数

    这个Rows无效的表的INFORMATION_SCHEMA数据库

  • Avg_row_length

    平均的行长度

  • Data_length

    MyISAM_日期长度是数据文件的长度,以字节为单位。

    InnoDB_日期长度是分配给群集索引存储的近似值,在字节。具体地说,它是在页面的聚集索引的大小,乘以InnoDB页面大小

    指在本节对于其他存储引擎信息末端的笔记。

  • Max_data_length

    MyISAM_ _最大数据长度是数据文件的最大长度。这是数据可以存储在表中的总字节数,给出数据指针的大小用。

    未使用的InnoDB

    指在本节对于其他存储引擎信息末端的笔记。

  • Index_length

    MyISAMindex_length是索引文件的长度,以字节为单位。

    InnoDBindex_length是分配给非聚集索引的存储量大约在字节。具体地说,它是在页面的非聚集索引的大小的总和,乘以InnoDB页:1

    指在本节对于其他存储引擎信息末端的笔记。

  • Data_free

    《数allocated但未用的字节。

    这个信息也显示InnoDB表(以前,它是在评论值)InnoDB表报告的自由空间的表空间,表。一台位于共享表空间,这是共享表空间的自由空间。如果你正在使用多个表空间和表都有自己的空间,自由的空间只表。自由空间是完全免费的程度负安全边际的字节数。即使自由空间显示为零,可以插入行只要不需要分配新的程度。

    对于分区表,这个价值只是一个估计,可能不完全正确。在这种情况下,这一信息更准确的方法是查询INFORMATION_SCHEMA.PARTITIONS表,如图所示:

    SELECT    SUM(DATA_FREE)    FROM  INFORMATION_SCHEMA.PARTITIONS    WHERE TABLE_SCHEMA = 'mydb'    AND   TABLE_NAME   = 'mytable';

    有关更多信息,参见24.14节,“information_schema分区表”

  • Auto_increment

    下一个AUTO_INCREMENT价值

  • Create_time

    创建表时

  • Update_time

    当数据文件的最后更新。对于一些存储引擎,这个值是NULL。例如,InnoDB商店里的多个表系统片和数据文件的时间戳不适用。即使文件表模式一InnoDB在一个单独的表鸡传染性法氏囊病文件,变化的缓冲可以延迟写入数据文件,所以文件修改时间是不同的从上插入、更新或删除时。为MyISAM,数据文件的时间戳使用;然而,在Windows的时间戳不更新更新这样值不准确。

  • Check_time

    当表格最后检查。不是所有的存储引擎的更新时间,在这种情况下,该值始终是NULL

  • Collation

    表的字符集和整理

  • Checksum

    “生活checksum value(如果任何)。

  • Create_options

    额外的选项used withCREATE TABLE。原始选项CREATE TABLE被称为保留选项报告可能不同于主动表设置和选项。

    InnoDB表,实际row_formatKEY_BLOCK_SIZE报告选项。在以前的版本,创建_选项最初提供的报告ROW_FORMATkey_block_size。有关更多信息,参见第13.1.18,“创建表的语法

  • Comment

    评论用在创建表时(或信息是为什么MySQL无法访问表的信息)。

笔记

  • MEMORY表的_日期长度Max_data_length,和index_length值近似实际分配的内存量。分配算法保留内存在大量减少分配次数。

  • 对于所有的视图,显示市场SHOW TABLE STATUS无效的除了Name显示视图名称和评论view

13.7.6.37显示表的语法

SHOW [EXTENDED] [FULL] TABLES
    [{FROM | IN} db_name]
    [LIKE 'pattern' | WHERE expr]

SHOW TABLES列出了非—临时在一个给定的数据库表。你也可以把这个列表的使用MySQLShowdb_name命令。这个LIKE条款,如果存在的话,表示匹配的表名。这个哪里条款可以使用更一般的条件选择行,讨论24.38节,“表达”的扩展

匹配的行LIKE条款是依赖的设置lower_case_table_names系统变量

可选EXTENDED改性剂的原因SHOW TABLES列出隐藏表创建失败ALTER TABLE声明.这些临时表的名字开始# SQL可降低使用DROP TABLE

该报告还列出了数据库中的视图。可选FULL改性剂的原因SHOW TABLES与第二输出列中显示的值基表一桌VIEW一个视图

如果你有一个基表或视图没有特权,它不会显示在输出SHOW TABLESmysqlshow _ DB NAME

13.7.6.38显示触发器语法

SHOW TRIGGERS
    [{FROM | IN} db_name]
    [LIKE 'pattern' | WHERE expr]

SHOW TRIGGERS触发器定义为当前数据库中的表列表(默认的数据库,除非条款给出)。该语句返回结果只对数据库和表,你有TRIGGER特权。这个LIKE条款,如果存在,表明匹配表的名称(不触发的名字),导致语句来显示这些表的触发器。这个哪里条款可以使用更一般的条件选择行,讨论24.38节,“表达”的扩展

对于触发ins_sum定义23.3节,“使用触发器”,本声明的输出如下所示:

mysql> SHOW TRIGGERS LIKE 'acc%'\G
*************************** 1. row ***************************
             Trigger: ins_sum
               Event: INSERT
               Table: account
           Statement: SET @sum = @sum + NEW.amount
              Timing: BEFORE
             Created: 2013-07-09 10:39:34.96
            sql_mode: NO_ENGINE_SUBSTITUTION
             Definer: me@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8mb4_0900_ai_ci

SHOW TRIGGERS输出具有以下列:

  • Trigger:触发器名称

  • Event:操作导致触发激活的类型。的价值“插入”'UPDATE',或“删除”

  • Table:该表定义了触发器

  • Statement:触发体;即,语句执行时触发激活。

  • Timing:是否触发激活之前或之后的触发事件。的价值“之前”'AFTER'

  • Created:日期和时间时,触发器的创建。这是一个时间戳(2)价值(与小数部分以百分之一秒)触发器。

  • sql_mode:SQL模式效果触发时执行。

  • Definer:谁创造了触发用户帐户,在&#39;user_name“@”host_name&#39;格式

  • character_set_client的会话值:character_set_client系统变量时,触发器的创建。

  • collation_connection的会话值:collation_connection系统变量时,触发器的创建。

  • Database Collation:整理数据库的触发器是相关的。

你也可以从中获得关于触发对象的信息INFORMATION_SCHEMA,其中包含一个TRIGGERS表看到24.30节,“information_schema触发器表”

13.7.6.39显示变量的语法

SHOW [GLOBAL | SESSION] VARIABLES
    [LIKE 'pattern' | WHERE expr]

SHOW VARIABLES为MySQL系统变量的值(见第5.1.7,服务器“系统变量”)。这句话不需要任何特权。它只需要连接到服务器的能力。

系统变量的信息也可以从这些来源:

SHOW VARIABLES,一个LIKE条款,如果存在的话,表示匹配的变量名。一哪里条款可以使用更一般的条件选择行,讨论24.38节,“表达”的扩展

SHOW VARIABLES接受一个可选的全球SESSIONmodifier变量的范围:

  • 用一个GLOBAL改性剂的声明显示,全球系统变量的值。这些都是用来初始化MySQL连接相应的会话变量的值。如果一个变量没有全球价值,没有价值的显示。

  • 用一个SESSION改性剂的声明显示的系统变量的值是在对当前的连接。如果一个变量没有会话值显示,全球价值。当地是同义词SESSION

  • 如果没有修饰符,默认是SESSION

每一个系统变量的范围是在上市第5.1.7,服务器“系统变量”

SHOW VARIABLES受版本依赖显示宽度的限制。变量的值很长不完全显示,使用SELECT作为一个workaround。例如:

选择@ @ global.innodb _ _ _路径文件的日期;

大多数的系统变量可以设置在服务器启动(只读变量,如version_comment有例外)。许多可以在运行时的变化SET声明。看到5.1.8节,“使用系统变量”,和第13.7.5.1,”句法变量赋值”

部分输出如下所示。名称和值的列表可能与您的服务器。第5.1.7,服务器“系统变量”描述变量,the meaning of each,and第5.1.1条,“配置服务器”提供有关信息,调整

mysql> SHOW VARIABLES;
+--------------------------------------------+------------------------------+
| Variable_name                              | Value                        |
+--------------------------------------------+------------------------------+
| activate_all_roles_on_login                | OFF                          |
| auto_generate_certs                        | ON                           |
| auto_increment_increment                   | 1                            |
| auto_increment_offset                      | 1                            |
| autocommit                                 | ON                           |
| automatic_sp_privileges                    | ON                           |
| avoid_temporal_upgrade                     | OFF                          |
| back_log                                   | 151                          |
| basedir                                    | /usr/                        |
| big_tables                                 | OFF                          |
| bind_address                               | *                            |
| binlog_cache_size                          | 32768                        |
| binlog_checksum                            | CRC32                        |
| binlog_direct_non_transactional_updates    | OFF                          |
| binlog_error_action                        | ABORT_SERVER                 |
| binlog_expire_logs_seconds                 | 2592000                      |
| binlog_format                              | ROW                          |
| binlog_group_commit_sync_delay             | 0                            |
| binlog_group_commit_sync_no_delay_count    | 0                            |
| binlog_gtid_simple_recovery                | ON                           |
| binlog_max_flush_queue_time                | 0                            |
| binlog_order_commits                       | ON                           |
| binlog_row_image                           | FULL                         |
| binlog_row_metadata                        | MINIMAL                      |
| binlog_row_value_options                   |                              |
| binlog_rows_query_log_events               | OFF                          |
| binlog_stmt_cache_size                     | 32768                        |
| binlog_transaction_dependency_history_size | 25000                        |
| binlog_transaction_dependency_tracking     | COMMIT_ORDER                 |
| block_encryption_mode                      | aes-128-ecb                  |
| bulk_insert_buffer_size                    | 8388608                      |

...

| max_allowed_packet                         | 67108864                     |
| max_binlog_cache_size                      | 18446744073709547520         |
| max_binlog_size                            | 1073741824                   |
| max_binlog_stmt_cache_size                 | 18446744073709547520         |
| max_connect_errors                         | 100                          |
| max_connections                            | 151                          |
| max_delayed_threads                        | 20                           |
| max_digest_length                          | 1024                         |
| max_error_count                            | 1024                         |
| max_execution_time                         | 0                            |
| max_heap_table_size                        | 16777216                     |
| max_insert_delayed_threads                 | 20                           |
| max_join_size                              | 18446744073709551615         |

...

| thread_handling                            | one-thread-per-connection    |
| thread_stack                               | 286720                       |
| time_zone                                  | SYSTEM                       |
| timestamp                                  | 1530906638.765316            |
| tls_version                                | TLSv1,TLSv1.1,TLSv1.2        |
| tmp_table_size                             | 16777216                     |
| tmpdir                                     | /tmp                         |
| transaction_alloc_block_size               | 8192                         |
| transaction_allow_batching                 | OFF                          |
| transaction_isolation                      | REPEATABLE-READ              |
| transaction_prealloc_size                  | 4096                         |
| transaction_read_only                      | OFF                          |
| transaction_write_set_extraction           | XXHASH64                     |
| unique_checks                              | ON                           |
| updatable_views_with_limit                 | YES                          |
| version                                    | 8.0.12                       |
| version_comment                            | MySQL Community Server - GPL |
| version_compile_machine                    | x86_64                       |
| version_compile_os                         | Linux                        |
| version_compile_zlib                       | 1.2.11                       |
| wait_timeout                               | 28800                        |
| warning_count                              | 0                            |
| windowing_use_high_precision               | ON                           |
+--------------------------------------------+------------------------------+

用一个LIKE条款,声明显示这些变量与该模式匹配的名字才行。获得一个特定变量的行,使用LIKE条款如下所示:

显示变量的max_join_size”;显示会话变量如max_join_size”;

得到一系列的变量的名称匹配的模式,使用%在通配符LIKE条款:

显示变量&#39;&#39;%1大小%;显示全局变量是“大小%;

通配符可以用在任何位置的匹配模式。严格地说,因为_是一个通配符,匹配任何单个字符,你要逃避它“_把它随便。在实践中,这是没有必要的。

13.7.6.40秀警告语法

SHOW WARNINGS [LIMIT [offset,] row_count]
SHOW COUNT(*) WARNINGS

SHOW WARNINGS是一个诊断的声明,显示有关条件的信息(错误,警告和注释)从当前会话中执行语句导致。警告是DML语句如生成INSERTUPDATE,和LOAD DATA INFILE以及DDL语句,如CREATE TABLEALTER TABLE

这个LIMIT条款具有相同的语法为SELECT声明。看到第13.2.10,选择“语法”

SHOW WARNINGS也可用以下EXPLAIN,显示扩展信息产生的EXPLAIN。看到第8.8.3,“扩展解释输出格式”

SHOW WARNINGS显示从当前会话中最近的非诊断性语句执行产生的条件的信息。如果最近的声明导致错误的分析,SHOW WARNINGS显示结果的条件下,无论语句类型(诊断或诊断意义)。

这个SHOW COUNT(*) WARNINGS诊断报表显示错误、警告的总数,和笔记。你也可以从中检索这个号码warning_count系统变量:

显示计数(*)警告;选择@ @ warning_count;

这些陈述的区别在于,首先是诊断不明确的声明邮件列表。其次,因为它是一个SELECT声明是不明确的非诊断和邮件列表。

一个相关的诊断报告,SHOW ERRORS,只显示错误条件(不包括警告和注意),和SHOW COUNT(*) ERRORS语句显示错误总数。看到第13.7.6.17,“显示错误语法”GET DIAGNOSTICS可用于检查信息的个人条件。看到第13.6.7.3,“诊断学语法”

这里是一个简单的例子,显示数据转换警告INSERT

MySQL的&#62;CREATE TABLE t1 (a TINYINT NOT NULL, b CHAR(4));查询行,0行受影响(0.05秒)MySQL &#62;INSERT INTO t1 VALUES(10,'mysql'), (NULL,'test'), (300,'xyz');查询行,3行的影响,3警告(0秒)记录:3份:0警告:3mysql &#62;SHOW WARNINGS\G*************************** 1。行***************************水平:报警代码:1265message:数据截断柱B在连续1 *************************** 2。行***************************水平:报警代码:1048message:列“一”不能为空*************************** 3。行***************************水平:报警代码:1264message:越界值列&#39;行33行集(0秒)

这个max_error_count系统变量控制误差,最大数量的警告,而服务器存储信息的信息,因此信息的数量SHOW WARNINGS显示器更改服务器可以存储信息的数量,改变价值max_error_count

max_error_count只控制多少的信息存储,没有多少算。价值warning_count不受max_error_count,即使产生的消息数超过max_error_count。下面的例子演示了这。这个ALTER TABLE语句产生三警告信息(严格的SQL模式禁用为例来防止错误的发生一个转换期之后)。只有一个消息存储和显示因为max_error_count已被设置为-1,但所有的计算(如图所示的价值warning_count):

MySQL的&#62;SHOW VARIABLES LIKE 'max_error_count';----------------- ------- | variable_name |价值| ----------------- ------- | max_error_count | 1024 | ----------------- ------- 1行集(0秒)MySQL &#62;SET max_error_count=1, sql_mode = '';查询好,为受影响的行(0.001秒)MySQL &#62;ALTER TABLE t1 MODIFY b CHAR;查询行,3行的影响,3警告(0秒)记录:3份:0警告:3mysql &#62;SHOW WARNINGS;--------- ------ ---------------------------------------- |水平|代码|消息| --------- ------ ---------------------------------------- |警告| 1263 |数据截断柱B在连续1 | --------- ------ ---------------------------------------- 1行集(0秒)MySQL &#62;SELECT @@warning_count;Fa@warningásónónónónónónónónón que siónónónónónónónónónónónónónónónónónónónónónónónónónónónónónécón de la?---- elásónónónón en el un 1 row in set(0.01 SEC)

禁用邮件存储、集max_error_count0。在这种情况下,warning_count还表示多少出现警告,但信息不存储无法显示。

这个sql_notes系统变量控制器warning_count无论是服务器存储。默认情况下,sql_notes是1,但是如果设置为0,说明没有增量warning_count和服务器不保存:

MySQL的&#62;SET sql_notes = 1;MySQL的&#62;DROP TABLE IF EXISTS test.no_such_table;查询行,0行的影响,1报警(0秒)MySQL &#62;SHOW WARNINGS;------- ------ ------------------------------------ |水平|代码|消息| ------- ------ ------------------------------------ |注| 1051 |未知表”测试。no_such_table”| ------- ------ ------------------------------------ 1行集(0秒)MySQL &#62;SET sql_notes = 0;MySQL的&#62;DROP TABLE IF EXISTS test.no_such_table;查询好,为受影响的行(0.001秒)MySQL &#62;SHOW WARNINGS;空集(0.001秒)

MySQL服务器发送到每个客户端计数指示错误、警告的总数,由客户端执行的最近的声明导致笔记。从C API,这个值可以通过调用mysql_warning_count()。看到第27.7.7.82,“mysql_warning_count()”

MySQL客户端,您可以启用和禁用自动警告显示warningsnowarning命令,分别或快捷方式,\WW(见4.5.1.2节,“MySQL命令”)。例如:

mysql> \W
Show warnings enabled.
mysql> SELECT 1/0;
+------+
| 1/0  |
+------+
| NULL |
+------+
1 row in set, 1 warning (0.03 sec)

Warning (Code 1365): Division by 0
mysql> \w
Show warnings disabled.

13.7.7其他管理报表

13.7.7.1 binlog语法

BINLOG 'str'

BINLOG是一个内部使用的声明。它产生的mysqlbinlog程序的二进制日志文件打印表示某些事件。(见4.6.8“,”mysqlbinlog用于处理二进制日志文件实用程序”的。)'str'价值是一个base 64编码的字符串,服务器将确定数据的变化对应的事件表明。这一声明要求BINLOG_ADMINSUPER特权

这个语句可以只执行格式描述事件和连续事件。

13.7.7.2缓存索引的语法

CACHE INDEX
  tbl_index_list [, tbl_index_list] ...
  [PARTITION (partition_list | ALL)]
  IN key_cache_name

tbl_index_list:
  tbl_name [[INDEX|KEY] (index_name[, index_name] ...)]

partition_list:
  partition_name[, partition_name][, ...]

这个CACHE INDEX语句指定表的索引到一个特定的密钥缓存。它仅用于MyISAM表在指标已分配,他们可以预加载到缓存中如果需要LOAD INDEX INTO CACHE

下面的语句将表中的索引t1T2,和t3对密钥缓存命名热门高速缓存

mysql> CACHE INDEX t1, t2, t3 IN hot_cache;
+---------+--------------------+----------+----------+
| Table   | Op                 | Msg_type | Msg_text |
+---------+--------------------+----------+----------+
| test.t1 | assign_to_keycache | status   | OK       |
| test.t2 | assign_to_keycache | status   | OK       |
| test.t3 | assign_to_keycache | status   | OK       |
+---------+--------------------+----------+----------+

语法CACHE INDEX使您可以指定从表中只有特定的指标应分配给缓存。当前的实现将所有表的索引的缓存,所以没有理由指定比任何其他的表名。

“密钥缓存中提到的ACACHE INDEX语句可以通过参数设置表或服务器参数设置设置它的大小了。例如:

MySQL的&#62;SET GLOBAL keycache1.key_buffer_size=128*1024;

键缓存参数可以作为一个结构化的系统变量成员访问。看到第5.1.8.2,“系统变量”

一个关键的缓存必须在你能分配指标,它的存在:

mysql> CACHE INDEX t1 IN non_existent_cache;
ERROR 1284 (HY000): Unknown key cache 'non_existent_cache'

默认情况下,表的索引分配给主(默认)缓存在服务器启动时创建的关键。当一个密钥缓存被破坏,所有指标的分配成为分配到默认密钥缓存了。

索引分配影响全局:如果一个客户端服务器分配一个索引到一个给定的高速缓存,该缓存是用于查询的索引,无论哪个客户问题的查询。

在MySQL 8中,这个声明也支持分区MyISAM表你可以指定一个或多个指标之一,几个或所有分区到一个给定的密钥缓存。例如,你可以做以下:

CREATE TABLE pt (c1 INT, c2 VARCHAR(50), INDEX i(c1))    ENGINE=MyISAM    PARTITION BY HASH(c1)    PARTITIONS 4;SET GLOBAL kc_fast.key_buffer_size = 128 * 1024;SET GLOBAL kc_slow.key_buffer_size = 128 * 1024;CACHE INDEX pt PARTITION (p0) IN kc_fast;CACHE INDEX pt PARTITION (p1, p3) IN kc_slow;

语句之前执行以下操作:

  • 创建一个分区表4个分区;这些分区自动命名p0,…,P3这个表有一个指标叫;i柱上C1

  • 创建二关键缓存命名kc_fastkc_slow

  • 分配给分区的索引p0KC _快餐键缓存和分区索引p1P3kc_slow键缓存;对其余分区索引(P2)使用服务器的默认密钥缓存。

如果您希望指定索引表中的所有分区pt一个单一的关键缓存命名kc_all,你可以使用下面的语句是一个2:

CACHE INDEX pt PARTITION (ALL) IN kc_all;

CACHE INDEX pt IN kc_all;

两种说法只是证明是等价的,发行的任何一个都会有同样的效果。换句话说,如果你希望分配指标的所有分区的分区表相同的密钥缓存,然后PARTITION (ALL)子句是可选的

当分配指标的多个分区的关键缓存分区不必是连续的,你不需要在任何特定的顺序列出他们的名字。对于任何分区不明确指定一个密钥缓存自动使用服务器的默认密钥缓存索引。

在MySQL 8中,指数预压也支持分区MyISAM表有关更多信息,参见第13.7.7.5,“负荷指数为缓存语法”

13.7.7.3表冲洗

FLUSH [NO_WRITE_TO_BINLOG | LOCAL] {
    flush_option [, flush_option] ...
  | tables_option
}

flush_option: {
    BINARY LOGS
  | ENGINE LOGS
  | ERROR LOGS
  | GENERAL LOGS
  | HOSTS
  | LOGS
  | PRIVILEGES
  | OPTIMIZER_COSTS
  | RELAY LOGS [FOR CHANNEL channel]
  | SLOW LOGS
  | STATUS
  | USER_RESOURCES
}

tables_option: {
    TABLES
  | TABLES tbl_name [, tbl_name] ...
  | TABLES WITH READ LOCK
  | TABLES tbl_name [, tbl_name] ... WITH READ LOCK
  | TABLES tbl_name [, tbl_name] ... FOR EXPORT
}

这个FLUSH语句有几种不同形式,明确或重新加载各种内部缓存刷新表,或获取锁。执行FLUSH,你必须有RELOAD特权。具体冲洗选项可能需要额外的特权,如后所述。

笔记

这是不可能的问题FLUSH存储函数或触发器中的语句。然而,你可以使用FLUSH在存储过程中,只要这些不是从存储函数或触发器调用。看到第1,“限制存储的程序”

默认情况下,服务器写FLUSH报表的二进制日志,复制到复制的奴隶。抑制测井,指定可选no_write_to_binlog关键词或其别名LOCAL

笔记

FLUSH LOGSFLUSH TABLES WITH READ LOCK(带或不带表),和FLUSH TABLES tbl_name ... FOR EXPORT不写在任何情况下,二进制日志,因为他们如果复制到奴隶问题。

这个FLUSH语句隐式提交。看到13.3.3部分,”声明,因为一个隐含的承诺”

这个mysqladmin实用新型提供一些直接操作命令行界面,使用命令如flush-hosts刷新日志flush-privileges冲洗的地位,和flush-tables。看到4.5.2“,”mysqladmin客户管理MySQL服务器”

发送一个SIGHUP信号给服务器造成的冲洗操作发生类似的多种形式FLUSH声明。看到第5.1.14”信号,服务器响应”

这个RESET语句类似于FLUSH。看到第13.7.7.6,复位”语法”,信息利用RESET语句以及复制

下面的列表(二)允许describesFLUSH陈述flush_option值。学院为手法FLUSH TABLES变种,看刷新表的语法

刷新表的语法

FLUSH TABLES冲表,根据不同的应用,获取锁。任何用在变异FLUSH语句必须是唯一的选择应用。FLUSH TABLE是同义词FLUSH TABLES

笔记

这里的描述表明表是通过关闭冲洗应用不同InnoDB表格内容,冲到磁盘而让他们打开。这还允许表文件可以被复制而表是开放的,只要其他活动不修改。

  • FLUSH TABLES

    关闭所有打开的表,使用力量要关闭所有的表,并刷新准备语句缓存。有关编写语句缓存,看8.10.3节,“缓存的准备好的语句和存储的程序”

    FLUSH TABLES是不允许的,有一个活跃的LOCK TABLES ... READ。冲洗和锁表,使用FLUSH TABLES tbl_name ... WITH READ LOCK相反

  • FLUSH TABLES tbl_name [, tbl_name] ...

    一个或多个用逗号分隔的表名,这种说法是一样的FLUSH TABLES没有名字,除了服务器刷新只有指定的表。如果一个命名表不存在,没有错误发生。

  • FLUSH TABLES WITH READ LOCK

    关闭所有打开的表和锁的所有数据库的所有表和一个全局读锁。这是如果你有一个文件系统如VERITAS或ZFS可以及时采取快照备份一个非常方便的方式获得。使用UNLOCK TABLES释放锁

    FLUSH TABLES WITH READ LOCK获得比表锁一个全局读锁,所以它不受相同的行为LOCK TABLESUNLOCK TABLES相对于表锁和隐式提交:

    FLUSH TABLES WITH READ LOCK不阻止服务器插入到日志表(见5.4.1部分,“选择通用查询和慢查询日志输出目的地”

  • FLUSH TABLES tbl_name [, tbl_name] ... WITH READ LOCK

    这句话的冲洗和获取读锁的命名表。声明首先取得独家元数据锁的表,所以它等待那些打开的表来完成交易。然后声明冲表从表缓存,重新打开表,获得表锁(如LOCK TABLES ... READ),和降级的元数据锁独家分享。在声明中获取锁和降级的元数据锁,其他会话可以读取但不能修改表。

    因为这句话获得表锁,你必须LOCK TABLES每个表的特权,除了要RELOAD这是需要使用任何特权FLUSH声明

    这句话只适用于现有的基础(非—TEMPORARY) 表如果一个名字指的是一个基表,该表是用。如果它指的是一个临时表,它被忽略。如果一个名称适用于一个视图,一个ER_WRONG_OBJECT发生错误。Otherwise,anER_NO_SUCH_TABLE错误发生

    使用UNLOCK TABLES释放锁,LOCK TABLES释放锁并获得其他的锁,或START TRANSACTION释放锁并开始一个新的交易。

    FLUSH TABLES变异使表被刷新和锁定在一个单一的操作。它提供了一个解决方案的限制FLUSH TABLES是不允许的,有一个活跃的LOCK TABLES ... READ

    这句话并不执行隐式UNLOCK TABLES所以,一个错误的结果,如果你使用的声明有任何积极的LOCK TABLES或者使用它没有先释放锁获得的第二时间。

    如果把表打开时HANDLER处理程序是隐式的,满脸通红,失去了它的位置。

  • FLUSH TABLES tbl_name [, tbl_name] ... FOR EXPORT

    FLUSH TABLES不同于InnoDB表它确保更改命名表已被刷新到磁盘中,二进制表的副本可以在服务器运行了。

    声明是这样的:

    1. 它获取共享元数据锁命名表。语句块只要其它会话活动事务已修改的表或表锁他们。当锁了,语句块事务试图更新表,同时允许只读操作继续。

    2. 检查是否所有的表的存储引擎支持FOR EXPORT。如果不,一个ER_ILLEGAL_HA错误发生时,该语句将失败。

    3. 声明通知存储引擎每个表使桌子准备出口。存储引擎必须确保任何挂起的更改写入磁盘。

    4. 声明提出的会话锁定表模式,元数据锁收购前不释放时FOR EXPORTcompletes声明。

    这个FLUSH TABLES ... FOR EXPORT声明要求你SELECT每个表的权限。因为这句话获得表锁,你也必须有LOCK TABLES每个表的特权,除了要RELOAD这是需要使用任何特权FLUSH声明

    这句话只适用于现有的基础(非—TEMPORARY)表。如果一个名字指的是一个基表,该表是用。如果它指的是一个临时表,它被忽略。如果一个名称适用于一个视图,一个ER_WRONG_OBJECT发生错误。Otherwise,anER_NO_SUCH_TABLE错误发生

    InnoDB支持出口对自己的表.ibd文件文件(即创建表innodb_file_per_table设置启用)InnoDB确保当通知的FOR EXPORT声明的任何更改已经刷新到磁盘。这允许一个表格内容的二进制副本进行时出口声明实际上是因为.ibd文件是一致和可复制在服务器正在运行。出口不适用于InnoDB系统表空间文件,或InnoDB表:FULLTEXT指标

    FLUSH TABLES ...FOR EXPORT负载partitioned is forInnoDB

    当通知FOR EXPORTInnoDB写到磁盘上,通常是在内存中或在单独的磁盘缓冲区以外的表空间文件举行某些类型的数据。每个表,InnoDB也会产生一个文件名为table_nameCFG桩复合地基在相同的数据库目录为真的结束了。《CFG桩复合地基文件包含元数据需要重新导入表空间文件后,在相同或不同的服务器。

    FOR EXPORT语句完成,InnoDB将会把所有的脏页将表数据文件。任何变化的缓冲条目被合并之前,冲洗。在这一点上,表锁和静态:表在磁盘上的一个事务一致的状态,你可以复制.ibd表空间文件连同相应的CFG桩复合地基文件获取那些表一致的快照。

    的程序,再输入复制的表的数据到一个MySQL实例,看第15.7.6,“每表表空间文件复制到另一个实例”

    在你完成了表,使用UNLOCK TABLES释放锁,LOCK TABLES释放锁并获得其他的锁,或START TRANSACTION释放锁并开始一个新的交易。

    虽然这些声明,实际上是在会话中,尝试使用FLUSH TABLES ... FOR EXPORT产生一个错误:

    冲洗表…读lockflush表…对于exportlock表…readlock表…写

    FLUSH TABLES ... FOR EXPORT实际上是在会话中,尝试使用这些语句产生一个错误:

    FLUSH TABLES WITH READ lockflush表…读lockflush表…出口

13.7.7.4杀死语法

KILL [CONNECTION | QUERY] processlist_id

每个连接到mysqld运行在一个单独的线程。你可以杀死一个线程KILL processlist_id声明

线程列表标识符可以由ID列的INFORMATION_SCHEMA.PROCESSLIST表的身份证件SHOW PROCESSLIST输出,和processlist_id的性能架构列threads表对于当前线程的返回值的CONNECTION_ID()功能

KILL允许可选联系QUERY修正:

  • KILL CONNECTION是一样的KILL没有改性剂:它终止与给定的相关连接processlist_id任何声明,终止连接执行后。

  • KILL QUERY终止当前正在执行的语句的连接,但叶片连接本身完好无损。

如果你有PROCESS特权,你可以看到所有的线程。如果你有CONNECTION_ADMINSUPER特权,你可以杀死所有的线程和报表。否则,你可以看到只有杀死自己的线程和报表。

你也可以使用mysqladmin列表mysqladmin杀检查并杀死线程的指令。

当你使用KILL,一个线程杀死标志设置为线程。在大多数情况下,它可能需要一些时间内死亡因为杀死旗是在特定的时间间隔只检查:

  • SELECT操作,为顺序GROUP BY循环,国旗是读完一行块检查。如果杀了标志设置,声明中止。

  • ALTER TABLE操作,使一个表复制检查kill标志定期每几个复制行从原来的表中读取。如果杀标志被设置,该语句将终止与临时表被删除。

    这个KILL语句返回而不等待确认,但杀旗检查中止操作相当小的时间内。中止操作执行任何必要的清理工作也需要一些时间。

  • UPDATEDELETE操作,杀标志检查每一块读之后,每次更新或删除的行。如果杀了标志设置,声明中止。如果你不使用事务,变化不回滚。

  • GET_LOCK()中止和回报无效的

  • 如果线程在锁表处理程序(状态:Locked),表锁很快中止

  • 如果线程在写呼叫等待的空闲磁盘空间,写中止与磁盘已满错误消息

警告

杀死一个REPAIR TABLEOPTIMIZE TABLE操作上的MyISAM在一个表中,损坏和不能使用的表结果。任何读或写这样的表失败直到你优化或修复一遍(不间断)。

13.7.7.5负荷指标为缓存语法

LOAD INDEX INTO CACHE
  tbl_index_list [, tbl_index_list] ...

tbl_index_list:
  tbl_name
    [PARTITION (partition_list | ALL)]
    [[INDEX|KEY] (index_name[, index_name] ...)]
    [IGNORE LEAVES]

partition_list:
    partition_name[, partition_name][, ...]

这个LOAD INDEX INTO CACHE声明表索引的关键预加载缓存,它被显式的指定CACHE INDEX声明,或为默认密钥缓存否则。

LOAD INDEX INTO CACHE仅用于MyISAM表。在MySQL 8.0,它也支持partitioned is forMyISAM表;此外,分区表的索引可以预装一个,几个,或所有分区。

这个IGNORE LEAVES改性剂的指标是非叶节点只造成块预装。

IGNORE LEAVES也支持分区MyISAM

以下语句预加载节点(索引块)的表索引t1T2

mysql> LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES;
+---------+--------------+----------+----------+
| Table   | Op           | Msg_type | Msg_text |
+---------+--------------+----------+----------+
| test.t1 | preload_keys | status   | OK       |
| test.t2 | preload_keys | status   | OK       |
+---------+--------------+----------+----------+

这一声明所有索引块的预紧力t1。它预装的非叶节点只块T2

语法LOAD INDEX INTO CACHE使您可以指定从表中只有特定的指标应预装。目前实施的所有表的索引预加载到缓存中,所以没有理由指定比任何其他的表名。

它是可能的预紧力指标对特定的分区的分区MyISAM表例如,以下2个报表,为分区的第一力指标P0一个分区表pt,而第二预紧力对分区索引P1p3对同一个表:

负荷指数为缓存PT分区(P0);负荷指数为缓存分区(P1,P3)PT;

预紧力的指标表中的所有分区pt,你可以使用以下2个陈述的任何一个:

负荷指数为缓存分区(全部);负载Pt Pt索引缓存;

两种说法只是证明是等价的,发行的任何一个都会有同样的效果。换句话说,如果你希望预紧力指标的所有分区的分区表,然后PARTITION (ALL)子句是可选的

当预压指标为多个分区,分区不必是连续的,你不需要在任何特定的顺序列出他们的名字。

LOAD INDEX INTO CACHE ... IGNORE LEAVES失败,除非在一个表中的所有指标都相同的块大小。你可以确定索引块尺寸表用myisamchk - DV检查Blocksize专栏

13.7.7.6复位语法

RESET reset_option [, reset_option] ...

reset_option: {
    MASTER
  | SLAVE
}

这个RESET声明用于清除各种服务器操作的状态。你必须有RELOAD特权执行RESET

的信息RESET PERSIST声明中移除坚持全球系统变量,看第13.7.7.7,“重置坚持语法”

RESET作为一个强大的版本的FLUSH声明。看到第13.7.7.3“同花顺语法”

这个RESET语句隐式提交。看到13.3.3部分,”声明,因为一个隐含的承诺”

下面的列表(二)允许describesRESET陈述reset_option价值观:

  • RESET MASTER

    删除所有的二进制日志索引文件中列出,重置二进制日志索引文件是空的,并创建一个新的二进制日志文件。

  • RESET SLAVE

    让奴隶在主人忘记其二进制日志复制的位置。同时将中继日志删除任何现有的中继日志文件并开始一个新的。

13.7.7.7复位坚持语法

RESET PERSIST [[IF EXISTS] system_var_name]

RESET PERSIST用于除去坚持全球系统变量的设置mysqld-auto.cnf走吧这句话需要SYSTEM_VARIABLES_ADMINSUPER特权。除去坚持系统变量导致变量不能初始化mysqld-auto.cnf在服务器启动

关于坚持系统变量,看5.1.8节,“使用系统变量”。有关RESET声明变量,明确其他服务器操作的状态,看第13.7.7.6,复位”语法”

这取决于变量的名称和IF EXISTS条款的存在,这些形式的声明:

  • RESET PERSIST

    这个语句删除所有保存的变量mysqld-auto.cnf

  • RESET PERSIST system_var_name

    这个语句删除指定的变量,从坚持mysqld-auto.cnf。这包括插件系统变量,即使目前没有安装的插件。如果变量是不存在的文件时,出现错误。

  • RESET PERSIST IF EXISTS system_var_name

    这个语句删除指定的变量,从坚持mysqld-auto.cnf。这包括插件系统变量,即使目前没有安装的插件。如果变量是不存在的文件,将生成一条警告。

RESET PERSIST是不是值的影响persisted_globals_load系统变量

RESET PERSIST影响绩效模式的内容persisted_variables表,表的内容对应的内容mysqld-auto.cnf文件

RESET PERSIST对性能没有影响的内容图式variables_info

13.7.7.8重启句法

RESTART

这一声明停止并重新启动MySQL服务器。它要求SHUTDOWN特权

一个利用RESTART当它是不可能或不方便获得命令行访问MySQL服务器对服务器主机重启。例如,SET PERSIST_ONLY可用于在运行时对系统变量只能被设置在启动服务器进行配置更改,但是服务器还必须重新启动,以使这些更改生效。这个RESTART语句提供了一种在客户端会话这么做,没有在服务器主机需要访问命令行。

笔记

在执行一个RESTART声明中,客户端可以预计目前的连接丢失。如果自动重新启用,连接将被恢复后,重新启动服务器。否则,必须重新手动连接。

一个成功的RESTART操作要求mysqld要在一个环境中有一个监测过程中可检测到进行服务器关机重启的目的运行:

  • 在监控过程中存在,RESTART起因mysqld终止这样的监控过程可以确定它应该开始一个新的mysqld实例

  • 如果没有监控过程是存在的,RESTART失败与错误

这些平台提供了必要的监测支持RESTART声明:

  • 窗户,当mysqld是开始作为一个Windows服务或独立。(mysqld叉,和一个过程作为显示器的其他,作为服务器。)

  • UNIX和类UNIX系统使用系统或_ mysqld safe管理mysqld

在Windows中,分叉用来实现RESTART使确定服务器进程附加到调试更加困难。为了减轻这个问题,启动服务器--gdb抑制分叉,除了它的其他行动建立一个调试环境。在非调试设置,--no-monitor可用于抑制分叉的监控过程的唯一目的。一个服务器开始用--gdb--no-monitor,执行RESTART导致服务器简单的退出而不重新启动。

13.7.7.9关机语法

SHUTDOWN

这句话的意思是MysQL服务器。它需要SHUTDOWN特权

SHUTDOWN提供了一个SQL级接口相同的功能,可使用关闭命令

13.8实用语句

138.SYNTAX描述

这个DESCRIBEEXPLAIN报表是同义词,用来获取表结构或查询执行计划的信息。有关更多信息,参见第13.7.6.5,“显示列的语法”,和第13.8.2,”解释语法”

13.8.2解释语法

{EXPLAIN | DESCRIBE | DESC}
    tbl_name [col_name | wild]

{EXPLAIN | DESCRIBE | DESC}
    [explain_type]
    {explainable_stmt | FOR CONNECTION connection_id}

explain_type: {
    FORMAT = format_name
}

format_name: {
    TRADITIONAL
  | JSON
}

explainable_stmt: {
    SELECT statement
  | DELETE statement
  | INSERT statement
  | REPLACE statement
  | UPDATE statement
}

这个DESCRIBEEXPLAIN报表是同义词。在实践中,这DESCRIBE关键词往往是用来获取表结构信息,而EXPLAIN是用来获取一个查询执行计划(即说明MySQL会执行一个查询)。

下面的讨论以DESCRIBEEXPLAIN与那些使用根据关键词,但是MySQL解析器对待完全同义。

获取表结构信息

DESCRIBE提供有关表中的列信息:

MySQL的&#62;DESCRIBE City;------------ ---------- ------ ----- --------- ---------------- |场|型|空|关键|默认|额外| ------------ ---------- ------ ----- --------- ---------------- | ID | int(11)|没有| PRI |空| auto_increment | |名字| char(35)|没有| | | | |国| char(3)|没有|大学| | | |区| char(20)|是|多| | | |人口| int(11)|没有| | 0 | | ------------ ---------- ------ ----- --------- ----------------

DESCRIBE是一个快捷方式SHOW COLUMNS. 这些单元还显示了对旧的信息。描述SHOW COLUMNS提供关于输出列的更多信息。看到第13.7.6.5,“显示列的语法”

默认情况下,DESCRIBE显示表中的所有列的信息。col_name,如果给定的,是表中的列的名称。在这种情况下,声明只显示指定的列信息。wild,如果是一个字符串。它可以包含SQL%_通配符。在这种情况下,声明只显示与匹配的字符串名称的列输出。没有必要将字符串中的引号除非它包含空格或其他特殊字符。

这个DESCRIBE声明提供兼容Oracle。

这个SHOW CREATE TABLESHOW TABLE STATUS,和SHOW INDEX报告还提供了有关表。看到第13.7.6,“语法”

获取执行计划信息

这个EXPLAIN声明提供了关于MySQL执行语句的信息:

EXPLAIN要求SELECT任何表或视图的访问权限,包括任何潜在的表观。对于视图,EXPLAIN还要求SHOW VIEW特权

借助EXPLAIN,你可以看到你应该添加索引表使语句执行利用指标行更快找到。你也可以使用EXPLAIN检查是否优化连接表的最佳顺序。给一点提示,优化器使用联接的表中指定的顺序对应的订单SELECT首先声明,声明选择straight_join而不是仅仅SELECT。。。。。。。(这第13.2.10,选择“语法”。)

优化痕迹有时可能提供的信息是互补的EXPLAIN。然而,优化器跟踪的格式和内容有不同版本之间的变化。详情见MySQL内核:追踪优化器

如果你有一个问题,指标不被使用当你认为他们应该跑ANALYZE TABLE更新表的统计,如基数的钥匙,可以影响优化器作出的选择。看到第13.7.3.1,“语法分析表”

笔记

MySQL Workbench具有直观解释的能力,提供了一个可视化表示EXPLAIN输出。看到教程:用解释来提高查询性能

13.8.3语法帮助

HELP 'search_string'

这个HELP声明从MySQL参考手册返回在线信息。它的正常运行需要的帮助表MySQL数据库可以帮助主题信息初始化(见第5.1.13,“服务器端”

这个HELP语句搜索给定的搜索字符串的帮助表并显示搜索结果。搜索字符串不区分大小写。

搜索字符串可以包含通配符%_。这些具有相同含义的模式匹配操作进行的LIKE算子。例如,代表“帮助”%返回主题列表,开始rep

帮助理解搜索字符串的几种类型的声明:

  • 在最一般的水平,使用contents检索列表的顶层帮助类别:

    帮助的内容
  • 一个主题列表在一个给定的帮助类,如Data Types,使用的类别名称:

    帮助“数据类型”
  • 在一个特定的帮助主题的帮助,如ASCII()函数或CREATE TABLE声明中,使用相关的关键字或关键词:

    帮助ascii&#39;help”创建表

换句话说,搜索字符串匹配的范畴,许多话题,或一个单一的主题。你不能事先告诉是否一个给定的搜索字符串,将返回一个列表的一个帮助主题的物品或帮助的信息。然而,你可以告诉我们什么样的反应HELP通过检查的结果集返回的行数和列数。

下面的描述表明,结果集可以采取的形式。例如,报表的输出显示使用熟悉的表格垂直的当你看到使用的格式MySQL知名客户,but thatMySQL本身格式化HELP在一个不同的结果集

  • 空的结果集

    没有比赛可以找到搜索字符串。

  • 结果集包含一个单排三列

    这意味着,搜索字符串产生一个命中帮助主题。结果有三列:

    • name课题名称

    • description正文:descriptive帮助为主题。

    • example:使用实例或实例。本栏可以空白。

    例子:HELP 'replace'

    yields:

    name: REPLACE
    description: Syntax:
    REPLACE(str,from_str,to_str)
    
    Returns the string str with all occurrences of the string from_str
    replaced by the string to_str. REPLACE() performs a case-sensitive
    match when searching for from_str.
    example: mysql> SELECT REPLACE('www.mysql.com', 'w', 'Ww');
            -> 'WwWwWw.mysql.com'
    
  • 结果集包含多个行和两列

    这意味着,搜索字符串匹配的许多帮助主题。结果集显示的帮助主题的名称:

    • name话题:help the name。

    • is_it_categoryY如果名字是一个帮助类,N如果它不。如果没有,那姓名当指定为参数的值HELP声明中应当单列结果集包含指定项目的说明。

    例子:HELP 'status'

    yields:

    +-----------------------+----------------+
    | name                  | is_it_category |
    +-----------------------+----------------+
    | SHOW                  | N              |
    | SHOW ENGINE           | N              |
    | SHOW MASTER STATUS    | N              |
    | SHOW PROCEDURE STATUS | N              |
    | SHOW SLAVE STATUS     | N              |
    | SHOW STATUS           | N              |
    | SHOW TABLE STATUS     | N              |
    +-----------------------+----------------+
    
  • 结果集包含多行三列

    这意味着搜索字符串匹配的类别。结果集包含类条目:

    • source_category_name求助:the category name。

    • name: The category or topic name

    • is_it_categoryY如果名字是一个帮助类,N如果它不。如果没有,那姓名当指定为参数的值HELP声明中应当单列结果集包含指定项目的说明。

    例子:HELP 'functions'

    yields:

    +----------------------+-------------------------+----------------+
    | source_category_name | name                    | is_it_category |
    +----------------------+-------------------------+----------------+
    | Functions            | CREATE FUNCTION         | N              |
    | Functions            | DROP FUNCTION           | N              |
    | Functions            | Bit Functions           | Y              |
    | Functions            | Comparison operators    | Y              |
    | Functions            | Control flow functions  | Y              |
    | Functions            | Date and Time Functions | Y              |
    | Functions            | Encryption Functions    | Y              |
    | Functions            | Information Functions   | Y              |
    | Functions            | Logical operators       | Y              |
    | Functions            | Miscellaneous Functions | Y              |
    | Functions            | Numeric Functions       | Y              |
    | Functions            | String Functions        | Y              |
    +----------------------+-------------------------+----------------+
    

13.8.4使用语法

USE db_name

这个USE db_name声明说,MySQL的使用db_name数据库作为默认值(电流)的后续语句的数据库。数据库是默认直到会话结束或另一个USE声明发表:

使用db1;select count(*)从mytable;#选择从db1.mytableuse DB2;select count(*)从mytable;#选择从db2.mytable

在一个特定的数据库的默认USE声明不排除你访问其他数据库的表。下面的示例程序作者从表db1数据库和编辑从表db2数据库:

USE db1;SELECT author_name,editor_name FROM author,db2.editor  WHERE author.editor_id = db2.editor.editor_id;