<?php /* MySQL_5.5中文参考手册 587开始 与GROUP BY子句同时使用的函数和修改程序 12.10.1. GROUP BY(聚合)函数 12.10.2. GROUP BY修改程序 12.10.3. 具备隐含字段的GROUP BY 12.10.1. GROUP BY(聚合)函数 本章论述了用于一组数值操做的 group (集合)函数。除非另做说明, group 函数会忽略 NULL 值。 假如你在一个不包含 ROUP BY子句的语句中使用一个 group函数,它至关于对全部行进行分组。 AVG([DISTINCT] expr) 返回expr 的平均值。 DISTINCT 选项可用于返回expr的不一样值的平均值。 若找不到匹配的行,则AVG()返回 NULL 。 mysql> SELECT student_name, AVG(test_score) -> FROM student -> GROUP BY student_name; BIT_AND(expr) 返回expr中全部比特的 bitwise AND 。计算执行的精确度为64比特(BIGINT) 。 若找不到匹配的行,则这个函数返回 18446744073709551615 。(这是无符号 BIGINT 值,全部比特被设置为 1)。 BIT_OR(expr) 返回expr 中全部比特的bitwise OR。计算执行的精确度为64比特(BIGINT) 。 若找不到匹配的行,则函数返回 0 。 BIT_XOR(expr) 返回expr 中全部比特的bitwise XOR。计算执行的精确度为64比特(BIGINT) 。 若找不到匹配的行,则函数返回 0 。 COUNT(expr) 返回SELECT语句检索到的行中非NULL值的数目。 若找不到匹配的行,则COUNT() 返回 0 。 mysql> SELECT student.student_name,COUNT(*) -> FROM student,course -> WHERE student.student_id=course.student_id -> GROUP BY student_name; COUNT(*) 的稍微不一样之处在于,它返回检索行的数目, 不论其是否包含 NULL值。 SELECT 从一个表中检索,而不检索其它的列,而且没有 WHERE子句时, COUNT(*)被优化到最快的返回速 度。例如: mysql> SELECT COUNT(*) FROM student; 这个优化仅适用于 MyISAM表, 缘由是这些表类型会储存一个函数返回记录的精确数量,并且很是容易访 问。对于事务型的存储引擎(InnoDB, BDB), 存储一个精确行数的问题比较多,缘由是可能会发生多重事物处 理, 而每一个均可能会对行数产生影响。 COUNT(DISTINCT expr,[expr...]) 返回不一样的非NULL值数目。 若找不到匹配的项,则COUNT(DISTINCT)返回 0 。 mysql> SELECT COUNT(DISTINCT results) FROM student; 在MySQL中, 你经过给定一个表达式列表而获取不包含NULL 不一样表达式组合的数目。在标准 SQL中,你将必须 在COUNT(DISTINCT ...)中链接全部表达式。 GROUP_CONCAT(expr) 该函数返回带有来自一个组的链接的非NULL值的字符串结果。其完整的语法以下所示: GROUP_CONCAT([DISTINCT] expr [,expr ...] [ORDER BY {unsigned_integer | col_name | expr} [ASC | DESC] [,col_name ...]] [SEPARATOR str_val]) mysql> SELECT student_name, -> GROUP_CONCAT(test_score) -> FROM student -> GROUP BY student_name; Or: mysql> SELECT student_name, -> GROUP_CONCAT(DISTINCT test_score -> ORDER BY test_score DESC SEPARATOR ' ') -> FROM student -> GROUP BY student_name; 在MySQL中,你能够获取表达式组合的链接值。你能够使用DISTINCT删去重复值。倘若你但愿多结果值进行排 序,则应该使用 ORDER BY子句。若要按相反顺序排列,将 DESC (递减) 关键词添加到你要用ORDER BY 子 句进行排序的列名称中。默认顺序为升序;可以使用ASC将其明确指定。 SEPARATOR 后面跟随应该被插入结 果的值中间的字符串值。默认为逗号 (‘,’)。经过指定SEPARATOR '' ,你能够删除全部分隔符。 使用group_concat_max_len系统变量,你能够设置容许的最大长度。程序中进行这项操做的语法以下,其中 val 是一个无符号整数: SET [SESSION | GLOBAL] group_concat_max_len = val; 若已经设置了最大长度, 则结果被截至这个最大长度。 MIN([DISTINCT] expr), MAX([DISTINCT] expr) 返回expr 的最小值和最大值。 MIN() 和 MAX() 的取值能够是一个字符串参数;在这些状况下, 它们返回最小 或最大字符串值。请参见7.4.5节,“MySQL如何使用索引”。 DISTINCT关键词能够被用来查找expr 的不一样值 的最小或最大值,然而,这产生的结果与省略DISTINCT 的结果相同。 若找不到匹配的行,MIN()和MAX()返回 NULL 。 mysql> SELECT student_name, MIN(test_score), MAX(test_score) -> FROM student -> GROUP BY student_name; 对于MIN()、 MAX()和其它集合函数, MySQL当前按照它们的字符串值而非字符串在集合中的相关位置比较 ENUM和 SET 列。这同ORDER BY比较两者的方式有所不一样。这一点应该在MySQL的将来版本中获得改善。 STD(expr) STDDEV(expr) 返回expr 的整体标准误差。这是标准 SQL 的延伸。这个函数的STDDEV() 形式用来提供和Oracle 的兼容性。 可以使用标准SQL函数 STDDEV_POP() 进行代替。 若找不到匹配的行,则这些函数返回 NULL 。 STDDEV_POP(expr) 返回expr 的整体标准误差(VAR_POP()的平方根)。你也能够使用 STD() 或STDDEV(), 它们具备相同的意义, 然而不是标准的 SQL。 若找不到匹配的行,则STDDEV_POP()返回 NULL。 STDDEV_SAMP(expr) 返回expr 的样本标准差 ( VAR_SAMP()的平方根)。 若找不到匹配的行,则STDDEV_SAMP() 返回 NULL 。 SUM([DISTINCT] expr) 返回expr 的总数。 若返回集合中无任何行,则 SUM() 返回NULL。DISTINCT 关键词可用于 MySQL 5.1 中, 求得expr 不一样值的总和。 若找不到匹配的行,则SUM()返回 NULL。 VAR_POP(expr) 返回expr 整体标准方差。它将行视为整体,而不是一个样本, 因此它将行数做为分母。你也能够使用 VARIANCE(),它具备相同的意义然而不是标准的 SQL。 若找不到匹配的项,则VAR_POP()返回NULL。 VAR_SAMP(expr) 返回expr 的样本方差。更确切的说,分母的数字是行数减去1。 若找不到匹配的行,则VAR_SAMP()返回NULL。 VARIANCE(expr) 返回expr 的整体标准方差。这是标准SQL 的延伸。可以使用标准SQL 函数 VAR_POP() 进行代替。 若找不到匹配的项,则VARIANCE()返回NULL。 12.10.2. GROUP BY修改程序 GROUP BY子句容许一个将额外行添加到简略输出端 WITH ROLLUP 修饰符。这些行表明高层(或高汇集)简略 操做。ROLLUP 于是容许你在多层分析的角度回答有关问询的问题。例如,它能够用来向OLAP (联机分析处 理) 操做提供支持。 设想一个名为sales 的表具备年份、国家、产品及记录销售利润的利润列: CREATE TABLE sales ( year INT NOT NULL, country VARCHAR(20) NOT NULL, product VARCHAR(32) NOT NULL, profit INT ); 能够使用这样的简单GROUP BY,每一年对表的内容作一次总结: mysql> SELECT year, SUM(profit) FROM sales GROUP BY year; +------+-------------+ | year | SUM(profit) | +------+-------------+ | 2000 | 4525 | | 2001 | 3010 | +------+-------------+ 这个输出结果显示了每一年的总利润, 但若是你也想肯定全部年份的总利润,你必须本身累加每一年的单个值或运 行一个加法询问。 或者你能够使用 ROLLUP, 它能用一个问询提供双层分析。将一个 WITH ROLLUP修饰符添加到GROUP BY 语 句,使询问产生另外一行结果,该行显示了全部年份的总价值: mysql> SELECT year, SUM(profit) FROM sales GROUP BY year WITH ROLLUP; +------+-------------+ | year | SUM(profit) | +------+-------------+ | 2000 | 4525 | | 2001 | 3010 | | NULL | 7535 | +------+-------------+ 总计高汇集行被年份列中的NULL值标出。 当有多重 GROUP BY 列时,ROLLUP产生的效果更加复杂。这时,每次在除了最后一个分类列以外的任何列出 现一个 “break” (值的改变) ,则问讯会产生一个高汇集累计行。 例如,在没有 ROLLUP的状况下,一个以年、国家和产品为基础的关于 sales 表的一览表可能以下所示: mysql> SELECT year, country, product, SUM(profit) -> FROM sales -> GROUP BY year, country, product; +------+---------+------------+-------------+ | year | country | product | SUM(profit) | +------+---------+------------+-------------+ | 2000 | Finland | Computer | 1500 | | 2000 | Finland | Phone | 100 | | 2000 | India | Calculator | 150 | | 2000 | India | Computer | 1200 | | 2000 | USA | Calculator | 75 | | 2000 | USA | Computer | 1500 | | 2001 | Finland | Phone | 10 | | 2001 | USA | Calculator | 50 | | 2001 | USA | Computer | 2700 | | 2001 | USA | TV | 250 | +------+---------+------------+-------------+ 表示总值的输出结果仅位于年/国家/产品的分析级别。当添加了 ROLLUP后, 问询会产生一些额外的行: mysql> SELECT year, country, product, SUM(profit) -> FROM sales -> GROUP BY year, country, product WITH ROLLUP; +------+---------+------------+-------------+ | year | country | product | SUM(profit) | +------+---------+------------+-------------+ | 2000 | Finland | Computer | 1500 | | 2000 | Finland | Phone | 100 | | 2000 | Finland | NULL | 1600 | | 2000 | India | Calculator | 150 | | 2000 | India | Computer | 1200 | | 2000 | India | NULL | 1350 | | 2000 | USA | Calculator | 75 | | 2000 | USA | Computer | 1500 | | 2000 | USA | NULL | 1575 | | 2000 | NULL | NULL | 4525 | | 2001 | Finland | Phone | 10 | | 2001 | Finland | NULL | 10 | | 2001 | USA | Calculator | 50 | | 2001 | USA | Computer | 2700 | | 2001 | USA | TV | 250 | | 2001 | USA | NULL | 3000 | | 2001 | NULL | NULL | 3010 | | NULL | NULL | NULL | 7535 | +------+---------+------------+-------------+ 对于这个问询, 添加ROLLUP 子句使村输出结果包含了四层分析的简略信息,而不仅是一个下面是怎样解释 ROLLUP输出: 一组给定的年份和国家的每组产品行后面, 会产生一个额外的总计行, 显示全部产品的总值。这些行将 产品列设置为 NULL。 一组给定年份的行后面,会产生一个额外的总计行,显示全部国家和产品的总值。这些行将国家和产品 列设置为 NULL。 最后, 在全部其它行后面,会产生一个额外的总计列,显示全部年份、国家及产品的总值。这一行将年 份、国家和产品列设置为 NULL。 使用ROLLUP 时的其它注意事项 如下各项列出了一些MySQL执行ROLLUP的特殊状态: 当你使用 ROLLUP时, 你不能同时使用 ORDER BY子句进行结果排序。换言之, ROLLUP 和ORDER BY 是互相 排斥的。然而,你仍能够对排序进行一些控制。在 MySQL中, GROUP BY 能够对结果进行排序,并且你能够 在GROUP BY列表指定的列中使用明确的 ASC和DESC关键词,从而对个别列进行排序。 (不论如何排序 被ROLLUP添加的较高级别的总计行仍出如今它们被计算出的行后面)。 LIMIT可用来限制返回客户端的行数。LIMIT 用在 ROLLUP后面, 所以这个限制会取消被ROLLUP添加的行。例 如: mysql> SELECT year, country, product, SUM(profit) -> FROM sales -> GROUP BY year, country, product WITH ROLLUP -> LIMIT 5; +------+---------+------------+-------------+ | year | country | product | SUM(profit) | +------+---------+------------+-------------+ | 2000 | Finland | Computer | 1500 | | 2000 | Finland | Phone | 100 | | 2000 | Finland | NULL | 1600 | | 2000 | India | Calculator | 150 | | 2000 | India | Computer | 1200 | +------+---------+------------+-------------+ 将ROLLUP同 LIMIT一块儿使用可能会产生更加难以解释的结果,缘由是对于理解高汇集行,你所掌握的上下文 较少。 在每一个高汇集行中的NULL 指示符会在该行被送至客户端时产生。服务器会查看最左边的改变值后面的GROUP BY子句指定的列。对于任何结果集合中的,有一个词匹配这些名字的列, 其值被设为 NULL。(若你使用列数字 指定了分组列,则服务器会经过数字肯定将哪一个列设置为 NULL)。 因为在高汇集行中的 NULL值在问询处理阶段被放入结果集合中,你没法将它们在问询自己中做为NULL值检 验。例如,你没法将 HAVING product IS NULL 添加到问询中,从而在输出结果中删去除了高汇集行之外的部 分。 另外一方面, NULL值在客户端不以 NULL 的形式出现, 于是能够使用任何MySQL客户端编程接口进行检验。 12.10.3. 具备隐含字段的GROUP BY MySQL 扩展了 GROUP BY的用途,所以你能够使用SELECT 列表中不出如今GROUP BY语句中的列或运算。这 表明 “对该组的任何可能值 ”。你能够经过避免排序和对没必要要项分组的办法获得它更好的性能。例如,在下 列问询中,你无须对customer.name 进行分组: mysql> SELECT order.custid, customer.name, MAX(payments) -> FROM order,customer -> WHERE order.custid = customer.custid -> GROUP BY order.custid; 在标准SQL中, 你必须将 customer.name添加到 GROUP BY子句中。在MySQL中, 假如你不在ANSI模式中运 行,则这个名字就是多余的。 假如你从 GROUP BY 部分省略的列在该组中不是惟一的,那么不要使用这个功能! 你会获得非预测性结果。 在有些状况下,你能够使用MIN()和MAX() 获取一个特殊的列值,即便他不是惟一的。下面给出了来自包含排序 列中最小值的列中的值: SUBSTR(MIN(CONCAT(RPAD(sort,6,' '),column)),7) See 3.6.4节,“拥有某个字段的组间最大值的行”. 注意,假如你正在尝试遵循标准 SQL, 你不能使用GROUP BY或 ORDER BY子句中的表达式。你能够经过使用 表达式的别名绕过这一限制: mysql> SELECT id,FLOOR(value/100) AS val -> FROM tbl_name -> GROUP BY id, val ORDER BY val; 然而, MySQL容许你使用GROUP BY 及 ORDER BY 子句中的表达式。例如: mysql> SELECT id, FLOOR(value/100) FROM tbl_name ORDER BY RAND(); 若是您想要更改列的类型而不是名称, CHANGE语法仍然要求旧的和新的列名称,即便旧的和新的列名称是一 样的。例如: mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL; 您也能够使用MODIFY来改变列的类型,此时不须要重命名: mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL; · 若是您使用CHANGE或MODITY缩短列长时,列中存在有索引,而且缩短后的列长小于索引长度, 则MySQL会自动缩短索引的长度。 · 当您使用CHANGE或MODIFY更改列的类型时,MySQL会尽可能把原有的列值转化为新的类型。 · 您能够使用FIRST或AFTER col_name在一个表行中的某个特定位置添加列。默认把列添加到最后。您 也能够在CHANGE或MODIFY语句中使用FIRST和AFTER。 · AFTER COLUMN用于指定列的新默认值,或删除旧的默认值。若是旧的默认值被删除同时列值 为NULL,则新的默认值为NULL。若是列值不能为NULL,MySQL会指定一个默认值,请参 见13.1.5节,“CREATE TABLE语法”。 · DROP INDEX用于取消索引。这是MySQL相对于标准SQL的扩展。请参见13.1.7节,“DROP INDEX语 法”。 · 若是列从表中被取消了,则这些列也从相应的索引中被取消。若是组成一个索引的全部列均被取消,则 该索引也被取消。 · 若是一个表只包含一列,则此列不能被取消。若是您想要取消表,应使用DROP TABLE。 · DROP PRIMAY DEY用于取消主索引。注释:在MySQL较早的版本中,若是没有主索引,则DROP PRIMARY KEY会取消表中的第一个UNIQUE索引。在MySQL 5.1中不会出现这种状况。若是在MySQL 5.1中对 没有主键的表使用DROP PRIMARY KEY,则会出现错误信息。 若是您向表中添加UNIQUE KEY或PRIMARY KEY,则UNIQUE KEY或PRIMARY KEY会被储存在非惟一索引之 前,这样MySQL就能够尽早地检查出重复关键字。 · ORDER BY用于在建立新表时,让各行按必定的顺序排列。注意,在插入和删除后,表不会仍保持此顺 序。当您知道多数状况下您会按照特定的顺序查询各行时,能够使用这个选项;在对表进行了大的改动后,通 过使用此选项,您能够提升查询效率。在有些状况下,若是表按列排序,对于MySQL来讲,排序可能会更简 单。 · 若是您对一个MyISAM表使用ALTER TABLE,则全部非惟一索引会被建立到一个单独的批里(和REPAIR TABLE相同)。当您有许多索引时,这样作能够使ALTER TABLE的速度更快。 这项功能能够明确激活。ALTER TABLE...DISABLE KEYS让MySQL中止更新MyISAM表中的非惟一索引。而后使 ALTER TABLE ... ENABLE KEYS MySQL 用从新建立丢失的索引。进行此操做时, 采用一种特殊的算法,比一个 接一个地插入关键字要快不少。所以,在进行成批插入操做前先使关键字禁用能够大大地加快速度。使 用ALTER TABLE ... DISABLE KEYS除了须要得到之前提到的权限之外,还须要得到INDEX权限。 · Innodb存储引擎支持FOREIGN KEY和REFERENCES子句。Innodb存储引擎执行ADD [CONSTRAINT [symbol]] FOREIGN KEY (...) REFERENCES ... (...)。请参见15.2.6.4节,“FOREIGN KEY约束”。对于其它存储 引擎,这些子句会被分析,可是会被忽略。对于全部的存储引擎,CHECK子句会被分析,可是会被忽略。请参 见13.1.5节,“CREATE TABLE语法”。接受这些子句但又忽略子句的缘由是为了提升兼容性,以便更容易地从 其它SQL服务器中导入代码,并运行应用程序,建立带参考数据的表。请参见1.8.5节,“MySQL与标准SQL的差 别”。 · InnoDB支持使用ALTER TABLE来取消外键: · ALTER TABLE yourtablename DROP FOREIGN KEY fk_symbol; 要了解更多信息,请参见15.2.6.4节,“FOREIGN KEY约束”。 · ALTER TABLE忽略DATA DIRECTORY和INDEX DIRECTORY表选项。 · 若是您想要把表默认的字符集和全部字符列(CHAR, VARCHAR, TEXT)改成新的字符集,应使用以下 语句: · ALTER TABLE tbl_name CONVERT TO CHARACTER SET charset_name; 警告:前面的操做转换了字符集之间的列类型。若是您有一列使用一种字符集(如latin1),可是存储的值实 际上使用了其它的字符集(如utf8),这种状况不是您想要的。此时,您必须对这样的列进行如下操做。 ALTER TABLE t1 CHANGE c1 c1 BLOB; ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8; 这种方法可以实现此功能的缘由是,当您转换到BLOB列或从BLOB列转换过来时,并无发生转换。 若是您指定CONVERT TO CHARACTER SET为二进制,则TEXT列被转换到相应的二进制字符串类型(BINARY, VARBINARY, BLOB)。这意味着这些列将再也不有字符集,接下来的CONVERT TO操做也将不适用于这些列。 要仅仅改变一个表的默认字符集,应使用此语句: ALTER TABLE tbl_name DEFAULT CHARACTER SET charset_name; 词语DEFAULT为自选项。若是您在向表中添加一个新列时(例如,使用ALTER TABLE...ADD column)没有指 定字符集,则此时使用的字符集为默认字符集。 警告:ALTER TABLE...DEFAULT CHARACTER SET和ALTER TABLE...CHARACTER SET是等价的,只用于更改 默认的表字符集。 · 若是InnoDB表在建立时,使用了.ibd文件中的本身的表空间,则这样的文件能够被删除和导入。使用此 语句删除.ibd文件: · ALTER TABLE tbl_name DISCARD TABLESPACE; 此语句用于删除当前的.ibd文件,因此应首先确认您有一个备份。若是在表空间被删除后尝试打开表格,则会 出现错误。 要把备份的.ibd文件还原到表中,需把此文件复制到数据库目录中,而后书写此语句: ALTER TABLE tbl_name IMPORT TABLESPACE; 见15.2.6.6节,“使用按表的表空间”。 · 使用mysql_info() C API函数,您能够了解有多少记录已被复制,以及(当使用IGNORE时)有多少记录 因为重复关键字的缘由已被删除 ALTER TABLE也能够用于对带分区的表进行从新分区,功能包括添加、取消、合并和拆分各分区,还可 以用于进行分区维护。 对带分区的表使用partition_options子句和ALTER TABLE能够对表进行从新分区,使用时依 据partition_options定义的分区方法。本子句以PARTITION BY为开头,而后使用与用于CREATE TABLE的partition_options子句同样的语法和规则(要了解详细信息,请参见13.1.5节,“CREATE TABLE语 法”)。注释:MySQL 5.1服务器目前接受此语法,可是不实际执行;等MySQL 5.1开发出来后,将执行此语 法。 用于ALTER TABLE ADD PARTITION的partition_definition子句支持用于CREATE TABLE语句 的partition_definition子句的一样名称的选项。(要了解语法和介绍,请参见13.1.5节,“CREATE TABLE语 法”。)例如,假设您有一个按照如下方式建立的带分区的表: 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,该分区用于储存小于2002的值。添加方法以下: ALTER TABLE t1 ADD PARTITION p3 VALUES LESS THAN (2002); 注释:您不能使用ALTER TABLE向一个没有进行分区的表添加分区。 DROP PARTITION用于取消一个或多个RANGE或LIST分区。此命令不能用于HASH或KEY 分区;用于这两个分 区时,应使用COALESCE PARTITION(见后)。若是被取消的分区其名称列于partition_names清单中,则储存 在此分区中的数据也被取消。例如,若是之前已定义的表t1,您能够采用以下方法取消名称为p0和p1的分区: ALTER TABLE DROP PARTITION p0, p1; ADD PARTITION和DROP PARTITION目前不支持IF [NOT] EXISTS。也不可能对一个分区或一个已分区的表进 行重命名。若是您但愿对一个分区进行重命名,您必须取消分区,再从新创建;若是您但愿对一个已分区的表 进行从新命名,您必须取消全部分区,而后对表进行重命名,再添加被取消的分区。 COALESCE PARTITION能够用于使用HASH或KEY进行分区的表,以便使用number来减小分区的数目。例如, 假设您使用下列方法建立了表t2: CREATE TABLE t2 ( name VARCHAR (30), started DATE ) PARTITION BY HASH(YEAR(started)) PARTITIONS (6); 您能够使用如下命令,把t2使用的分区的数目由6个减小到4个: ALTER TABLE t2 COALESCE PARTITION 2; 包含在最后一个number分区中的数据将被合并到其他的分区中。在此状况下,分区4和分区5将被合并到前4个 分区中(编号为0、一、2和3的分区)。 若是要更改部分分区,但不更改全部的分区,您能够使用REORGANIZE PARTITION。这个命令有多种使用方 法: o 把多个分区合并为一个分区。经过把多个分区的名称列入partition_names清单,并 为partition_definition提供一个单一的定义,能够实现这个功能。 o 把一个原有的分区拆分为多个分区。经过为partition_names命名一个分区,并提供多 个partition_definitions,能够实现这个功能。 o 更改使用VALUES LESS THAN定义的分区子集的范围或更改使用VALUES IN定义的分区子集的值清单。 注释:对于没有明确命名的分区,MySQL会自动提供默认名称p0, p1, p2等。 要了解有关ALTER TALBE...REORANIZE PARTITION命令的详细信息 多个附加子句用于提供分区维护和修补功能。这些功能与用于非分区表的功能相似。这些功能由CHECK TABLE和REPAIR TABLE等命令(这些命令不支持用于分区表)执行。这些子句包括ANALYZE PARTITION, CHECK PARTITION, OPTIMIZE PARTITION, REBUILD PARTITION和REPAIR PARTITION.每一个选项均为一 个partition_names子句,包括一个或多个分区名称。须要更改的表中必须已存在这些分区。多个分区名称用逗 号分隔。要了解更多信息,或要了解举例说明,请参见18.3.3节,“分区维护”。 如下例子展现了ALTER TABLE的使用。首先展现表t1。表t1采用以下方法建立: mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10)); 把表t1从新命名为t2: mysql> ALTER TABLE t1 RENAME t2; 把列a从INTERGER更改成TINYINT NOT NULL(名称保持不变),并把列b从CHAR(10)更改成CHAR(20),同 时把列b从新命名为列c: mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20); 添加一个新的TIMESTAMP列,名称为d: mysql> ALTER TABLE t2 ADD d TIMESTAMP; 在列d和列a中添加索引: mysql> ALTER TABLE t2 ADD INDEX (d), ADD INDEX (a); 删除列c: mysql> ALTER TABLE t2 DROP COLUMN c; 添加一个新的AUTO_INCREMENT整数列,名称为c: mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, -> ADD PRIMARY KEY (c); 注意咱们为c编制了索引(做为PRIMARY KEY),由于AUTO_INCREMENT列必须编制索引。同时咱们定 义c为NOT NULL,由于主键列不能为NULL。 当您添加一个AUTO_INCREMENT列时,列值被自动地按序号填入。对于MyISAM表,您能够在ALTER TABLE之 前执行SET INSERT_ID=value来设置第一个序号,也能够使用AUTO_INCREMENT=value表选项来设置。请参 见13.5.3节,“SET语法”。 若是值大于AUTO_INCREMENT列中的最大值,则您能够使用用于InnoDB表的ALTER TALBE...AUTO_INCREMENT=value表选项,来为新行设置序号。若是值小于列中当前的最大值,不会出现错 误信息,当前的序列值也不改变。 使用MyISAM表时,若是您不更改AUTO_INCREMENT列,则序列号不受影响。若是您取消一 个AUTO_INCREMENT列,而后添加另外一个AUTO_INCREMENT列,则序号从新排列,从1开始。 在建立表格时,您能够使用TEMPORARY关键词。只有在当前链接状况下,TEMPORARY表才是可见的。当链接 关闭时,TEMPORARY表被自动取消。这意味着两个不一样的链接能够使用相同的临时表名称,同时两个临时表 不会互相冲突,也不与原有的同名的非临时表冲突。(原有的表被隐藏,直到临时表被取消时为止。)您必须 拥有CREATE TEMPORARY TABLES权限,才能建立临时表。 若是表已存在,则使用关键词IF NOT EXISTS能够防止发生错误。注意,原有表的结构与CREATE TABLE语句 中表示的表的结构是否相同,这一点没有验证。注释:若是您在CREATE TABLE...SELECT语句中使用IF NOT EXISTS,则不论表是否已存在,由SELECT部分选择的记录都会被插入。 MySQL经过数据库目录中的.frm表格式(定义)文件表示每一个表。表的存储引擎也可能会建立其它文件。对 于MyISAM表,存储引擎能够建立数据和索引文件。所以,对于每一个MyISAM表tbl_name,有三个磁盘文件: 文件做用 tbl_name.frm 表格式(定义)文件 tbl_name.MYD 数据文件 tbl_name.MYI 索引文件 CREATE TABLE用于建立带给定名称的表。您必须拥有表CREATE权限。 容许的表名称的规则列于9.2节,“数据库、表、索引、列和别名”中。默认的状况是,表被建立到当前的数据库 中。若是表已存在,或者若是没有当前数据库,或者若是数据库不存在,则会出现错误。 表名称被指定为db_name.tbl_name,以便在特定的数据库中建立表。不管是否有当前数据库,均可以经过这 种方式建立表。若是您使用加引号的识别名,则应对数据库和表名称分别加引号。例如,`mydb`.`mytbl`是 合法的,可是`mydb.mytbl`不合法。 在建立表格时,您能够使用TEMPORARY关键词。只有在当前链接状况下,TEMPORARY表才是可见的。当链接 关闭时,TEMPORARY表被自动取消。这意味着两个不一样的链接能够使用相同的临时表名称,同时两个临时表 不会互相冲突,也不与原有的同名的非临时表冲突。(原有的表被隐藏,直到临时表被取消时为止。)您必须 拥有CREATE TEMPORARY TABLES权限,才能建立临时表。 若是表已存在,则使用关键词IF NOT EXISTS能够防止发生错误。注意,原有表的结构与CREATE TABLE语句 中表示的表的结构是否相同,这一点没有验证。注释:若是您在CREATE TABLE...SELECT语句中使用IF NOT EXISTS,则不论表是否已存在,由SELECT部分选择的记录都会被插入。 MySQL经过数据库目录中的.frm表格式(定义)文件表示每一个表。表的存储引擎也可能会建立其它文件。对 于MyISAM表,存储引擎能够建立数据和索引文件。所以,对于每一个MyISAM表tbl_name,有三个磁盘文件: 文件做用 tbl_name.frm 表格式(定义)文件 tbl_name.MYD 数据文件 tbl_name.MYI 索引文件 用于表示表的由存储引擎建立的文件在第15章:存储引擎和表类型中描述。 要了解有关各类列类型的性质的通常说明,请参见第11章:列类型。要了解有关空间列类型的说明,请参 见第19章:MySQL中的空间扩展。 · 若是没有指定是NULL或是NOT NULL,则列在建立时假定指定为NULL。 · 一个整数列能够拥有一个附加属性AUTO_INCREMENT。当您向一个已编入索引的AUTO_INCREMENT列 中插入一个NULL值(建议)或0时,此列被设置为下一个序列的值。一般状况下为value+1,此处value是当前 在表中的列的最大值。AUTO_INCREMENT序列从1开始。这样的列必须被定义为一种整数类型,请参 见11.1.1节,“数值类型概述”中的叙述。(值1.0不是整数)。请参见25.2.3.36节,“mysql_insert_id()”。 为--sql-mode服务器选项或sql_mode系统变量指定NO_AUTO_VALUE_ON_ZERO特征位,这样能够把0存储 到AUTO_INCREMENT列中,同时不生成一个新的序列值。请参见5.3.1节,“mysqld命令行选项”。 注释:有时候,每一个表只有一个AUTO_INCREMENT列,此列必须编制索引,不能有DEFAULT值。一 个AUTO_INCREMENT列只有在只包含正数的状况下,才能运行正常。插入一个负数会被认为是插入了一个非 常大的正数。这样作是为了不当数字由正数转为负数时出现精度问题,同时也为了确 保AUTO_INCREMENT列中不会包含0。 对于MyISAM和BDB表,您能够在一个多列关键字中指定一个AUTO_INCREMENT次级列。请参见3.6.9节,“使 用AUTO_INCREMENT”。 为了让MySQL与部分ODBC应用软件相兼容,您能够使用如下查询方法找到最后一个插入行 的AUTO_INCREMENT值: SELECT * FROM tbl_name WHERE auto_col IS NULL · 字符列的定义能够包括一个CHARACTER SET属性,用来指定字符集,也能够指定列的整序。要了解详 细状况,请参见第10章:字符集支持。CHARSET是CHARACTER SET的同义词。 · CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin); MySQL 5.1理解,在字符列定义中的长度规约以字符为单位。(有些早期版本以字节为单位。) · DEFAULT子句用于为列指定一个默认值。默认值必须为一个常数,不能为一个函数或一个表达式,有一 种状况例外。例如,一个日期列的默认值不能被设置为一个函数,如NOW()或CURRENT_DATE。不过,有一 种例外,您能够对TIMESTAMP列指定CURRENT_TIMESTAMP为默认值。请参见11.3.1.1节,“MySQL 4.1中 的TIMESTAMP属性”。 BLOB和TEXT列不能被赋予默认值。 若是在列定义中没有明确的DEFAULT值,则MySQL按照以下规则肯定默认值: 若是列能够使用NULL做为值,则使用DEFAULT NULL子句对列进行定义。(在MySQL的早期版本中也如此。) 若是列不能使用NULL做为值,则MySQL对列进行定义时不使用DEFAULT子句。输入数据时,如 果INSERT或REPLACE语句不包括列的值,则MySQL依据当时的有效的SQL模式操做列: o 若是严格模式没有被启用,则MySQL会根据列数据类型,把列设置为明确的默认值。 o 若是严格模式已被启用,则事务表会出现错误,语句被回滚。对于非事务表,会出现错误,不过,若是 错误出如今一个多行语句中的第二行或后续行,则之前的各行将被插入。 假设表t按下面的方法进行定义: CREATE TABLE t (i INT NOT NULL); 在这种状况下,i没有明确的默认值,因此在严格模式中,每一个后续语句都会产生一个错误,而且没有行被插 入。当未使用严格模式时,只有第三个语句产生错误;明确的默认值被插入到前两个语句中,可是第三个语句 会出现错误,由于DEFAULT(i)不会产生一个值: INSERT INTO t VALUES(); INSERT INTO t VALUES(DEFAULT); INSERT INTO t VALUES(DEFAULT(i)); 见5.3.2节,“SQL服务器模式”。 对于一个给定的表,您能够使用SHOW CREATE TABLE语句来查看那些列有明确的DEFAULT子句。 · 对于列的评注能够使用COMMENT选项来进行指定。评注经过SHOW CREATE TABLE和SHOW FULL COLUMNS语句显示。 · 属性SERIAL能够用做BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE的别名。 · KEY一般是INDEX同义词。若是关键字属性PRIMARY KEY在列定义中已给定,则PRIMARY KEY也能够只 指定为KEY。这么作的目的是与其它数据库系统兼容。 · 在UNIQUE索引中,全部的值必须互不相同。若是您在添加新行时使用的关键字与原有行的关键字相 同,则会出现错误。例外状况是,若是索引中的一个列容许包含NULL值,则此列能够包含多个NULL值。此例 外状况不适用于BDB表。在BDB中,带索引的列只容许一个单一NULL。 · PRIMARY KEY是一个惟一KEY,此时,全部的关键字列必须定义为NOT NULL。若是这些列没有被明确 地定义为NOT NULL,MySQL应隐含地定义这些列。一个表只有一个PRIMARY KEY。若是您没有PRIMARY KEY而且一个应用程序要求在表中使用PRIMARY KEY,则MySQL返回第一个UNIQUE索引,此索引没有做 为PRIMARY KEY的NULL列。 · 在已建立的表中,PRIMARY KEY的位置最靠前,而后是全部的UNIQUE索引,而后是非惟一索引。这可 以帮助MySQL优化程序选择优先使用哪一个索引,而且更快速的检测出重复的UNIQUE关键字。 · PRIMARY KEY能够是一个多列索引。可是,在列规约中使用PRIMARY KEY关键字属性没法建立多列索 引。这么作只能把一个列标记为主列。您必须使用一个单独的PRIMARY KEY(index_col_name, ...)子句。 · 若是PRIMARY KEY或UNIQUE索引只包括一个列,而且此列为整数类型,则您也能够在SELECT语句中 把此列做为_rowid引用。 · 在MySQL中,PRIMARY KEY的名称为PRIMARY。对于其它索引,若是您没有赋予名称,则索引被赋予 的名称与第一个已编入索引的列的名称相同,并自选添加后缀(_2, _3,...),使名称为惟一名称。您能够使 用SHOW INDEX FROM tbl_name来查看表的索引名称。请参见13.5.4.11节,“SHOW INDEX语法”。 · 部分存储引擎容许您在建立索引时指定索引类型。index_type指示语句的语法是USING type_name。 示例: CREATE TABLE lookup (id INT, INDEX USING BTREE (id)) ENGINE = MEMORY; 要了解有关USING的详细说明,请参见13.1.4节,“CREATE INDEX语法”。 要了解有关MySQL如何使用索引的更多信息,请参见7.4.5节,“MySQL如何使用索引”。 · 在MySQL 5.1中,只有MyISAM,InnoDB, BDB和MEMORY存储引擎支持在含有NULL值的列中编索引。 在其它状况下,您必须定义已编索引的列为NOT NULL,不然会出现错误。 · 在一个索引规约中使用col_name(length)语法,您能够建立一个索引,此索引只使用一 个CHAR或VARCHAR列的第一个length字符。只对列值的前缀编制索引能够使索引文件大大减少。请参 见7.4.3节,“列索引”。 MyISAM和InnoDB存储引擎也支持对BLOB和TEXT列编索引。当对BLOB或TEXT列编索引时,您必须为索引指 定一个前缀长度。例如: CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10))); 对于MyISAM和InnoDB表,前缀最长能够为1000字节,对于其它表格类型,最长能够为255字节。注意前缀长 度限值以字节为单位,而在CREATE TABLE语句中的前缀长度用字符数目来表述。当为一个使用多字节字符集 的列指定前缀长度时,必定要考虑到这一点。 · 一个index_col_name规约能够以ASC或DESC结尾。这些关键词能够在未来进行扩展,用于指定升序或 降序的索引值存储。当前,这些关键词被分析可是被忽略;索引值均以升序储存。 · 当您在SELECT中的TEXT列或BLOB列中使用ORDER BY或GROUP BY时,服务器只使用初始的字节数目 对值进行分类。字节数目由max_sort_length系统变量进行指示。请参见11.4.3节,“BLOB和TEXT类型”。 · 您能够建立特殊的FULLTEXT索引,用于全文搜索。只有MyISAM表类型支持FULLTEXT索 引。FULLTEXT索引只能够从CHAR, VARCHAR和TEXT列中建立。整个列都会被编入索引;不支持对部分列编索 引。若是已指定,前缀长度会被忽略。要了解运行的详细说明,请参见12.7节,“全文搜索功能”。 · 您能够为空间列类型建立SPATIAL索引。只有MyISAM表支持空间类型,已编索引的列必须声明为NOT NULL。请参见第19章:MySQL中的空间扩展。 · InnoDB表支持对外键限制条件进行检查。请参见15.2节,“InnoDB存储引擎”。注意, 在InnoDB中,FOREIGN KEY语法比本节开始时介绍的CREATE TABLE语句的语法更严格:被引用的表中的列必 须有明确的命名。InnoDB支持外键的ON DELETE和ON UPDATE两种操做。有关精确语法的说明,请参 见15.2.6.4节,“FOREIGN KEY约束”。 对于其它存储引擎,MySQL服务器对CREATE TABLE语句中的FOREIGN KEY和REFERENCES语法进行分析,但 不采起进一步的行动。全部的存储引擎均对CHECK子句进行分析,可是忽略CHECK子句。请参 见1.8.5.5节,“外键”。 · 对于MyISAM表,每一个NULL列要多占用一位,进位到距离最近的字节。最大记录长度(以字节为单位) 按照以下方法计算: · row length = 1 · + (sum of column lengths) · + (number of NULL columns + delete_flag + 7)/8 · + (number of variable-length columns) 对于采用静态记录格式的表,delete_flag为1。静态表在行记录中使用一位用做位标记。位标记指示该行是否 已被删除。对于动态表,delete_flag为0,由于在动态行标题中已存储了位标记。 这些计算方法不适用于InnoDB表。对于InnoDB表,NULL列的存储量与NOT NULL列的存储量没有区别。 ENGINE和TYPE选项用于为表指定存储引擎。ENGINE是首选的选项名称。 ENGINE和TYPE选项采用如下值: 存储引擎说明 ARCHIVE 档案存储引擎。请参见15.8节,“ARCHIVE存储引擎”。 BDB 带页面锁定的事务安全表。也称为BerkeleyDB。请参见15.5节,“BDB (BerkeleyDB)存储引 擎”。 CSV 值之间用逗号隔开的表。请参见15.9节,“CSV存储引擎。 EXAMPLE 示例引擎。请参见15.6节,“EXAMPLE存储引擎”。 FEDERATED 能够访问远程表的存储引擎。请参见15.7节,“FEDERATED存储引擎”。 HEAP 见15.4节,“MEMORY (HEAP)存储引擎”。 (OBSOLETE) ISAM 在MySQL 5.1中没有此引擎。若是您要从之前的版本升级到MySQL 5.1,您应该在进行升级前 把原有的ISAM表转换为MyISAM表。请参见第15章:存储引擎和表类型。 InnoDB 带行锁定和外键的事务安全表。请参见15.2节,“InnoDB存储引擎”。 MEMORY 本表类型的数据只保存在存储器里。(在早期MySQL版本中被称为HEAP。) MERGE MyISAM表的集合,做为一个表使用。也称为MRG_MyISAM。请参见15.3节,“MERGE存储引 擎”。 MyISAM 二进制轻便式存储引擎,此引擎是MySQL所用的默认存储引擎。请参见15.1节,“MyISAM存储 引擎”。 NDBCLUSTER 成簇表,容错表,以存储器为基础的表。也称为NDB。请参见第17章:MySQL簇。 要了解有关MySQL存储引擎的更多信息,请参见第15章:存储引擎和表类型。 若是被指定的存储引擎没法利用,则MySQL使用MyISAM代替。例如,一个表定义包括ENGINE=BDB选项,但 是MySQL服务器不支持BDB表,则表被建立为MyISAM表。这样,若是您在主机上有事务表,但在从属机上创 建的是非交互式表(以加快速度)时,能够进行复制设置。在MySQL 5.1中,若是没有遵照存储引擎规约,则 会出现警告。 其它表选项用于优化表的性质。在多数状况下,您没必要指定表选项。这些选项适用于全部存储引擎,另有说明 除外: · AUTO_INCREMENT 表的初始AUTO_INCREMENT值。在MySQL 5.1中,本选项只适用于MyISAM和MEMORY表。InnoDB也支持本选 项。若是引擎不支持AUTO_INCREMENT表选项,则要设置引擎的第一个auto-increment值,需插入一 个“假”行。该行的值比建立表后的值小一,而后删除该假行。 对于在CREATE TABLE语句中支持AUTO_INCREMENT表选项的引擎,您也能够使用ALTER TABLE tbl_name AUTO_INCREMENT = n来从新设置AUTO_INCREMENT值。 · AVG_ROW_LENGTH 表中平均行长度的近似值。只须要对含尺寸可变的记录的大型表进行此项设置。 当建立一个MyISAM表时,MySQL使用MAX_ROWS和AVG_ROW_LENGTH选项的乘积来肯定得出的表有多大。 若是有一个选项未指定,则表的最大尺寸为65,536TB数据。(若是操做系统不支持这么大的文件,则表的尺寸 被限定在操做系统的限值处。)若是您想缩小指针尺寸使索引更小,速度更快,而且您不须要大文件,则您可 以经过设置myisam_data_pointer_size系统变量来减小默认指针的尺寸。(见5.3.3节,“服务器系统变量”。) 若是您但愿全部的表能够扩大,超过默认限值,而且愿意让表稍微慢点,并稍微大点,则您能够经过设置此变 量增长默认指针的尺寸。 · [DEFAULT] CHARACTER SET 用于为表指定一个默认字符集。CHARSET是CHARACTER SET的同义词。 对于CHARACTER SET. · COLLATE 用于为表指定一个默认整序。 · CHECKSUM 若是您但愿MySQL随时对全部行进行实时检验求和(也就是,表变动后,MySQL自动更新检验求和),则应把 此项设置为1。这样作,表的更新速度会略微慢些,可是更容易寻找到受损的表。CHECKSUM TABLE语句用于 报告检验求和(仅限于MyISAM)。 · COMMENT 表的注释,最长60个字符。 · CONNECTION FEDERATED表的链接字符串。( 注释:较早版本的MySQL使用COMMENT选项用于链接字符串。 · MAX_ROWS 您打算储存在表中的行数目的最大值。这不是一个硬性限值,而更像一个指示语句,指示出表必须能存储至少 这么多行。 · MIN_ROWS 您打算存储在表中的行数目的最小值。 · PACK_KEYS 若是您但愿索引更小,则把此选项设置为1。这样作一般使更新速度变慢,同时阅读速度加快。把选项设置 为0能够取消全部的关键字压缩。把此选项设置为DEFAULT时,存储引擎只压缩长的CHAR或VARCHAR列(仅 限于MyISAM)。 若是您不使用PACK_KEYS,则默认操做是只压缩字符串,但不压缩数字。若是您使用PACK_KEYS=1,则对数 字也进行压缩。 在对二进制数字关键字进行压缩时,MySQL采用前缀压缩: o 每一个关键字须要一个额外的字节来指示前一个关键字中有多少字节与下一个关键字相同。 o 指向行的指针以高位字节优先的顺序存储在关键字的后面,用于改进压缩效果。 这意味着,若是两个连续行中有许多相同的关键字,则后续的“相同”的关键字一般只占用两个字节(包括指向 行的指针)。与此相比,常规状况下,后续的关键字占用storage_size_for_key + pointer_size(指针尺寸一般 为4)。可是,只有在许多数字相同的状况下,前缀压缩才有好处。若是全部的关键字彻底不一样,而且关键字 不能含有NULL值,则每一个关键字要多使用一个字节。(在这种状况中,储存压缩后的关键字的长度的字节与 用于标记关键字是否为NULL的字节是同一字节。) · PASSWORD 使用密码对.frm文件加密。在标准MySQL版本中,本选项不起任何做用。 · DELAY_KEY_WRITE 若是您想要延迟对关键字的更新,等到表关闭后再更新,则把此项设置为1(仅限于MyISAM)。 · ROW_FORMAT 定义各行应如何储存。当前,此选项只适用于MyISAM表。对于静态行或长度可变行,此选项值能够 为FIXED或DYNAMIC。myisampack用于把类型设置为COMPRESSED。请参见15.1.3节,“MyISAM表的存储 格式”。 在默认状况下,InnoDB记录以压缩格式存储(ROW_FORMAT=COMPACT)。经过指 定ROW_FORMAT=REDUNDANT,仍然能够申请用于较早版本的MySQL中的非压缩格式。 · RAID_TYPE 在MySQL 5.0中,RAID支持被删除了。要了解有关RAID的说明,请参 见http://dev.mysql.com/doc/refman/4.1/en/create-table.html。 · UNION 当您想要把一组相同的表看成一个表使用时,采用UNION。UNION仅适用于MERGE表。请参 见15.3节,“MERGE存储引擎”。 对于您映射到一个MERGE表上的表,您必须拥有SELECT, UPDATE和DELETE权限。(注释:之前,全部被使 用的表必须位于同一个数据库中,并做为MERGE表。这些限制再也不适用。) · INSERT_METHOD 若是您但愿在MERGE表中插入数据,您必须用INSERT_METHOD指定应插入行的表。INSERT_METHOD选项仅 用于MERGE表。使用FIRST或LAST把行插入到第一个或最后一个表中;或者使用NO,阻止插入行。请参 见15.3节,“MERGE存储引擎”。 · DATA DIRECTORY, INDEX DIRECTORY 经过使用DATA DIRECTORY='directory'或INDEX DIRECTORY='directory',您能够指定MyISAM存储引擎放置 表格数据文件和索引文件的位置。注意,目录应是通向目录的完整路径(不是相对路径)。 仅当您没有使用--skip-symbolic-links选项时,DATA DIRECTORY, INDEX DIRECTORY才能使用。操做系统必 须有一个正在工做的、线程安全的realpath()调用。要了解全面信息,请参见7.6.1.2节,“在Unix平台上使用表 的符号连接”。 · 对于用CREATE TABLE建立的表,能够使用partition_options控制分区。若是使用了partition_options, 则其中必须包含至少一个PARTITION BY子句。本子句包含用于肯定分区的函数;该函数会返回一个整值,范 围从1到num。此处num为分区的数目。此函数中能够使用的选项显示在下面的清单中。要点:在本节开始时 介绍的用于partition_options的语法中显示的选项,并非都能用于全部分区类型。要了解各类类型具体的信 息,请参见如下各种型的清单。要了解有关在MySQL中的分区的操做和使用状况的全面说明,以及要了解表 建立的示例和与MySQL分区有关的其它命令,请参见第18章:分区。 o HASH(expr):用于混编一个或多个列,建立一个关键字,用于放置行,并肯定行的位置。expr是一 个表达式,使用一个或多个表中的列。该表达式能够是任何可以生成单一整值的合法的MySQL表达式(包 括MySQL函数)。例如,这些都是有效的CREATE TABLE语句,语句中使用了PARTITION BY HASH: o CREATE TABLE t1 (col1 INT, col2 CHAR(5)) o PARTITION BY HASH(col1); o o CREATE TABLE t1 (col1 INT, col2 CHAR(5)) o PARTITION BY HASH( ORD(col2) ); o o CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) o PARTITION BY HASH ( YEAR(col3) ); VALUES LESS THAN或VALUES IN子句不能和PARTITION BY HASH一块儿使用。 PARTITION BY HASH使用expr被分区数目所除后的余数(也就是模数)。要了解示例和其它信息,请参 见18.2.3节,“HASH分区”。 LENEAR关键词须要一种不一样的算法。在这种状况下,经过一次或屡次逻辑AND运算得出的结果,计算出存储 记录的分区的数目。要了解线形混编的讨论和示例,请参见18.2.3.1节,“LINEAR HASH分区”。 o KEY(column_list):与HASH近似,除了有一点不同,即MySQL提供了混编函数,以保证均匀的数据分 布。column_list自变量只是各列的一个清单。本示例显示了由关键字进行分区的一个简单的表,分为4个分 区: o CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) o PARTITION BY KEY(col3) o PARTITIONS 4; 采用LINEAR关键词,您能够对由关键字分区的表进行线形分区。这与由HASH进行分区的表格有一样的效果; 也就是说,使用&操做符查找分区数目,而不是使用模数(详细说明见18.2.3.1节,“LINEAR HASH分 区”和18.2.4节,“KEY分区”)。本示例采用了关键字线形分区,用来在5个分区之间分配数据: CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY LINEAR KEY(col3) PARTITIONS 5; VALUES LESS THAN或VALUES IN子句不能和PARTITION BY KEY一块儿使用。 o RANGE:在此状况下,expr使用一套VALUES LESS THAN操做符显示了某一范围内的值。当使用范围分 区时,您必须使用VALUES LESS THAN定义至少一个分区。VALUES IN不能和范围分区一块儿使用。 VALUES LESS THAN能够与一个文字值同时使用,或者与一个能够求算单一值的表达式同时使用。 举例说明,假设您有一个表,您但愿采用如下方法对包含年份值的一列进行分区: 分区编号: 年份范围: 0 1990之前 1 1991 - 1994 2 1995 - 1998 3 1999 - 2002 4 2003 - 2005 5 2006年之后 采用这种分区方法的表能够经过以下CREATE TABLE语句实现: CREATE TABLE t1 ( year_col INT, some_data 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 (2002), PARTITION p4 VALUES LESS THAN (2006), PARTITION p5 VALUES LESS THAN MAXVALUE ); PARTITION ... VALUES LESS THAN ...语句按顺序执行。VALUES LESS THAN MAXVALUE的做用是指定大于最 大值的“其他”的值。 注意,VALUES LESS THAN子句按顺序执行,执行方式相似于switch ... case语段的一部分(许多编程语言, 如C, Java和PHP也如此)。也就是说,子句必须按照这样一种方法排列,每个后续的VALUES LESS THAN中 指定的上限值大于前一个VALUES LESS THAN中指定的上限值,并在清单的最后加一个参照性的MAXVALUE。 VALUES IN与一系列的值同时使用。举例说明,您能够建立以下的分区方法: CREATE TABLE client_firms ( id INT, name VARCHAR(35) ) PARTITION BY RANGE (id) ( PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21), PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22), PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23), PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24) ); 当前,与VALUES IN...同时使用的值必须只包含整数值。 (由于此表只使用VALUES IN表达式进行分区,您也能够用PARTITION BY LIST代替,而不是使用PARTITION BY RANGE。请参见下一条。) 在使用VALUES LESS THAN或VALUES IN状况下,每一个分区使用PARTITION name定义,此处name是分区的标 识名,后面接VALUES...子句。 o LIST(expr):当根据含有一系列限定性值(例如州代码或国家代码)的列进行分区时使用。在这种状况 下,全部与特定的州或国家有关的记录都被分配到一个单一分区中,或者能够预留出一个分区,用于一系列特 定的州或国家。LIST(expr)与RANGE相似,除了一点之外,即只有VALUES IN能够被用于为每一个分区指定值。 当使用清单分区时,您必须使用VALUES IN定义至少一个分区。VALUES LESS THAN不能与PARTITION BY LIST一块儿使用。 o 分区数目能够使用PARTITION num子句,自选进行指定,此处,num是分区的数目。若是本子句和其 它PARTITION子句同时使用,则num必须与使用PARTITION子句说明的分区的总数相等。 注释:不论您在建立一个由RANGE或LIST进行分区的表时是否使用了PARTITIONS子句,您必须在表定义中包 括至少一个PARTITION VALUES(见后)。 o 一个分区能够自选分隔成多个子分区。使用自选的SUBPARTITION BY子句能够指示。子分区能够 由HASH或KEY进行分隔。两种方法创建的子分区均为LINEAR。分隔子分区时的操做方式与之前描述的分区类 型的操做方式同样。(没法由LIST或RANGE进行子分区分隔。) 使用SUBPARTITIONS关键词,后面接一个整值,能够对子分区的数目进行指示。 · 使用一个partition_definition子句能够对每一个分区分别进行定义。下面是组成这个子句的各个部分: o PARTITION partition_name:用于为分区指定一个逻辑名称。 o VALUE子句:对于范围分区,每一个分区必须包括一个VALUES LESS THAN子句;对于清单分区,您必须 为每一个分区指定一个VALUES IN子句。本子句用于肯定哪些行将被存储到此分区中。要了解语法示例,请参 见第18章:分区中对分区类型的讨论。 o 自选的COMMENT子句能够用于描述分区。注释必须加单引号。举例说明: o COMMENT = 'Data for the years previous to 1999' o DATA DIRECTORY和INDEX DIRECTORY能够被用于指示本分区的数据和索引各自的存储位置的目 录。data_dir和index_dir都必须是绝对系统路径。例如: o CREATE TABLE th (id INT, name VARCHAR(30), adate DATE) o PARTITION BY LIST(YEAR(adate)) o ( o PARTITION p1999 VALUES IN (1995, 1999, 2003) DATA DIRECTORY = '/var/appdata/95/data' INDEX DIRECTORY = '/var/appdata/95/idx', o PARTITION p2000 VALUES IN (1996, 2000, 2004) DATA DIRECTORY = '/var/appdata/96/data' INDEX DIRECTORY = '/var/appdata/96/idx', o PARTITION p2001 VALUES IN (1997, 2001, 2005) DATA DIRECTORY = '/var/appdata/97/data' INDEX DIRECTORY = '/var/appdata/97/idx', o PARTITION p2000 VALUES IN (1998, 2002, 2006) DATA DIRECTORY = '/var/appdata/98/data' INDEX DIRECTORY = '/var/appdata/98/idx' ); DATA DIRECTORY和INDEX DIRECTORY的操做方法与CREATE TABLE语句中的table_option子句的操做方法一 样。此table_option子句用于位于MyISAM表管理程序下的各表。 能够为每一个分区指定一个数据目录和一个索引目录。若是不指定,则数据和索引被存储在默认的MySQL数据目 录中。 o MAX_ROWS和MIN_ROWS分别用于将被存储在分区中的行数目最大值和行数目最小 值。max_number_of_rows和min_number_of_rows的值必须为正整数。和具备一样名称的桌面选项一 样,max_number_of_rows和min_number_of_rows只做为对服务器的“建议”值,并非硬性限值。 o 自选的TABLESPACE子句能够用于为分区指定一个桌面空间。仅用于MySQL Cluster。 o 自选的[STORAGE] ENGINE子句能够把本分区中表的类型改成指定的类型。表的类型能够是本MySQL服 务器支持的全部类型。STORAGE关键字和等号(=)均为自选项。若是没有使用此选项设置分区存储引擎,则适 用于整个表的引擎能够用于此分区。 注释:分区管理程序对于PARTITION和SUBPARTITION均接受[STORAGE] ENGINE选项。目前,此子句的使用 方式仅限于对全部的分区或子分区设置同一个存储引擎,若是试图在同一个表内对不一样的分区或子分区设置不 同的存储引擎,则会出现错误ERROR 1469 (HY000):在本版本的MySQL中,不容许在各分区中混用管理程 序。咱们打算在未来的MySQL 5.1版本中加入这种对分区的限定。 o NODEGROUP选项能够用于使本分区能够做为节点组的一部分,节点组使用node_group_id识别。本选 项仅适用于MySQL Cluster。 o 分区定义能够自选地包含一个或多个subpartition_definition子句。每一个这种子句至少包 括SUBPARTITION name,此处,name是子分区的识别名称。除了用SUBPARTITION代替PARTITION关键词 外,用于子分区定义的语法与用于分区定义的语法同样。 子分区必须由HASH或KEY完成,而且只能对RANGE或LIST分区进行子分区。请参见18.2.5节,“子分区”。 · 分区能够修改、合并、添加到表中,或从表中删去。要了解有关完成这些任务的MySQL命令的基本说 明,请参见13.1.2节,“ALTER TABLE语法”。要了解详细的说明和示例,请参见18.3节,“分区管理”。 您能够在CREATE TABLE语句的末尾添加一个SELECT语句,在一个表的基础上建立表。 CREATE TABLE new_tbl SELECT * FROM orig_tbl; MySQL会对SELECT中的全部项建立新列。举例说明: mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT, -> PRIMARY KEY (a), KEY(b)) -> TYPE=MyISAM SELECT b,c FROM test2; 本语句用于建立含三个列(a, b, c)的MyISAM表。注意,用SELECT语句建立的列附在表的右侧,而不是覆盖 在表上。参考如下示例: mysql> SELECT * FROM foo; +---+ | n | +---+ | 1 | +---+ mysql> CREATE TABLE bar (m INT) SELECT n FROM foo; Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM bar; +------+---+ | m | n | +------+---+ | NULL | 1 | +------+---+ 1 row in set (0.00 sec) 对应于表foo中的每一行,在表bar中插入一行,含有表foo中的值以及新列中的默认值。 在由CREATE TABLE...SELECT生成的表中,只在CREATE TABLE部分中命名的列首先出现。在两个部分中都命 名的列和只在SELECT部分中命名的列随后出现。也能够经过指定CREATE TABLE部分中的列覆盖SELECT列中 的数据类型。 若是在把数据复制到表中时出现错误,则表会自动被取消,不会被建立。 CREATE TABLE...SELECT不会自动建立任何索引。索引须要专门建立,以便使语句的灵活性更强。若是您但愿 为已建立的表创建索引,您应在SELECT语句前指定索引。 mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo; 列的类型会发生部分转化。例如,AUTO_INCREAMENT属性不会被保留,VARCHAR列会变成CHAR列。 当使用CREATE...SELECT建立表时,在查询时必定要对功能调用和表达式起别名。若是不起别名, 则CREATE语句会出现错误或者生成不符合须要的列名称。 CREATE TABLE artists_and_works SELECT artist.name, COUNT(work.artist_id) AS number_of_works FROM artist LEFT JOIN work ON artist.id = work.artist_id GROUP BY artist.id; 您也能够明确地为一个已生成的列指定类型: CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar; 根据其它表的定义(包括在原表中定义的全部的列属性和索引),使用LIKE建立一个空表: CREATE TABLE new_tbl LIKE orig_tbl; CREATE TABLE...LIKE不会复制对原表或外键定义指定的DATA DIRECTORY或INDEX DIRECTORY表选项。 您能够在SELECT前增长IGNORE或REPLACE,指示如何对复制惟一关键字值的记录进行操纵。使 用IGNORE后,若是新记录复制了原有的惟一关键字值的记录,则新记录被丢弃。使用REPLACE后,新记录替 换具备相同的惟一关键字值的记录。若是没有指定IGNORE或REPLACE,则出现多重惟一关键字值时会致使发 生错误。 为了确保更新日志/二进位日志能够被用于再次建立原表,MySQL不容许在CREATE TABLE...SELECT过程当中进 行联合插入 给表重命名 RENAME TABLE current_db.tbl_name TO other_db.tbl_name; 若是您编写的DELETE语句中没有WHERE子句,则全部的行都被删除。当您不想知道被删除的行的数目时,有 一个更快的方法,即便用TRUNCATE TABLE。请参见13.2.9节,“TRUNCATE语法”。 若是您删除的行中包括用于AUTO_INCREMENT列的最大值,则该值被从新用于BDB表,可是不会被用 于MyISAM表或InnoDB表。若是您在AUTOCOMMIT模式下使用DELETE FROM tbl_name(不含WHERE子句) 删除表中的全部行,则对于全部的表类型(除InnoDB和MyISAM外),序列从新编排。对于InnoDB表,此项操 做有一些例外,在15.2.6.3节,“AUTO_INCREMENT列如何在InnoDB中运行”中进行了讨论。 对于MyISAM和BDB表,您能够把AUTO_INCREMENT次级列指定到一个多列关键字中。在这种状况下,从序列 的顶端被删除的值被再次使用,甚至对于MyISAM表也如此。请参见3.6.9节,“使用AUTO_INCREMENT”。 DELETE语句支持如下修饰符: · 若是您指定LOW_PRIORITY,则DELETE的执行被延迟,直到没有其它客户端读取本表时再执行。 · 对于MyISAM表,若是您使用QUICK关键词,则在删除过程当中,存储引擎不会合并索引端结点,这样可 以加快部分种类的删除操做的速度。 · 在删除行的过程当中,IGNORE关键词会使MySQL忽略全部的错误。(在分析阶段遇到的错误会以常规方 式处理。)因为使用本选项而被忽略的错误会做为警告返回。 删除操做的速度会受到一些因素的影响 在MyISAM表中,被删除的记录被保留在一个带连接的清单中,后续的INSERT操做会从新使用旧的记录位置。 要从新使用未使用的空间并减少文件的尺寸,则使用OPTIMIZE TABLE语句或myisamchk应用程序从新编排 表。OPTIMIZE TABLE更简便,可是myisamchk速度更快。请参见13.5.2.5节,“OPTIMIZE TABLE语 法”和第7章:优化。 QUICK修饰符会影响到在删除操做中索引端结点是否合并。当用于被删除的行的索引值被来自后插入的行的相 近的索引值代替时,DELETE QUICK最为适用。在此状况下,被删除的值留下来的空穴被从新使用。 未充满的索引块跨越某一个范围的索引值,会再次发生新的插入。当被删除的值致使出现未充满的索引块 时,DELETE QUICK没有做用。在此状况下,使用QUICK会致使未利用的索引中出现废弃空间。下面是此种情 况的举例说明: 1. 建立一个表,表中包含已编索引的AUTO_INCREMENT列。 2. 在表中插入不少记录。每次插入会产生一个索引值,此索引值被添加到索引的高端处。 3. 使用DELETE QUICK从列的低端处删除一组记录。 在此状况下,与被删除的索引值相关的索引块变成未充满的状态,可是,因为使用了QUICK,这些索引块不会 与其它索引块合并。当插入新值时,这些索引块仍为未充满的状态,缘由是新记录不含有在被删除的范围内的 索引值。另外,即便您此后使用DELETE时不包含QUICK,这些索引块也还是未充满的,除非被删除的索引值 中有一部分碰巧位于这些未充满的块的之中,或与这些块相邻。在这些状况下,若是要从新利用未使用的索引 空间,需使用OPTIMIZE TABLE。 若是您打算从一个表中删除许多行,使用DELETE QUICK再加上OPTIMIZE TABLE能够加快速度。这样作能够 从新创建索引,而不是进行大量的索引块合并操做。 用于DELETE的MySQL惟一的LIMIT row_count选项用于告知服务器在控制命令被返回到客户端前被删除的行的 最大值。本选项用于确保一个DELETE语句不会占用过多的时间。您能够只重复DELETE语句,直到相关行的数 目少于LIMIT值为止。 若是DELETE语句包括一个ORDER BY子句,则各行按照子句中指定的顺序进行删除。此子句只在与LIMIT联用 是才起做用。例如,如下子句用于查找与WHERE子句对应的行,使用timestamp_column进行分类,并删除第 一(最旧的)行: DELETE FROM somelog WHERE user = 'jcole' ORDER BY timestamp_column LIMIT 1; 您能够在一个DELETE语句中指定多个表,根据多个表中的特定条件,从一个表或多个表中删除行。不过,您 不能在一个多表DELETE语句中使用ORDER BY或LIMIT。 table_references部分列出了包含在联合中的表。此语法在13.2.7.1节,“JOIN语法”中进行了说明。 对于第一个语法,只删除列于FROM子句以前的表中的对应的行。对于第二个语法,只删除列于FROM子句之中 (在USING子句以前)的表中的对应的行。做用是,您能够同时删除许多个表中的行,并使用其它的表进行搜 索: DELETE t1, t2 FROM t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id; 或: DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id; 当搜索待删除的行时,这些语句使用全部三个表,可是只从表t1和表t2中删除对应的行。 以上例子显示了使用逗号操做符的内部联合,可是多表DELETE语句能够使用SELECT语句中容许的全部类型的 联合,好比LEFT JOIN。 本语法容许在名称后面加.*,以便与Access相容。 若是您使用的多表DELETE语句包括InnoDB表,而且这些表受外键的限制,则MySQL优化程序会对表进行处 理,改变原来的从属关系。在这种状况下,该语句出现错误并返回到前面的步骤。要避免此错误,您应该从单 一表中删除,并依靠InnoDB提供的ON DELETE功能,对其它表进行相应的修改。 注释:当引用表名称时,您必须使用别名(若是已给定): DELETE t1 FROM test AS t1, test2 WHERE ... 进行多表删除时支持跨数据库删除,可是在此状况下,您在引用表时不能使用别名。举例说明: DELETE test1.tmp1, test2.tmp2 FROM test1.tmp1, test2.tmp2 WHERE ... 目前,您不能从一个表中删除,同时又在子查询中从同一个表中选择。 DO语法 DO expr [, expr] ... DO用于执行表达式,可是不返回任何结果。DO是SELECT expr的简化表达方式。DO有一个优点,就是若是您 不太关心结果的话,DO的速度稍快。 DO主要用于执行有反作用的函数,好比RELEASE_LOCK()。 HANDLER语法 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语句提供通往表存储引擎接口的直接通道。HANDLER能够用于MyISAM和InnoDB表。 HANDLER...OPEN语句用于打开一个表,经过后续的HANDLER...READ语句创建读取表的通道。本表目标不会 被其它线程共享,也不会关闭,直到线程调用HANDLER...CLOSE或线程停止时为止。若是您使用一个别名打开 表,则使用其它HANDLER语句进一步参阅表是必须使用此别名,而不能使用表名。 若是被指定的索引知足给定的值而且符合了WHERE条件,则第一个HANDLER...READ语法取出一行。若是您有 一个多列索引,则指定索引列值为一个用逗号隔开的清单。既能够为索引中的全部列指定值,也能够为索引列 的最左边的前缀指定值。假设一个索引包括三个列,名称为col_a, col_b,和col_c,并按此顺序排 列。HANDLER语句能够为索引中的全部三个列指定值,或者为一个最左边前缀中的各列指定值。举例说明: HANDLER ... index_name = (col_a_val,col_b_val,col_c_val) ... HANDLER ... index_name = (col_a_val,col_b_val) ... HANDLER ... index_name = (col_a_val) ... 第二个HANDLER...READ语法按索引的顺序从表中取出一行。索引的顺序符合WHERE条件。 第三个HANDLER...READ语法按天然行的顺序从表中取出一行。天然行的顺序符合WHERE条件。当想要对整个 表进行扫描时,此语句比HANDLER tbl_name READ index_name更快。天然行的顺序指的是行存储 在MyISAM表数据文件的顺序。本语句也适用于InnoDB表,可是由于没有独立的数据文件,因此没有这类概 念。 不使用LIMIT子句时,全部形式的HANDLER...READ语句均只取出一行。若是要返回多个行,应加入一 个LIMIT子句。本语句于SELECT语句的语法同样。请参见13.2.7节,“SELECT语法”。 HANDLER...CLOSE用于关闭使用HANDLER...OPEN打开的表。 注释:要使用HANDLER接口来查阅一个表的PRIMARY KEY,应使用带引号的识别符`PRIMARY`: HANDLER tbl_name READ `PRIMARY` > (...); HANDLER是比较低级别的语句。例如,它不能提供一致性。也就是说,HANDLER...OPEN不能为表作快照,也 不能锁定表。这意味着,当一个HANDLER...OPEN语句被编写后,表数据能够被更改(用此线程或用其它线 程),而且这些更改只会部分地出如今HANDLER...NEXT或HANDLER...PREV扫描中。 使用HANDLER接口代替常规的SELECT语句有多个缘由: · HANDLER比SELECT更快: o 一个指定的存储引擎管理程序目标为了HANDLER...OPEN进行整序。该目标被从新用于该表的后续 的HANDLER语句;不须要对每一个语句进行从新初始化。 o 涉及的分析较少。 o 没有优化程序或查询校验开销。 o 在两个管理程序请求之间,不须要锁定表。 o 管理程序接口不须要提供外观一致的数据(例如,容许无条理的读取),因此存储引擎能够使用优化, 而SELECT一般不容许使用优化。 · 有些应用程序使用与ISAM近似的接口与MySQL链接。使用HANDLER能够更容易地与这些应用程序连 接。 · HANDLER容许您采用一种特殊的方式进出数据库。而使用SELECT时难以采用(或不可能采用)这种方 式。有些应用程序能够提供一个交互式的用户接口与数据库链接。当与这些应用程序同时使用时, 用HANDLER接口观看数据更加天然 INSERT ... SELECT语法 INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [(col_name,...)] SELECT ... [ ON DUPLICATE KEY UPDATE col_name=expr, ... ] 使用INSERT...SELECT,您能够快速地从一个或多个表中向一个表中插入多个行。 示例: INSERT INTO tbl_temp2 (fld_id) SELECT tbl_temp1.fld_order_id FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100; 使用INSERT...SELECT语句时会出现如下状况: · 明确地指定IGNORE,用于忽略会致使重复关键字错误的记录。 · 不要同时使用DELAYED和INSERT...SELECT。 · INSERT语句的目标表会显示在查询的SELECT部分的FROM子句中。(在有些旧版本的MySQL中不会出 现这种状况。) · AUTO_INCREMENT列照常运行。 · 为了确保二进制日志能够被用于再次建立原表,MySQL不容许在INSERT...SELECT运行期间同时进行插 入操做。 · 目前,您不能在向一个表插入的同时,又在一个子查询中从同一个表中选择。 在ON DUPLICATE KEY UPDATE的值部分中,只要您不使用SELECT部分中的GROUP BY,您就能够引用在其它 表中的列。有一个反作用是,您必须使值部分中的非惟一列的名称符合要求。 您能够使用REPLACE替代INSERT,来覆盖旧行。对于包含惟一关键字值,并复制了旧行的新行,在进行处理 时,REPLACE能够做为INSERT IGNORE的同类子句:新行被用于替换旧行,而不是被丢弃 INSERT DELAYED语法 INSERT DELAYED ... 用于INSERT语句的DELAYED选项是MySQL相对于标准SQL的扩展。若是您的客户端不能等待INSERT完成,则 这个选项是很是有用的。当您使用MySQL进行日志编写时,这是很是常见的问题。您也能够按期运 行SELECT和UPDATE语句,这些语句花费的时间较长。 当一个客户端使用INSERT DELAYED时,会马上从服务器处获得一个肯定。而且行被排入队列,当表没有被其 它线程使用时,此行被插入。 使用INSERT DELAYED的另外一个重要的好处是,来自许多客户端的插入被集中在一块儿,并被编写入一个块。这 比执行许多独立的插入要快不少。 使用DELAYED时有一些限制: · INSERT DELAYED仅适用于MyISAM, MEMORY和ARCHIVE表。对于MyISAM表,若是在数据文件的中间 没有空闲的块,则支持同时采用SELECT和INSERT语句。在这些状况下,基本不须要对MyISAM使用INSERT DELAYED。请参见15.1节,“MyISAM存储引擎”, 15.4节,“MEMORY (HEAP)存储引擎”和15.8节,“ARCHIVE存 储引擎”。 · INSERT DELAYED应该仅用于指定值清单的INSERT语句。服务器忽略用于INSERT DELAYED...SELECT语句的DELAYED。 · 服务器忽略用于INSERT DELAYED...ON DUPLICATE UPDATE语句的DELAYED。 · 由于在行被插入前,语句马上返回,因此您不能使用LAST_INSERT_ID()来获 取AUTO_INCREMENT值。AUTO_INCREMENT值可能由语句生成。 · 对于SELECT语句,DELAYED行不可见,直到这些行确实被插入了为止。 · DELAYED在从属复制服务器中被忽略了,由于DELAYED不会在从属服务器中产生与主服务器不同的 数据。 注意,目前在队列中的各行只保存在存储器中,直到它们被插入到表中为止。这意味着,若是您强行停止 了mysqld(例如,使用kill -9)或者若是mysqld意外中止,则全部没有被写入磁盘的行都会丢失。 如下详细描述了当您对INSERT或REPLACE使用DELAYED选项时会发生什么状况。在这些描述中,“线程”指的 是已接受了一个INSERT DELAYED语句的线程,“管理程序”指的是为某个特定的表处理全部INSERT DELAYED语句的线程。 · 当一个线程对一个表执行DELAYED语句时,会建立出一个管理程序线程(若是原来不存在),对用于 本表的全部DELAYED语句进行处理。 · 线程会检查是否管理程序之前已获取了DELAYED锁定;若是没有获取,则告知管理程序线程进行此项 操做。即便其它线程对表有READ或WRITE锁定,也能够得到DELAYED锁定。可是管理程序会等待全部 的ALTER TABLE锁定或FLUSH TABLE锁定,以确保表的结构是最新的。 · 线程执行INSERT语句,但不是把行写入表中,而是把最终行的拷贝放入一个由管理程序线程管理的队 列中。线程会提示出现语法错误,这些错误会被报告到客户端中。 · 由于在插入操做以前,INSERT返回已经完成,因此客户端不能从服务器处获取重复记录的数目,也不 能获取生成的行的AUTO_INCREMENT值。(若是您使用C API,则出于一样的缘由,mysql_info()函数不会返 回任何有意义的东西。) · 当行被插入表中时,二进制日志被管理程序线程更新。在多行插入状况下,当第一行被插入时,二进制 日志被更新。 · 每次delayed_insert_limit行被编写时,管理程序会检查是否有SELECT语句仍然未执行。若是有,则会 在继续运行前,让这些语句先执行。 · 当管理程序的队列中没有多余的行时,表被解锁。若是在delayed_insert_timeout时间内,没有接收到 新的INSERT DELAYED语句,则管理程序停止。 · 若是在某个特定的管理程序队列中,有超过delayed_queue_size的行未被执行,则申请INSERT DELAYED的线程会等待,直到队列中出现空间为止。这么作能够确保mysqld不会把全部的存储器都用于被延 迟的存储队列。 · 管理程序线程会显示在MySQL进程清单中,其命令列中包含delayed_insert。若是您执行一个FLUSH TABLES语句或使用KILL thread_id进行删除,则会删除此线程。不过,在退出前,线程会首先把全部排入队列 的行存储到表中。在这期间,该线程不会从其它线程处接受任何新的INSERT语句。若是您在此以后执行一 个INSERT DELAYED语句,则会建立出一个新的管理程序线程。 注意,若是有一个INSERT DELAYED管理程序正在运行,则这意味着INSERT DELAYED语句比常规的INSERT语 句具备更高的优先权。其它更新语句必须等待,直到INSERT DELAYED语句队列都运行完毕,或者管理程序线 程被停止(使用KILL thread_id),或者执行了一个FLUSH TABLES时为止。 · 如下状态变量提供了有关INSERT DELAYED语句的信息: 状态变量意义 Delayed_insert_threads 管理程序线程的数目 Delayed_writes 使用INSERT DELAYED写入的行的数目 Not_flushed_delayed_rows 等待被写入的行的数目 · 您能够经过发送一个SHOW STATUS语句,或者执行一个mysqladmin extended-status命令,来阅 览这些变量。 注意,当没有使用表时,INSERT DELAYED比常规的INSERT要慢。对于服务器来讲,为每一个含有延迟行的表操 纵一个独立的线程,也是一个额外的系统开销。这意味着只有当您确认您须要时,才应使用INSERT DELAYED REPLACE语法 REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] VALUES ({expr | DEFAULT},...),(...),... 或: REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name SET col_name={expr | DEFAULT}, ... 或: REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] SELECT ... REPLACE的运行与INSERT很相像。只有一点除外,若是表中的一个旧记录与一个用于PRIMARY KEY或一 个UNIQUE索引的新记录具备相同的值,则在新记录被插入以前,旧记录被删除。请参见13.2.4节,“INSERT语 法”。 注意,除非表有一个PRIMARY KEY或UNIQUE索引,不然,使用一个REPLACE语句没有意义。该语句会 与INSERT相同,由于没有索引被用于肯定是否新行复制了其它的行。 全部列的值均取自在REPLACE语句中被指定的值。全部缺失的列被设置为各自的默认值,这和INSERT同样。 您不能从当前行中引用值,也不能在新行中使用值。若是您使用一个例如“SET col_name = col_name + 1”的 赋值,则对位于右侧的列名称的引用会被做为DEFAULT(col_name)处理。所以,该赋值至关于SET col_name = DEFAULT(col_name) + 1。 为了可以使用REPLACE,您必须同时拥有表的INSERT和DELETE权限。 REPLACE语句会返回一个数,来指示受影响的行的数目。该数是被删除和被插入的行数的和。若是对于一个单 行REPLACE该数为1,则一行被插入,同时没有行被删除。若是该数大于1,则在新行被插入前,有一个或多个 旧行被删除。若是表包含多个惟一索引,而且新行复制了在不一样的惟一索引中的不一样旧行的值,则有多是一 个单一行替换了多个旧行。 受影响的行数能够容易地肯定是否REPLACE只添加了一行,或者是否REPLACE也替换了其它行:检查该数是否 为1(添加)或更大(替换)。 若是您正在使用C API,则能够使用mysql_affected_rows()函数得到受影响的行数。 目前,您不能在一个子查询中,向一个表中更换,同时从同一个表中选择。 如下是所用算法的更详细的说明(该算法也用于LOAD DATA...REPLACE): 1. 尝试把新行插入到表中 2. 当由于对于主键或惟一关键字出现重复关键字错误而形成插入失败时: a. 从表中删除含有重复关键字值的冲突行 b. 再次尝试把新行插入到表中 在没有表被引用的状况下,容许您指定DUAL做为一个假的表名。 · mysql> SELECT 1 + 1 FROM DUAL; · -> 2 有些服务器要求一个FROM子句。DUAL仅用于与这些服务器兼容。若是没有表被引用,则MySQL不要求该子 句,前面的语句能够按如下方法编写: mysql> SELECT 1 + 1; -> 2 HAVING子句基本上是最后使用,只位于被发送给客户端的条目以前,没有进行优化。(LIMIT用 于HAVING以后。) SQL标准要求HAVING必须引用GROUP BY子句中的列或用于总计函数中的列。不过,MySQL支持对此工做性质 的扩展,并容许HAVING由于SELECT清单中的列和外部子查询中的列。 若是HAVING子句引用了一个意义不明确的列,则会出现警告。在下面的语句中,col2意义不明确,由于它既 做为别名使用,又做为列名使用: mysql> SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2; 标准SQL工做性质具备优先权,所以若是一个HAVING列名既被用于GROUP BY,又被用做输出列清单中的起了 别名的列,则优先权被给予GROUP BY列中的列。 · HAVING不能用于应被用于WHERE子句的条目。例如,不能编写以下语句: · mysql> SELECT col_name FROM tbl_name HAVING col_name > 0; 而应这么编写: mysql> SELECT col_name FROM tbl_name WHERE col_name > 0; · HAVING子句能够引用总计函数,而WHERE子句不能引用: · mysql> SELECT user, MAX(salary) FROM users · -> GROUP BY user HAVING MAX(salary)>10; (在有些较早版本的MySQL中,本语句不运行。) MySQL prepare语法: PREPARE statement_name FROM preparable_SQL_statement; /*定义*/ EXECUTE statement_name [USING @var_name [, @var_name] ...]; /*执行预处理语句*/ {DEALLOCATE | DROP} PREPARE statement_name /*删除定义*/ ; PREPARE语句用于预备一个语句,并指定名称statement_name,之后引用该语句。语句名称对大小写不敏感。preparable_stmt能够是一个文字字符串, 也能够是一个包含了语句文本的用户变量。 该文本必须表现为一个单一的SQL语句,而不是多个语句。在这语句里,‘?'字符能够被用于标识参数,当执行时,以指示数据值绑定到查询后。‘?'字符不该加引号, 即便你想要把它们与字符串值结合在一块儿。 参数标记只能用于数据值应该出现的地方,而不是SQL关键字,标识符,等等。 若是预语句已经存在,则在新的预语句被定义前,它会被隐含地删掉。 每次都看别人的,今天我本身写下来,之后就不用看别人的了 语法 PREPARE statement_name FROM sql_text /*定义*/ EXECUTE statement_name [USING variable [,variable...]] /*执行预处理语句*/ DEALLOCATE PREPARE statement_name /*删除定义*/ 为了与PostgreSQL兼容,MySQL也支持LIMIT row_count OFFSET offset语法。 若是要恢复从某个偏移量到结果集合的末端之间的全部的行,您能够对第二个参数是使用比较大的数。本语句 能够恢复从第96行到最后的全部行: mysql> SELECT * FROM tbl LIMIT 95,18446744073709551615; 使用1个自变量时,该值指定从结果集合的开头返回的行数: mysql> SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows 换句话说,LIMIT n与LIMIT 0,n等价。 对于已预备的语句,您能够使用位置保持符。如下语句将从tb1表中返回一行: mysql> SET @a=1; mysql> PREPARE STMT FROM "SELECT * FROM tbl LIMIT ?"; mysql> EXECUTE STMT USING @a; 如下语句将从tb1表中返回第二到第六行: mysql> SET @skip=1; SET @numrows=5; mysql> PREPARE STMT FROM "SELECT * FROM tbl LIMIT ?, ?"; mysql> EXECUTE STMT USING @skip, @numrows; 在SELECT关键词的后面,您能够使用许多选项。这些选项能够影响语句的运行。 ALL, DISTINCT和DISTINCTROW选项指定是否重复行应被返回。若是这些选项没有被给定,则默认值 为ALL(全部的匹配行被返回)。DISTINCT和DISTINCTROW是同义词,用于指定结果集合中的重复行应被删 除。 HIGH_PRIORITY, STRAIGHT_JOIN和以SQL_为开头的选项是MySQL相对于标准SQL的扩展。 · HIGH_PRIORITY给予SELECT更高的优先权,高于用于更新表的语句。您应该只对查询使 用HIGH_PRIORITY。查询速度很是快,并且马上被执行。SELECT HIGH_PRIORITY查询在表被锁定用于读取 时被发出。即便有一个新的语句正在等待表变为空闲,查询也会运行。 HIGH_PRIORITY不能和SELECT语句同时使用。SELECT语句是UNION的一部分。 · STRAIGHT_JOIN用于促使优化符把表联合在一块儿,顺序按照这些表在FROM子句中排列的顺序。若是优 化符联合表时顺序不佳,您能够使用STRAIGHT_JOIN来加快查询的速度。请参见7.2.1节,“EXPLAIN语法(获 取关于SELECT的信息)”。STRAIGHT_JOIN也能够被用于table_references清单中。请参 见13.2.7.1节,“JOIN语法”。 · SQL_BIG_RESULT能够与GROUP BY或DISTINCT同时使用,来告知优化符结果集合有不少行。在这种 状况下,MySQL直接使用以磁盘为基础的临时表(若是须要的话)。在这种状况下,MySQL还会优先进行分 类,不优先使用临时表。临时表对于GROUP BY组分带有关键字。 · SQL_BUFFER_RESULT促使结果被放入一个临时表中。这能够帮助MySQL提早解开表锁定,在须要花费 较长时间的状况下,也能够帮助把结果集合发送到客户端中。 · SQL_SMALL_RESULT能够与GROUP BY或DISTINCT同时使用,来告知优化符结果集合是较小的。在此 状况下,MySAL使用快速临时表来储存生成的表,而不是使用分类。在MySQL 5.1中,一般不须要这样。 · SQL_CALC_FOUND_ROWS告知MySQL计算有多少行应位于结果集合中,不考虑任何LIMIT子句。行的 数目能够使用SELECT FOUND_ROWS()恢复。请参见12.9.3节,“信息函数”。 · 若是您正在使用一个query_cache_type值,值为2或DEMAND,则SQL_CACHE告知MySQL把查询结果存 储在查询缓存中。对于使用UNION的查询或子查询,本选项会影响查询中的全部SELECT。请参 见5.13节,“MySQL查询高速缓冲”。 · SQL_NO_CACHE告知MySQL不要把查询结果存储在查询缓存中。请参见5.13节,“MySQL查询高速缓 冲”。对于一个使用UNION或子查询的查询,本选项会影响查询中的SELECT JOIN语法 MySQL支持如下JOIN语法。这些语法用于SELECT语句的table_references部分和多表DELETE和UPDATE语句: table_references: table_reference [, table_reference] … table_reference: table_factor | join_table table_factor: tbl_name [[AS] alias] [{USE|IGNORE|FORCE} INDEX (key_list)] | ( table_references ) | { OJ table_reference LEFT OUTER JOIN table_reference ON conditional_expr } join_table: table_reference [INNER | CROSS] JOIN table_factor [join_condition] | table_reference STRAIGHT_JOIN table_factor | table_reference STRAIGHT_JOIN table_factor ON condition | table_reference LEFT [OUTER] JOIN table_reference join_condition | table_reference NATURAL [LEFT [OUTER]] JOIN table_factor | table_reference RIGHT [OUTER] JOIN table_reference join_condition | table_reference NATURAL [RIGHT [OUTER]] JOIN table_factor join_condition: ON conditional_expr | USING (column_list) 一个表引用还被称为一个联合表达式。 与SQL标准相比,table_factor的语法被扩展了。SQL标准只接受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中,CROSS JOIN从语法上说与INNER JOIN等同(二者能够互相替换。在标准SQL中,二者是不等同 的。INNER JOIN与ON子句同时使用,CROSS JOIN以其它方式使用。 一般,在只含有内部联合运行的联合表达式中,圆括号能够被忽略。MySQL也支持嵌套的联合 (见7.2.10节,“MySQL如何优化嵌套Join”)。 一般,您不该对ON部分有任何条件。ON部分用于限定在结果集合中您想要哪些行。可是,您应在WHERE子句 中指定这些条件。这条规则有一些例外。 在前面的清单中显示的{ OJ ... LEFT OUTER JOIN ...}语法的目的只是为了保持与ODBC的兼容性。语法中的花 括号应按字面书写;该括号不是中间语法。中间语法用于语法描述的其它地方。 · 表引用能够使用tbl_name AS alias_name或tbl_name alias_name指定别名: · mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 · -> WHERE t1.name = t2.name; · mysql> SELECT t1.name, t2.salary FROM employee t1, info t2 · -> WHERE t1.name = t2.name; · ON条件句是能够被用于WHERE子句的格式的任何条件表达式。 · 若是对于在LEFT JOIN中的ON或USING部分中的右表没有匹配的记录,则全部列被设置为NULL的一个 行被用于右表。若是一个表在其它表中没有对应部分,您能够使用这种方法在这种表中查找记录: · mysql> SELECT table1.* FROM table1 · -> LEFT JOIN table2 ON table1.id=table2.id · -> WHERE table2.id IS NULL; 本例查找在table1中含有一个id值的全部行。同时,在table2中没有此id值(即,table1中的全部行在table2中 没有对应的行)。本例假设table2.id被定义为NOT NULL。请参见7.2.9节,“MySQL如何优化LEFT JOIN和RIGHT JOIN”。 · USING(column_list)子句用于为一系列的列进行命名。这些列必须同时在两个表中存在。若是表a和 表b都包含列c1, c2和c3,则如下联合会对比来自两个表的对应的列: · a LEFT JOIN b USING (c1,c2,c3) · 两个表的NATURAL [LEFT] JOIN被定义为与INNER JOIN语义相同,或与使用USING子句的LEFT JOIN语 义相同。USING子句用于为同时存在于两个表中的全部列进行命名。 · INNER JOIN和,(逗号)在无联合条件下是语义相同的:二者均可以对指定的表计算出笛卡儿乘积 (也就是说,第一个表中的每一行被联合到第二个表中的每一行)。 · RIGHT JOIN的做用与LEFT JOIN的做用相似。要使代码能够在数据库内移植,建议您使用LEFT JOIN代 替RIGHT JOIN。 · STRAIGHT_JOIN与JOIN相同。除了有一点不同,左表会在右表以前被读取。STRAIGH_JOIN能够被 用于这样的状况,即联合优化符以错误的顺序排列表。 您能够提供提示,当从一个表中恢复信息时,MySQL应使用哪一个索引。经过指定USE INDEX(key_list),您 能够告知MySQL只使用一个索引来查找表中的行。另外一种语法IGNORE INDEX(key_list)能够被用于告 知MySQL不要使用某些特定的索引。若是EXPLAIN显示MySQL正在使用来自索引清单中的错误索引时,这些提 示会有用处。 您也能够使用FORCE INDEX,其做用接近USE INDEX(key_list),不过增长了一项做用,一次表扫描被假设 为代价很高。换句话说,只有当没法使用一个给定的索引来查找表中的行时,才使用表扫描。 USE KEY、IGNORE KEY和FORCE KEY是USE INDEX、IGNORE INDEX和FORCE INDEX的同义词。 注释:当MySQL决定如何在表中查找行并决定如何进行联合时,使用USE INDEX、IGNORE INDEX和FORCE INDEX只会影响使用哪些索引。当分解一个ORDER BY或GROUP BY时,这些语句不会影响某个索引是否被使 用。 部分的联合示例: mysql> SELECT * FROM table1,table2 WHERE table1.id=table2.id; mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id; mysql> SELECT * FROM table1 LEFT JOIN table2 USING (id); mysql> SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id -> LEFT JOIN table3 ON table2.id=table3.id; mysql> SELECT * FROM table1 USE INDEX (key1,key2) -> WHERE key1=1 AND key2=2 AND key3=3; mysql> SELECT * FROM table1 IGNORE INDEX (key3) -> WHERE key1=1 AND key2=2 AND key3=3; 见7.2.9节,“MySQL如何优化LEFT JOIN和RIGHT JOIN”。 注释:天然联合和使用USING的联合,包括外部联合变量,依据SQL:2003标准被处理。这些变动时MySQL与标 准SQL更加相符。不过,对于有些联合,这些变动会致使不一样的输出列。另外,有些查询在旧版本(5.0.12以 前)工做正常,但也必须从新编写,以符合此标准。对于有关当前联合处理和旧版本中的联合处理的效果的对 比,如下列表提供了更详细的信息。 · NATURAL联合或USING联合的列会与旧版本不一样。特别是,再也不出现冗余的输出列,用于SELECT *扩 展的列的顺序会与之前不一样。 示例: CREATE TABLE t1 (i INT, j INT); CREATE TABLE t2 (k INT, j INT); INSERT INTO t1 VALUES(1,1); INSERT INTO t2 VALUES(1,1); SELECT * FROM t1 NATURAL JOIN t2; SELECT * FROM t1 JOIN t2 USING (j); 对于旧版本,语句会产生如下输出: +------+------+------+------+ | i | j | k | j | +------+------+------+------+ | 1 | 1 | 1 | 1 | +------+------+------+------+ +------+------+------+------+ | i | j | k | j | +------+------+------+------+ | 1 | 1 | 1 | 1 | +------+------+------+------+ 在第一个SELECT语句中,列i同时出如今两个表中,为一个联合列,因此,依据标准SQL,该列在输出中只出 现一次。与此相似,在第二个SELECT语句中,列j在USING子句中被命名,应在输出中只出现一次。可是,在 两种状况下,冗余的列均没被消除。另外,依据标准SQL,列的顺序不正确。 如今,语句产生以下输出: +------+------+------+ | j | i | k | +------+------+------+ | 1 | 1 | 1 | +------+------+------+ +------+------+------+ | j | i | k | +------+------+------+ | 1 | 1 | 1 | +------+------+------+ 冗余的列被消除,而且依据标准SQL,列的顺序是正确的: o 第一,两表共有的列,按在第一个表中的顺序排列 o 第二,第一个表中特有的列,按该表中的顺序排列 o 第三,第二个表中特有的列,按该表中的顺序排列 · 对多方式天然联合的估算会不一样。方式要求从新编写查询。假设您有三个表t1(a,b), t2(c,b)和t3(a,c), 每一个表有一行:t1(1,2), t2(10,2)和t3(7,10)。同时,假设这三个表具备NATURAL JOIN: · SELECT … FROM t1 NATURAL JOIN t2 NATURAL JOIN t3; 在旧版本中,第二个联合的左操做数被认为是t2,然而它应该为嵌套联合(t1 NATURAL JOIN t2)。结果, 对t3的列进行检查时,只检查其在t2中的共有列。若是t3与t1有共有列,这些列不被用做equi-join列。所以, 在旧版本的MySQL中,前面的查询被转换为下面的equi-join: SELECT … FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c; 此联合又省略了一个equi-join谓语(t1.a = t3.a)。结果是,该联合产生一个行,而不是空结果。正确的等价 查询以下: SELECT … FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c AND t1.a = t3.a; 若是您要求在当前版本的MySQL中得到和旧版本中相同的查询结果,应把天然联合改写为第一个equi-join。 · 在旧版本中,逗号操做符(,)和JOIN均有相同的优先权,因此联合表达式t1, t2 JOIN t3被理解 ((t1, t2) JOIN t3) JOIN (t1, (t2 JOIN t3)) 为。如今, 有更高的优先权,因此表达式被理解为。这个变动会影响 使用ON子句的语句,由于该子句只参阅联合操做数中的列。优先权的变动改变了对什么是操做数的理解。 示例: 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); 在旧版本中,SELECT是合法的,由于t1, t2被隐含地归为(t1,t2)。如今,JOIN取得了优先权,所以用于ON子句 的操做数是t2和t3。由于t1.i1不是任何一个操做数中的列,因此结果是出如今'on clause'中有未知列't1.i1'的错 误。要使联合能够被处理,用使用圆括号把前两个代表确地归为一组,这样用于ON子句的操做数 为(t1,t2)和t3: SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3); 本变动也适用于INNER JOIN,CROSS JOIN,LEFT JOIN和RIGHT JOIN。 · 在旧版本中,ON子句能够参阅在其右边命名的表中的列。如今,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; 在旧版本中,SELECT语句是合法的。如今该语句会运行失败,出如今'on clause'中未知列'i3'的错误。这是因 为i3是t3中的一个表,而t3不是ON子句中的操做数。本语句应进行以下改写: SELECT * FROM t1 JOIN t2 JOIN t3 ON (i1 = i3); · 在旧版本中,一个USING子句能够被改写为一个ON子句。ON子句对比了相应的列。例如,如下两个子 句具备相同的语义: · 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 如今,这两个子句再也不是同样的: o 在决定哪些行知足联合条件时,两个联合保持语义相同。 o 在决定哪些列显示SELECT *扩展时,两个联合的语义不相同。USING联合选择对应列中的合并值, 而ON联合选择全部表中的全部列。对于前面的USING联合,SELECT *选择这些值: o COALESCE(a.c1,b.c1), COALESCE(a.c2,b.c2), COALESCE(a.c3,b.c3) 对于ON联合,SELECT *选择这些值: a.c1, a.c2, a.c3, b.c1, b.c2, b.c3 使用内部联合时,COALESCE(a.c1,b.c1)与a.c1或b.c1相同,由于两列将具备相同的值。使用外部联合时(比 如LEFT JOIN),两列中有一列能够为NULL。该列将会从结果中被忽略 UNION语法 SELECT ... UNION [ALL | DISTINCT] SELECT ... [UNION [ALL | DISTINCT] SELECT ...] UNION用于把来自许多SELECT语句的结果组合到一个结果集合中。 列于每一个SELECT语句的对应位置的被选择的列应具备相同的类型。(例如,被第一个语句选择的第一列应和 被其它语句选择的第一列具备相同的类型。)在第一个SELECT语句中被使用的列名称也被用于结果的列名 称。 SELECT语句为常规的选择语句,可是受到以下的限定: · 只有最后一个SELECT语句能够使用INTO OUTFILE。 · HIGH_PRIORITY不能与做为UNION一部分的SELECT语句同时使用。若是您对第一个SELECT指定 了HIGH_PRIORITY,则不会起做用。若是您对其它后续的SELECT语句指定了HIGH_PRIORITY,则会产生语法 错误。 若是您对UNION不使用关键词ALL,则全部返回的行都是惟一的,如同您已经对整个结果集合使用 了DISTINCT。若是您指定了ALL,您会从全部用过的SELECT语句中获得全部匹配的行。 DISTINCT关键词是一个自选词,不起任何做用,可是根据SQL标准的要求,在语法中容许采用。 (在MySQL中,DISTINCT表明一个共用体的默认工做性质。) 您能够在同一查询中混合UNION ALL和UNION DISTINCT。被混合的UNION类型按照这样的方式对待, 即DISTICT共用体覆盖位于其左边的全部ALL共用体。DISTINCT共用体能够使用UNION DISTINCT明确地生 成,或使用UNION(后面不加DISTINCT或ALL关键词)隐含地生成。 若是您想使用ORDER BY或LIMIT子句来对所有UNION结果进行分类或限制,则应对单个地SELECT语句加圆括 号,并把ORDER BY或LIMIT放到最后一个的后面。如下例子同时使用了这两个子句: (SELECT a FROM tbl_name WHERE a=10 AND B=1) UNION (SELECT a FROM tbl_name WHERE a=11 AND B=2) ORDER BY a LIMIT 10; 这种ORDER BY不能使用包括表名称(也就是,采用tbl_name.col_name格式的名称)列引用。能够在第一 个SELECT语句中提供一个列别名,并在ORDER BY中参阅别名,或使用列位置在ORDER BY中参阅列。(首选 采用别名,由于不建议使用列位置。) 另外,若是带分类的一列有别名,则ORDER BY子句必须引用别名,而不能引用列名称。如下语句中的第一个 语句必须运行,可是第二个会运行失败,出如今'order clause'中有未知列'a'的错误: (SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY b; (SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY a; To apply ORDER BY or LIMIT to an individual SELECT, place the clause inside the parentheses that enclose the SELECT: 为了对单个SELECT使用ORDER BY或LIMIT,应把子句放入圆括号中。圆括号包含了SELECT: (SELECT a FROM tbl_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION (SELECT a FROM tbl_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10); 圆括号中用于单个SELECT语句的ORDER BY只有当与LIMIT结合后,才起做用。不然,ORDER BY被优化去 除。 UNION结果集合中的列的类型和长度考虑了被全部SELECT语句恢复的数值。例如,考虑以下语句: mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10); +---------------+ | REPEAT('a',1) | +---------------+ | a | | bbbbbbbbbb | +---------------+ (在部分早期版本的MySQL中,第二行已被删节到长度为1。) 使用ANY, IN和SOME进行子查询 语法: operand comparison_operator ANY (subquery) operand IN (subquery) operand comparison_operator SOME (subquery) ANY关键词必须后面接一个比较操做符。ANY关键词的意思是“对于在子查询返回的列中的任一数值,若是比较 结果为TRUE的话,则返回TRUE”。例如: SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2); 假设表t1中有一行包含(10)。若是表t2包含(21,14,7),则表达式为TRUE,由于t2中有一个值为7,该 值小于10。若是表t2包含(20,10),或者若是表t2为空表,则表达式为FALSE。若是表t2包含(NULL, NULL, NULL),则表达式为UNKNOWN。 词语IN是=ANY的别名。所以,这两个语句是同样的: SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 IN (SELECT s1 FROM t2); 不过,NOT IN不是<> ANY的别名,可是是<> ALL的别名。请参见13.2.8.4节,“使用ALL进行子查询”。 词语SOME是ANY的别名。所以,这两个语句是同样的: SELECT s1 FROM t1 WHERE s1 <> ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2); 使用词语SOME的机会不多,可是本例显示了为何SOME是有用的。对于多数人来讲,英语短语“a is not equal to any b”的意思是“没有一个b与a相等”,可是在SQL语法中不是这个意思。该语法的意思是“有部 分b与a不相等”。使用<> SOME有助于确认每一个人都理解该查询的真正含义。 13.2.8.4. 使用ALL进行子查询 语法: operand comparison_operator ALL (subquery) 词语ALL必须接在一个比较操做符的后面。ALL的意思是“对于子查询返回的列中的全部值,若是比较结果 为TRUE,则返回TRUE。”例如: SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2); 假设表1中有一行包含(10)。若是表t2包含(-5,0,+5),则表达式为TRUE,由于10比t2中的全部三个值 都大。若是表t2包含(12,6,NULL,-100),则表达式为FALSE,由于表t2中有一个值12大于10。若是 表t2包含(0,NULL,1),则表达式为unknown。 最后,若是表t2为空表,则结果为TRUE。所以,当表t2为空表时,如下语句为TRUE: SELECT * FROM t1 WHERE 1 > ALL (SELECT s1 FROM t2); 可是,当表t2为空表时,本语句为NULL: SELECT * FROM t1 WHERE 1 > (SELECT s1 FROM t2); 另外,当表t2为空表时,如下语句为NULL: 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); EXISTS和NOT EXISTS 若是一个子查询返回任何的行,则EXISTS subquery为FALSE。例如: SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2); 过去,EXISTS子查询以SELECT *为开始,可是能够以SELECT 5或SELECT column1或其它的为开始。MySQL在 这类子查询中忽略了SELECT清单,所以没有区别。 对于前面的例子,若是t2包含任何行,即便是只含有NULL值的行,EXISTS条件也为TRUE。这其实是一个不 可能的例子,由于基本上全部的[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子句,该子句又包含在一 个NOT EXISTS子句中。该查询正式地回答了这个问题,“是否有某个城市拥有没有列在Stores中的商店?”。可 以比较容易的说,一个带嵌套的NOT EXISTS能够回答这样的问题,“是否对于全部的y,x都为TRUE?” TRUNCATE语法 TRUNCATE [TABLE] tbl_name TRUNCATE TABLE用于彻底清空一个表。从逻辑上说,该语句与用于删除全部行的DELETE语句等同,可是在 有些状况下,二者在使用上有所不一样。 对于InnoDB表,若是有须要引用表的外键限制,则TRUNCATE TABLE被映射到DELETE上;不然使用快速删减 (取消和从新建立表)。使用TRUNCATE TABLE从新设置AUTO_INCREMENT计数器,设置时不考虑是否有外 键限制。 对于其它存储引擎,在MySQL 5.1中,TRUNCATE TABLE与DELETE FROM有如下几处不一样: · 删减操做会取消并从新建立表,这比一行一行的删除行要快不少。 · 删减操做不能保证对事务是安全的;在进行事务处理和表锁定的过程当中尝试进行删减,会发生错误。 · 被删除的行的数目没有被返回。 · 只要表定义文件tbl_name.frm是合法的,则能够使用TRUNCATE TABLE把表从新建立为一个空表,即便 数据或索引文件已经被破坏。 · 表管理程序不记得最后被使用的AUTO_INCREMENT值,可是会从头开始计数。即便对 于MyISAM和InnoDB也是如此。MyISAM和InnoDB一般再也不次使用序列值。 · 当被用于带分区的表时,TRUNCATE TABLE会保留分区;即,数据和索引文件被取消并从新建立,同时 分区定义(.par)文件不受影响。 TRUNCATE TABLE是在MySQL中采用的一个Oracle SQL扩展 MySQL实用工具语句 13.3.1. DESCRIBE语法(获取有关列的信息) 13.3.2. USE语法 13.3.1. DESCRIBE语法(获取有关列的信息) {DESCRIBE | DESC} tbl_name [col_name | wild] DESCRIBE能够提供有关表中各列的信息。它是SHOW COLUMNS FROM的快捷方式。这些语句也能够显示语 句,用于阅览。 见13.5.4.3节,“SHOW COLUMNS语法”。 col_name能够是一个列名称,或一个包含‘%’和‘_’的通配符的字符串,用于得到对于带有与字符串相匹配的名 称的各列的输出。没有必要在引号中包含字符串,除非其中包含空格或其它特殊字符。 mysql> DESCRIBE city; +------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+----------+------+-----+---------+----------------+ | Id | int(11) | NO | PRI | NULL | auto_increment | | Name | char(35) | NO | | | | | Country | char(3) | NO | UNI | | | | District | char(20) | YES | MUL | | | | Population | int(11) | NO | | 0 | | +------------+----------+------+-----+---------+----------------+ 5 rows in set (0.00 sec) NULL字段指示是否NULL能够被存储在列中。 Key字段指示是否该列已编制索引。PRI的值指示该列是表的主键的一部分。UNI指示,该列是UNIQUE索引的 一部分。MUL值指示,在列中某个给定值屡次出现是容许的。 MUL将被显示在UNIQUE索引中,缘由之一是多个列会组合成一个复合UNIQUE索引;尽管列的组合是惟一的, 但每一个列仍能够屡次出现同一个给定值。注意,在复合索引中,只有索引最左边的列能够进入Key字段中。 默认字段指示,默认值被赋予该列。 Extra字段包含能够获取的与给定列有关的附加信息。在咱们的例子中,Extra字段指示,Id列使 用AUTO_INCREMENT关键词建立。 若是列类型与您预计的依据CREATE TABLE语句得出的列类型不一样,则请注意,MySQL有时会改变列类型。请 参见13.1.5.1节,“沉寂的列规格变动”。 DESCRIBE语句被设立出来,用于与Oracle相兼容。 SHOW CREATE TABLE和SHOW TABLE STATUS语句也能够提供有关表的信息。请参见13.5.4节,“SHOW语 法”。 13.3.2. USE语法 USE db_name USE db_name语句能够通告MySQL把db_name数据库做为默认(当前)数据库使用,用于后续语句。该数据 库保持为默认数据库,直到语段的结尾,或者直到发布一个不一样的USE语句: mysql> USE db1; mysql> SELECT COUNT(*) FROM mytable; # selects from db1.mytable mysql> USE db2; mysql> SELECT COUNT(*) FROM mytable; # selects from db2.mytable 使用USE语句为一个特定的当前的数据库作标记,不会阻碍您访问其它数据库中的表。下面的例子能够 从db1数据库访问做者表,并从db2数据库访问编辑表: mysql> USE db1; mysql> SELECT author_name,editor_name FROM author,db2.editor -> WHERE author.editor_id = db2.editor.editor_id; USE语句被设立出来,用于与Sybase相兼容 MySQL事务处理和锁定语句 13.4.1. START TRANSACTION, COMMIT和ROLLBACK语法 13.4.2. 不能回滚的语句 13.4.3. 会形成隐式提交的语句 13.4.4. SAVEPOINT和ROLLBACK TO SAVEPOINT语法 13.4.5. LOCK TABLES和UNLOCK TABLES语法 13.4.6. SET TRANSACTION语法 13.4.7. XA事务 MySQL经过SET AUTOCOMMIT, START TRANSACTION, COMMIT和ROLLBACK等语句支持本地事务(在给定的 客户端链接中)。请参见13.4.1节,“START TRANSACTION, COMMIT和ROLLBACK语法”。XA事务支持还能够 容许MySQL参与分布式事务。请参见13.4.7节,“XA事务”。 13.4.1. START TRANSACTION, COMMIT和ROLLBACK语法 START TRANSACTION | BEGIN [WORK] COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE] ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE] SET AUTOCOMMIT = {0 | 1} START TRANSACTION或BEGIN语句能够开始一项新的事务。COMMIT能够提交当前事务,是变动成为永久变 更。ROLLBACK能够回滚当前事务,取消其变动。SET AUTOCOMMIT语句能够禁用或启用默认 的autocommit模式,用于当前链接。 自选的WORK关键词被支持,用于COMMIT和RELEASE,与CHAIN和RELEASE子句。CHAIN和RELEASE能够被 用于对事务完成进行附加控制。Completion_type系统变量的值决定了默认完成的性质。请参见5.3.3节,“服务 器系统变量”。 AND CHAIN子句会在当前事务结束时,马上启动一个新事务,而且新事务与刚结束的事务有相同的隔离等 级。RELEASE子句在终止了当前事务后,会让服务器断开与当前客户端的链接。包含NO关键词能够抑 制CHAIN或RELEASE完成。若是completion_type系统变量被设置为必定的值,使连锁或释放完成能够默认进 行,此时NO关键词有用。 默认状况下,MySQL采用autocommit模式运行。这意味着,当您执行一个用于更新(修改)表的语句之 后,MySQL马上把更新存储到磁盘中。 若是您正在使用一个事务安全型的存储引擎(如InnoDB, BDB或NDB簇),则您能够使用如下语句禁 用autocommit模式: SET AUTOCOMMIT=0; 经过把AUTOCOMMIT变量设置为零,禁用autocommit模式以后,您必须使用COMMIT把变动存储到磁盘中, 或着若是您想要忽略从事务开始进行以来作出的变动,使用ROLLBACK。 若是您想要对于一个单一系列的语句禁用autocommit模式,则您能够使用START TRANSACTION语句: START TRANSACTION; SELECT @A:=SUM(salary) FROM table1 WHERE type=1; UPDATE table2 SET summary=@A WHERE type=1; COMMIT; 使用START TRANSACTION,autocommit仍然被禁用,直到您使用COMMIT或ROLLBACK结束事务为止。然 后autocommit模式恢复到原来的状态。 BEGIN和BEGIN WORK被做为START TRANSACTION的别名受到支持,用于对事务进行初始化。START TRANSACTION是标准的SQL语法,而且是启动一个ad-hoc事务的推荐方法。BEGIN语句与BEGIN关键词的使用 不一样。BEGIN关键词能够启动一个BEGIN...END复合语句。后者不会开始一项事务。请参见20.2.7节,“BEGIN ... END复合语句”。 您也能够按照以下方法开始一项事务: START TRANSACTION WITH CONSISTENT SNAPSHOT; WITH CONSISTENT SNAPSHOT子句用于启动一个一致的读取,用于具备此类功能的存储引擎。目前,该子句 只适用于InnoDB。该子句的效果与发布一个START TRANSACTION,后面跟一个来自任何InnoDB表 的SELECT的效果同样。请参见15.2.10.4节,“一致的非锁定读”。 开始一项事务会形成一个隐含的UNLOCK TABLES被执行。 为了得到最好的结果,事务应只使用由单一事务存储引擎管理的表执行。不然,会出现如下问题: · 若是您使用的表来自多个事务安全型存储引擎(例如InnoDB和BDB),而且事务隔离等级不 是SERIALIZABLE,则有可能当一个事务提交时,其它正在进行中的、使用一样的表的事务将只会发生由第一 个事务产生的变动。也就是,用混合引擎不能保证事务的原子性,并会形成不一致。(若是混合引擎事务不经 常有,则您能够根据须要使用SET TRANSACTION ISOLATION LEVEL把隔离等级设置到SERIALIZABLE。) · 若是您在事务中使用非事务安全型表,则对这些表的任何变动被马上存储,不论autocommit模式的状 态如何。 若是您在更新了事务中一个事务表以后,发布一个ROLLBACK语句,则会出现一 个ER_WARNING_NOT_COMPLETE_ROLLBACK警告。对事务安全型表的变动被回滚,可是对非事务安全型表 没有变动。 每一个事务被存储在一个组块中的二进制日志中,在COMMIT之上。被回滚的事务不被计入日志。(例外状况: 对非事务表的更改不会被回滚。若是一个被回滚的事务包括对非事务表的更改,则整个事务使用一个在末端 的ROLLBACK语句计入日志,以确保对这些表的更改进行复制。)见5.11.3节,“二进制日志”。 您能够使用SET TRANSACTION ISOLATION LEVEL更改事务的隔离等级。请参见13.4.6节,“SET TRANSACTION语法”。 回滚能够慢速运行。在用户没有明确要求时,也能够进行回滚(例如,当错误发生时)。所以,在明确地和隐 含的(ROLLBACK SQL命令)回滚时,SHOW PROCESSLIST会在Stage列中显示Rolling back,用于链接。 13.4.2. 不能回滚的语句 有些语句不能被回滚。一般,这些语句包括数据定义语言(DDL)语句,好比建立或取消数据库的语句,和创 建、取消或更改表或存储的子程序的语句。 您在设计事务时,不该包含这类语句。若是您在事务的前部中发布了一个不能被回滚的语句,则后部的其它语 句会发生错误,在这些状况下,经过发布ROLLBACK语句不能回滚事务的所有效果。 13.4.3. 会形成隐式提交的语句 如下语句(以及同义词)均隐含地结束一个事务,彷佛是在执行本语句前,您已经进行了一个COMMIT。 · ALTER FUNCTION, ALTER PROCEDURE, ALTER TABLE, BEGIN, CREATE DATABASE, CREATE FUNCTION, CREATE INDEX, CREATE PROCEDURE, CREATE TABLE, DROP DATABASE, DROP FUNCTION, DROP INDEX, DROP PROCEDURE, DROP TABLE, LOAD MASTER DATA, LOCK TABLES, RENAME TABLE, SET AUTOCOMMIT=1, START TRANSACTION, TRUNCATE TABLE, UNLOCK TABLES. · 当当前全部的表均被锁定时,UNLOCK TABLES能够提交事务。 · CREATE TABLE, CREATE DATABASE DROP DATABASE, TRUNCATE TABLE, ALTER FUNCTION, ALTER PROCEDURE, CREATE FUNCTION, CREATE PROCEDURE, DROP FUNCTION和DROP PROCEDURE等语句会导 致一个隐含提交。 · InnoDB中的CREATE TABLE语句被做为一个单一事务进行处理。这意味着,来自用户的ROLLBACK不会 撤销用户在事务处理过程当中建立的CREATE TABLE语句。 事务不能被嵌套。这是隐含COMMIT的结果。当您发布一个START TRANSACTION语句或其同义词时, 该COMMIT被执行,用于任何当前事务。 13.4.4. SAVEPOINT和ROLLBACK TO SAVEPOINT语法 SAVEPOINT identifier ROLLBACK [WORK] TO SAVEPOINT identifier RELEASE SAVEPOINT identifier InnoDB支持SQL语句SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT和自选的用 于ROLLBACK的WORK关键词。 SAVEPOINT语句用于设置一个事务保存点,带一个标识符名称。若是当前事务有一个一样名称的保存点,则旧 的保存点被删除,新的保存点被设置。 ROLLBACK TO SAVEPOINT语句会向以命名的保存点回滚一个事务。若是在保存点被设置后,当前事务对行进 行了更改,则这些更改会在回滚中被撤销。可是,InnoDB不会释放被存储在保存点以后的存储器中的行锁 定。(注意,对于新插入的行,锁定信息被存储在行中的事务ID承载;锁定没有被分开存储在存储器中。在这 种状况下,行锁定在撤销中被释放。)在被命名的保存点以后设置的保存点被删除。 若是语句返回如下错误,则意味着不存在带有指定名称的保存点: ERROR 1181: Got error 153 during ROLLBACK RELEASE SAVEPOINT语句会从当前事务的一组保存点中删除已命名的保存点。不出现提交或回滚。若是保存 点不存在,会出现错误。 若是您执行COMMIT或执行不能命名保存点的ROLLBACK,则当前事务的全部保存点被删除。 13.4.5. LOCK TABLES和UNLOCK TABLES语法 LOCK TABLES tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE} [, tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}] ... UNLOCK TABLES LOCK TABLES能够锁定用于当前线程的表。若是表被其它线程锁定,则形成堵塞,直到能够获取全部锁定为 止。UNLOCK TABLES能够释放被当前线程保持的任何锁定。当线程发布另外一个LOCK TABLES时,或当与服务 器的链接被关闭时,全部由当前线程锁定的表被隐含地解锁。 表锁定只用于防止其它客户端进行不正当地读取和写入。保持锁定(即便是读取锁定)的客户端能够进行表 层级的操做,好比DROP TABLE。 注意,下面是对事务表使用LOCK TABLES的说明: · 在尝试锁定表以前,LOCK TABLES不是事务安全型的,会隐含地提交全部活性事务。同时,开始一项 事务(例如,使用START TRANSACTION),会隐含地执行UNLOCK TABLES。(见13.4.3节,“会形成隐式提 交的语句”。 · 对事务表(如InnoDB)使用LOCK TABLES的正确方法是,设置AUTOCOMMIT=0而且不能调用UNLOCK TABLES,直到您明确地提交事务为止。当您调用LOCK TABLES时,InnoDB会内部地取其本身的表锁 定,MySQL取其本身的表锁定。InnoDB在下一个提交时释放其表锁定,可是,对于MySQL,要释放表锁定, 您必须调用UNLOCK TABLES。您不该该让AUTOCOMMIT=1,由于那样的话,InnoDB会在调用LOCK TABLES以后马上释放表锁定,而且很容易造成死锁定。注意,若是AUTOCOMMIT=1,咱们根本不能获 取InnoDB表锁定,这样就能够帮助旧的应用软件避免没必要要的死锁定。 · ROLLBACK不会释放MySQL的非事务表锁定。 要使用LOCK TABLES,您必须拥有相关表的LOCK TABLES权限和SELECT权限。 使用LOCK TABLES的主要缘由是仿效事务,或在更新表时加快速度。这将在后面进行更详细的解释。 若是一个线程得到对一个表地READ锁定,该线程(和全部其它线程)只能从该表中读取。若是一个线程得到 对一个表的WRITE锁定,只有保持锁定的线程能够对表进行写入。其它的线程被阻止,直到锁定被释放时为 止。 READ LOCAL和READ之间的区别是,READ LOCAL容许在锁定被保持时,执行非冲突性INSERT语句(同时插 入)。可是,若是您正打算在MySQL外面操做数据库文件,同时您保持锁定,则不能使用READ LOCAL。对 于InnoDB表,READ LOCAL与READ相同。 当您使用LOCK TABLES时,您必须锁定您打算在查询中使用的全部的表。虽然使用LOCK TABLES语句得到的 锁定仍然有效,可是您不能访问没有被此语句锁定的任何的表。同时,您不能在一次查询中屡次使用一个已锁 定的表——使用别名代替,在此状况下,您必须分别得到对每一个别名的锁定。 mysql> LOCK TABLE t WRITE, t AS t1 WRITE; 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; 若是您的查询使用一个别名引用一个表,那么您必须使用一样的别名锁定该表。若是没有指定别名,则不会锁 定该表。 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锁定,则另外一个线程会申请一个WRITE锁定,后续的READ锁定申请会等待,直到WRITE线程得到锁 定并释放锁定。您能够使用LOW_PRIORITY WRITE锁定来容许其它线程在该线程正在等待WRITE锁定时获 得READ锁定。只有当您肯定最终将有一个时机,此时没有线程拥有READ锁定时,您才应该使 用LOW_PRIORITY WRITE锁定。 LOCK TABLES按照以下方式执行: 1. 按照内部定义的顺序,对全部要被锁定的表进行分类。从用户的角度,此顺序是未经定义的。 2. 若是使用一个读取和一个写入锁定对一个表进行锁定,则把写入锁定放在读取锁定以前。 3. 一次锁定一个表,直到线程获得全部锁定为止。 该规则确保表锁定不会出现死锁定。可是,对于该规则,您须要注意其它的事情: 若是您正在对一个表使用一个LOW_PRIORITY WRITE锁定,这只意味着,MySQL等待特定的锁定,直到没有 申请READ锁定的线程时为止。当线程已经得到WRITE锁定,并正在等待获得锁定表清单中的用于下一个表的 锁定时,全部其它线程会等待WRITE锁定被释放。若是这成为对于应用程序的严重的问题,则您应该考虑把部 分表转化为事务安全型表。 您能够安全地使用KILL来结束一个正在等待表锁定的线程。请参见13.5.5.3节,“KILL语法”。 注意,您不能使用INSERT DELAYED锁定任何您正在使用的表,由于,在这种状况下,INSERT由另外一个线程执 行。 一般,您不须要锁定表,由于全部的单个UPDATE语句都是原子性的;没有其它的线程能够干扰任何其它当前 正在执行的SQL语句。可是,在几种状况下,锁定表会有好处: · 若是您正在对一组MyISAM表运行许多操做,锁定您正在使用的表,能够快不少。锁定MyISAM表能够 加快插入、更新或删除的速度。不利方面是,没有线程能够更新一个用READ锁定的表(包括保持锁定的 表),也没有线程能够访问用WRITE锁定的表(除了保持锁定的表之外)。 有些MyISAM操做在LOCK TABLES之下更快的缘由是,MySQL不会清空用于已锁定表的关键缓存,直 到UNLOCK TABLE被调用为止。一般,关键缓存在每一个SQL语句以后被清空。 · 若是您正在使用MySQL中的一个不支持事务的存储引擎,则若是您想要肯定在SELECT和UPDATE之间没 有其它线程,您必须使用LOCK TABLES。本处所示的例子要求LOCK TABLES,以便安全地执行: · mysql> LOCK TABLES trans READ, customer WRITE; · mysql> SELECT SUM(value) FROM trans WHERE customer_id=some_id; · mysql> UPDATE customer · -> SET total_value=sum_from_previous_statement · -> WHERE customer_id=some_id; · mysql> UNLOCK TABLES; 若是没有LOCK TABLES,有可能另外一个线程会在执行SELECT和UPDATE语句之间在trans表中插入一个新行。 经过使用相对更新(UPDATE customer SET value=value+new_value)或LAST_INSERT_ID()函数,您能够在 许多状况下避免使用LOCK TABLES。请参见1.8.5.3节,“事务和原子操做”。 经过使用用户层级的顾问式锁定函数GET_LOCK()和RELEASE_LOCK(),您也能够在有些状况下避免锁定表。这 些锁定被保存在服务器中的一个混编表中,使用pthread_mutex_lock() 和pthread_mutex_unlock(),以加快速 度。请参见12.9.4节,“其余函数”。 要了解更多有关锁定规则的说明,请参见7.3.1节,“锁定方法”。 您能够使用FLUSH TABLES WITH READ LOCK语句锁定位于全部带有读取锁定的数据库中的全部表。请参 见13.5.5.2节,“FLUSH语法”。若是您有一个能够及时拍摄快照的文件系统,好比Veritas,这是得到备份的一 个很是方便的方式。 注释:若是您对一个已锁定的表使用ALTER TABLE,该表可能会解锁。请参见A.7.1节,“与ALTER TABLE有关 的问题”。 13.4.6. SET TRANSACTION语法 SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE } 本语句用于设置事务隔离等级,用于下一个事务,或者用于当前会话。 在默认状况下,SET TRANSACTION会为下一个事务(还未开始)设置隔离等级。若是您使用GLOBAL关键词, 则语句会设置全局性的默认事务等级,用于从该点之后建立的全部新链接。原有的链接不受影响。要进行此操 做,您须要SUPER权限。使用SESSION关键测能够设置默认事务等级,用于对当前链接执行的全部未来事务。 要了解对每一个InnoDB事务隔离等级的描述,请参见15.2.10.3节,“InnoDB和TRANSACTION ISOLATION LEVEL”。InnoDB支持MySQL 5.1中的各个等级。默认的等级是REPEATABLE READ。 您能够使用--transaction-isolation选项,对mysqld设置初始的默认全局隔离等级。请参 见5.3.1节,“mysqld命令行选项”。 13.4.7. XA事务 13.4.7.1. XA事务SQL语法 13.4.7.2. XA事务状态 对于InnoDB存储引擎,能够得到对XA事务的支持。MySQL XA的执行依据X/Open CAE文件Distributed Transaction Processing: The XA Specification。本文件由Open Group出版,能够 从http://www.opengroup.org/public/pubs/catalog/c193.htm获取。在I.5节,“对XA事务的限制”对当前XA执行 的限制进行了描述。 在客户端方面,没有特殊要求。链接MySQL服务器的XA接口由以XA关键词开头的SQL语句组成。MySQL客户端 必须能发送SQL语句,并能理解XA语句接口的语义,可是它们不须要被连接到特定的MySQL客户库上。 当前,在MySQL链接器当中,MySQL链接器/J 5.0.0直接支持XA(也就是,经过一个能够控制XA SQL语句接口 的等级接口)。 XA支持分布式的事务,具有能力,让多个独立的事务资源参加全局的事务。事务资源一般是RDBMSs,不过也 能够是其它种类的资源。 一个全局事务会涉及到多个行动,这些行动自己是事务性的。不过,全部行动都必须做为一个群组成功完成, 或者做为一个群组被回滚。实际上,这会延伸ACID性质,“提升等级”,这样,多个ACID事务就能够一块儿执 行,至关于也拥有ACID性质的全局操做的组件。(可是,对于一个分布式事务,您必须使用SERAILIZABLE隔 离等级,以实现ACID性质。对于一个非分布式事务,使用REPEATABLE READ就足够了。可是对于分布式事 务,使用REPEATABLE READ是不够的。) 分布式事务的部分示例: · 应用程序至关于一个把消息传递服务和RDBMS组合在一块儿的整合工具。应用程序能够确保,全部进行 消息发送、回收和处理的事务(同时包含一个事务数据库)均在一个全局事务中发生。您能够把这看做是“事 务电子邮件。” · 应用程序执行的行动会涉及到不一样数据库服务器,好比MySQL服务器和Oracle服务器(或多个MySQL服 务器)。涉及到多个服务器的行动必须做为一个全局事务的一部分发生,而不是做为针对每一个服务器的独立的 本地事务发生。 · 银行把账户信息保存在RDBMS中,并经过自动取款机(ATMs)分发和收取欠款。必需要确保ATM行动 被正确地反映到账户中,可是这不能只由RDBMS单独完成。全局事务管理器会整合ATM和数据库资源,以确保 财务事务的总体一致性。 使用全局事务的应用程序涉及一个或多个资源管理器和一个事务管理器: · 资源管理器(RM)用于提供通向事务资源的途径。数据库服务器是一种资源管理器。该管理器必须可 以提交或回滚由RM管理的事务。 · 事务管理器(TM)用于协调做为一个全局事务一部分的事务。TM与管理每一个事务的RMs进行通信。一 个全局事务中各个单个事务均是全局事务的“分支”。全局事务和各分支经过一种命名方法进行标识。这种命名 方法在后面进行讲述。 MySQL执行XA MySQL时,MySQL服务器至关于一个用于管理全局事务中的XA事务的资源管理器。与MySQL服 务器链接的客户端至关于事务管理器。 要执行一个全局事务,必须知道涉及到了哪些组件,而且把每一个组件引到一点,在此时,组件能够被提交或回 滚时。根据每一个组件报告的有关组件效能的内容,这些组件必须做为一个原子性群组所有提交或回滚。即,要 么全部的组件必须提交,要么全部的组件必须回滚。要管理一个全局事务,必需要考虑任何组件或链接网络可 能会故障。 用于执行全局事务的过程使用两阶段提交(2PC),发生时间在由全局事务的分支进行的行动已经被执行之 后。 1. 在第一阶段,全部的分支被预备好。即,它们被TM告知要准备提交。一般,这意味着用于管理分支的每 个RM会记录对于被稳定保存的分支的行动。分支指示是否它们能够这么作。这些结果被用于第二阶段。 2. 在第二阶段,TM告知RMs是否要提交或回滚。若是在预备分支时,全部的分支指示它们将可以提交,则 全部的分支被告知要提交。若是在预备时,有任何分支指示它将不能提交,则全部分支被告知回滚。 在有些状况下,一个全局事务可能会使用一阶段提交(1PC)。例如,当一个事务管理器发现,一个全局事务 只由一个事务资源组成(即,单一分支),则该资源能够被告知同时进行预备和提交。 13.4.7.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 对于XA START,JOIN和RESUME子句不被支持。 对于XA END,SUSPEND [FOR MIGRATE]子句不被支持。 每一个XA语句以XA关键词为开头,多数语句要求一个xid值。 xid是一个XA事务标识符。它指示该语句适用于哪 个事务。xid值由客户端提供,或由MySQL服务器生成。xid值包含一到三个部分: xid: gtrid [, bqual [, formatID ]] gtrid是一个全局事务标识符,bqual是一个分支限定符,formatID是一个数字,用于标识由gtrid和bqual值使用 的格式。根据语法的表示,bqual和formatID是自选的。若是没有给定,默认的bqual值是''。若是没有给定,默 认的fromatID值是1。 gtrid和bqual必须为字符串文字,每一个的长度最多为64字节(不是字符)。gtrid和bqual能够用多种方法指定。 您能够使用带引号的字符串('ab'),十六进制字符串(0x6162, X'ab'),或位值(b'nnnn')。 formatID是一个无符号的整数。 经过MySQL服务器的带下划线的XA支持子程序,gtrid和bqual值被理解为以字节为单位。可是,在包含XA语句 的SQL语句正在被分析的同时,服务器会去操做一些特定的字符集。为了安全,把gtrid和bqual做为十六进制字 符串写入。 一般,xid值由事务管理器生成。由一个TM生成的值必须与由其它TMs生成的值不一样。一个给定的TM必须能识 别本身的xid值。这些值位于由XA RECOVER语句返回的值清单中。 XA START xid用于启动一个带给定xid值的XA事务。每一个XA事务必须有一个惟一的xid值,所以该值当前不能被 其它的XA事务使用。使用gtrid和bqual值评估惟一性。全部下列的用于XA事务的XA语句必须使用与XA START语句中给定的相同的xid值进行指定。若是您使用这些语句,可是指定的xid值与部分原有的XA事务不对 应的话,会发生错误。 一项或多项XA事务能够是同一个全局事务的一部分。在一个给定的全局事务中的全部XA事务必须在xid值中使 用一样的gtrid值。出于这个缘由,gtrid值必须为全局惟一的,这样,有关一个给定的XA事务是哪一个全局事务的 一部分的问题就不会含糊不清。对于一个全局事务中的每一个XA事务,xid值中的bqual部分必须不同。 (bqual值应不同,这个要求是当前执行MySQL XA的一个限制条件。这不是XA规约的一部分。) 对于在MySQL服务器上的处于PREPARED状态的XA事务,XA RECOVER语句会返回信息。 (见13.4.7.2节,“XA事务状态”.。)输出包括一个行,该行用于服务器上的每一个这类XA事务,不管是哪一个客户 端启动了它。 XA RECOVER输出行看上去像这样(例如,xid值包括'abc', 'def'和7等部分): mysql> XA RECOVER; +----------+--------------+--------------+--------+ | formatID | gtrid_length | bqual_length | data | +----------+--------------+--------------+--------+ | 7 | 3 | 3 | abcdef | +----------+--------------+--------------+--------+ 输出列有如下意义: · formatID是事务xid的formatID部分 · gtrid_length是xid的gtrid部分的长度,以字节为单位 · bqual_length是xid的bqual部分的长度,以字节为单位 · data是xid的gtrid部分和bqual部分的串联 13.4.7.2. XA事务状态 XA事务在如下状态下进展: 1. 使用XA START来启动一个XA事务,并把它放入ACTIVE状态。 2. 对于一个ACTIVE XA事务,发布构成事务的SQL语句,而后发布一个XA END语句。XA END把事务放 入IDLE状态。 3. 对于一个IDLE XA事务,您能够发布一个XA PREPARE语句或一个XA COMMIT…ONE PHASE语句: · XA PREPARE把事务放入PREPARED状态。在此点上的XA RECOVER语句将在其输出中包括事务 的xid值,由于XA RECOVER会列出处于PREPARED状态的全部XA事务。 · XA COMMIT…ONE PHASE用于预备和提交事务。xid值将不会被XA RECOVER列出,由于事务终止。 4. 对于一个PREPARED XA事务,您能够发布一个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语句不能被使用,直到该事务被提交或被回滚为 mysql> show variables like '%XA%'; +------------------------+-------+ | Variable_name | Value | +------------------------+-------+ | innodb_support_xa | ON | | min_examined_row_limit | 0 | +------------------------+-------+ WITH GRANT OPTION子句给予用户能力,能够在指定的权限层级,向其它用户给定其拥有的任何权限。您应 该留心您给予了谁GRANT OPTION权限,由于拥有不一样权限的两个用户能够联合使用权限! 您不能向其它用户授予您本身没有的权限;GRANT OPTION权限只容许您赋予您本身拥有的权限。 要注意,当您在某个特定权限层级向一个用户授予GRANT OPTION权限时,用户拥有的该层级的任何权限(或 将来将被给定的权限)也能够由该用户授予。假设您向一个用户赋予了数据库INSERT权限。若是您而后赋予 数据库SELECT权限,并指定了WITH GRANT OPTION,则该用户不只能够向其它用户给予SELECT权限,还可 以给予INSERT。若是您而后向用户授予数据库UPDATE权限,则用户能够授予INSERT, SELECT和UPDATE。 您不该该向一个常规用户授予ALTER权限。若是您这么作,则该用户能够尝试经过对表从新命名来破坏受权系 统! The MAX_QUERIES_PER_HOUR count, MAX_UPDATES_PER_HOUR count, and MAX_CONNECTIONS_PER_HOUR count options limit the number of queries, updates, and logins a user can perform during any given one-hour period. If count is 0 (the default), this means that there is no limitation for that user. MAX_QUERIES_PER_HOUR count, MAX_UPDATES_PER_HOUR count和MAX_CONNECTIONS_PER_HOUR count选项限制了在任何给定的一小时期间,用户能够执行的查询、 更新和登陆的数目。若是count是0(默认值),这意味着,对该用户没有限制。 MAX_USER_CONNECTIONS count选项限制了帐户能够同时进行的链接的最大数目。若是count是0(默认 值),则max_user_connections系统能够决定该帐户同时链接的数目。 注释:要对一个原有的用户指定任何这类资源限制型选项,同时又不影响原有的权限,需使用GRANT USAGE ON *.* ... WITH MAX_...。 见5.8.4节,“限制帐户资源”。 除了根据username和密码进行常规鉴定外,MySQL还能够检查X509证实属性。要为MySQL帐户指定与SSL有 关的选项,需使用GRANT语句的REQUIRE子句。(要了解有关在MySQL中使用SSL的背景信息,请参 见5.8.7节,“使用安全链接”。) 对于一个给定的帐户,有多种可能性能够限制链接类型: · 若是帐户没有SSL或X509要求,而且若是username和密码是有效的,则容许不加密链接。可是,若是 客户端有正确的证实和关键文件,则根据客户端的选择,也能够使用加密链接。 · REQUIRE SSL选项用于告知服务器,对于该帐户只容许SSL加密链接。注意,若是有容许任何非SSL连 接的访问控制记录,则本选项能够被忽略。 · mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' · -> IDENTIFIED BY 'goodsecret' REQUIRE SSL; · REQUIRE X509意味着客户端必须拥有一个有效证实,除非不须要确切的证实、发布者和主题。惟一的 要求是,应能够使用CA证实其中之一来验证签名。 · mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' · -> IDENTIFIED BY 'goodsecret' REQUIRE X509; · REQUIRE ISSUER 'issuer'用于对链接尝试进行限定,客户端必须出示一个由CA’issuer’发布的有效 的X509证实。若是客户端出示的证实是有效的,可是有一个不一样的发布者,则服务器会拒绝链接。使 用X509证实就意味着要加密,因此在这种状况下,SSL选项是没必要要的。 · mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' · -> IDENTIFIED BY 'goodsecret' · -> REQUIRE ISSUER '/C=FI/ST=Some-State/L=Helsinki/ · O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com'; 注意,ISSUER值应被做为一个单一字符串输入。 · REQUIRE SUBJECT 'subject'用于对链接尝试进行限定,客户端必须出示一个包含主题subject的有效 的X509证实。若是客户端出示的证实是有效的,可是有一个不一样的主题,则服务器会拒绝链接。 · mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' · -> IDENTIFIED BY 'goodsecret' · -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/ · O=MySQL demo client certificate/ · CN=Tonu Samuel/Email=tonu@example.com'; 注意,SUBJECT值应被做为一个单一字符串输入。 · 须要REQUIRE CIPHER 'cipher'来确认使用了密码和足够长度的关键字。若是使用了采用短型加密关键 字的旧算法,SSL自己会比较脆弱。使用本选项,您能够要求使用特定的密码方法来许可一个链接。 · mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' · -> IDENTIFIED BY 'goodsecret' · -> REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA'; SUBJECT, ISSUER和CIPHER选项能够在REQUIRE子句中结合,以下: mysql> GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' -> IDENTIFIED BY 'goodsecret' -> REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/ O=MySQL demo client certificate/ CN=Tonu Samuel/Email=tonu@example.com' -> AND ISSUER '/C=FI/ST=Some-State/L=Helsinki/ O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com' -> AND CIPHER 'EDH-RSA-DES-CBC3-SHA'; 注意,SUBJECT和ISSUER值各自应被做为一个单一字符串输入。 在REQUIRE各选项之间,AND关键词是自选的。 选项的顺序无所谓,可是选项不能被指定两次。 当mysqld启动后,全部的权限被读入存储器中。要了解详细说明,请参见5.7.7节,“权限更改什么时候生效”。 注意,若是您正在使用表权限或列权限,即便只对一个用户使用,服务器也会对全部用户检查表权限和列权 限,这会略微下降MySQL的速度。与此相似,若是您对某些用户限制查询、更新或链接的数目,则服务器必须 监测这些值。 标准SQL版本和MySQL版本的GRANT之间的最大区别是: · 在MySQL中,权限与hostname和username的组合有关,与单一的username无关。 · 标准SQL不拥有全局层级或数据库层级权限,也不支持MySQL支持的全部权限类型。 · MySQL不支持标准SQL TRIGGER或UNDER权限。 · 标准SQL权限以一种分等级的方式进行组织。若是您取消一个用户,则用户被授予的全部权限都被撤 销。在MySQL中,若是您使用DROP USER,也会如此。请参见13.5.1.2节,“DROP USER语法”。 · 在标准SQL中,当您取消一个表时,对一个表的全部权限会被撤销。在标准SQL中,当您撤销一个权限 时,根据该权限被授予的全部权限也会被撤销。在MySQL中,只有使用明确的REVOKE语句,或经过操做存储 在MySQL受权表中的值,才能取消权限。 · 在MySQL中,能够只对一个表中的部分列拥有INSERT权限。在此状况下,若是您忽略您不拥 有INSERT权限的那些列,,您仍然能够对表执行INSERT语句。若是没有启用严格的SQL模式,则被忽略的列 被设置为各自隐含的默认值。在严格模式下,若是某个被忽略的列没有默认值,则该语句被拒 绝。5.3.2节,“SQL服务器模式”对严格模式进行了讨论。13.1.5节,“CREATE TABLE语法”对隐含默认值进行了 讨论。 您不拥有INSERT权限的列被设置为各自的默认值。标准SQL要求您拥有全部列的INSERT权限。 在MySQL中,若是您只拥有一个表中的部分列的INSERT权限,同时,若是您从INSERT语句中忽略您不拥有权 限的列,则您仍然能够对表执行INSERT语句;那些列将被设置为各自的默认值。在严格模式下(即 当sql_mode='traditional'时,若是某些被忽略的列没有默认值,则INSERT语句将被拒绝 SET PASSWORD语法 SET PASSWORD = PASSWORD('some password') SET PASSWORD FOR user = PASSWORD('some password') SET PASSWORD语句用于向一个原有MySQL用户帐户赋予一个密码。 第一个语法为当前用户设置密码。已使用一个非匿名帐户链接到服务器上的任何客户即均可以更改该帐户的密 码。 第二个语法为当前服务器主机上的一个特定帐户设置密码。只有拥有mysql数据库UPDATE权限的客户端能够这 么作。user值应以user_name@host_name的格式被给定,此处user_name和host_name与mysql.user表登陆 项的User和Host列中列出的彻底同样。举例说明,若是您有一个登陆项,User和Host列值 为'bob'和'%.loc.gov',您应该按以下方法写语句: mysql> SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass'); 这至关于如下语句: mysql> UPDATE mysql.user SET Password=PASSWORD('newpass') -> WHERE User='bob' AND Host='%.loc.gov'; mysql> FLUSH PRIVILEGES; 注释:若是您正在使用一个4.1之前的客户端链接到一个MySQL 4.1或MySQL 4.1之后的服务器,则在阅 读5.7.9节,“MySQL 4.1中的密码哈希处理”以前,不能使用前面的SET PASSWORD或UPDATE语句。密码格式 在MySQL 4.1中变动了,而且在特定状况下,若是您更改密码,您可能没法在链接到服务器上。 您能够经过执行SELECT CURRENT_USER()观看您当前的鉴定user@host登陆项。 表维护语句 13.5.2.1. ANALYZE TABLE语法 13.5.2.2. BACKUP TABLE语法 13.5.2.3. CHECK TABLE语法 13.5.2.4. CHECKSUM TABLE语法 13.5.2.5. OPTIMIZE TABLE语法 13.5.2.6. REPAIR TABLE语法 13.5.2.7. RESTORE TABLE语法 13.5.2.1. ANALYZE TABLE语法 ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... 本语句用于分析和存储表的关键字分布。在分析期间,使用一个读取锁定对表进行锁定。这对于MyISAM, BDB和InnoDB表有做用。对于MyISAM表,本语句与使用myisamchk -a至关。 MySQL使用已存储的关键字分布来决定,当您对除常数之外的对象执行联合时,表按什么顺序进行联合。 本语句会返回一个含有如下列的表: 列值 Table 表名称 Op 进行分析 Msg_type 状态、错误、信息或警告之一 Msg_text 消息 您能够使用SHOW INDEX语句检查已存储的关键字分布。请参见13.5.4.11节,“SHOW INDEX语法”。 若是从上一个ANALYZE TABLE语句开始,表没有变化,则再也不分析该表。 ANALYZE TABLE语句被写入二进制日志中,除非使用了自选的NO_WRITE_TO_BINLOG关键词(或其别 名LOCAL)。 13.5.2.2. BACKUP TABLE语法 BACKUP TABLE tbl_name [, tbl_name] ... TO '/path/to/backup/directory' 注释:本语句不理想。咱们正在努力寻找一种更好的替代方式,该方式将提供在线备份能力。同时,也能够使 用mysqlhotcopy本来替代。 BACKUP TABLE用于在刷新了全部对磁盘的缓冲变动后,把恢复表所需的最少数目的表文件拷贝到备份目录 中。本语句只对MyISAM表起做用。它能够拷贝.frm定义文件和.MYD数据文件。.MYI索引文件能够从这两个文 件中重建。本目录应被指定为一个完整的路径名。 在使用本语句前,请参见5.9.1节,“数据库备份”。 在备份期间,为每一个表保持一个读取锁定,每次一个,在正在备份时锁定。若是您想要把多个表做为一个快照 来备份(防止它们在备份操做过程当中被更改),您必须实现发布一个LOCK TABLES语句,以得到对一个组群中 的每一个表的读取锁定。 该语句会返回一个含有如下列的表: 列值 Table 表名称 Op 进行备份 Msg_type 状态、错误、信息或警告之一 Msg_text 消息 13.5.2.3. CHECK TABLE语法 CHECK TABLE tbl_name [, tbl_name] ... [option] ... option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED} 检查一个或多个表是否有错误。CHECK TABLE对MyISAM和InnoDB表有做用。对于MyISAM表,关键字统计数 据被更新。 CHECK TABLE也能够检查视图是否有错误,好比在视图定义中被引用的表已不存在。 CHECK TABLE语句会返回一个含有如下列的表: 列值 Table 表名称 Op 进行检查 Msg_type 状态、错误、信息或错误之一 Msg_text 消息 注意,该语句可能会为每一个被检查的表产生多行信息。最后一行有一个Msg_type状态值。Msg_text一般应 为OK。若是您没有获得OK,或表已经更新了,则您一般应该运行修复后的表。请参见5.9.4节,“表维护和崩溃 恢复”。表已经更新了,这意味着表的存储引擎指示没有必要检查表。 能够给予的不一样的检查选项列于下表中。这些选项只适用于检查MyISAM表。对于InnoDB表和视图,这些选项 被忽略。 类型意义 QUICK 不扫描行,不检查错误的连接。 FAST 只检查没有被正确关闭的表。 CHANGED 只检查上次检查后被更改的表,和没有被正确关闭的表。 MEDIUM 扫描行,以验证被删除的连接是有效的。也能够计算各行的关键字校验和,并使用计算出的校验 和验证这一点。 EXTENDED 对每行的全部关键字进行一个全面的关键字查找。这能够确保表是100%一致的,可是花的时间较 长。 若是没有指定QUICK, MEDIUM或EXTENDED选项,则对于动态格式MyISAM表,默认检查类型是MEDIUM。这 与对表运行myisamchk --medium-check tbl_name的结果相同。对于静态格式MyISAM表,默认检查类型 也是MEDIUM,除非CHANGED或FAST已被指定。在此状况下,默认值为QUICK。对于CHANGED和FAST,行 扫描被跳过,由于行极少被破坏。 您能够组合检查选项,以下面的例子所示。该例子对表进行了一个快速检查,来查看该表是否被正确关闭: CHECK TABLE test_table FAST QUICK; 注释:在有些状况下,CHECK TABLE会更改表。若是表被标记为“corrupted”或“not closed properly”,则出现 这种状况。可是CHECK TABLE不会找出表中的问题。在这种状况下,CHECK TABLE会把表标记为良好。 若是一个表被破坏,颇有可能问题在索引中,而不在数据部分中。全部前述的检查类型均可以完全地检查索 引,所以,能够找出多数的错误。 若是您只想要检查您假定的表是良好的,您应该不使用检查选项或QUICK选项。当您时间匆忙时,应使 用QUICK。QUICK没法找出数据文件中的错误的风险很是小。(在多数状况下,在正常使用中,MySQL应能在 数据文件中找出错误。若是找出了错误,表被标记为“corrupted”,并不能被使用,直到修复为止。) 若是您想要时常检查表,FAST和CHANGED多数状况下从本来中被使用(例如,从cron中被执行)。在多数情 况下,FAST优先于CHANGED。(只有一种状况FAST不优先于CHANGED,那就是当您怀疑您在MyISAM代码中 发现了错误。) 当MySQL试图经过关键字更新一行或查找一行时,若是您已经运行了一个常规检查后但仍获得来自表的奇怪的 错误,此时使用EXTENDED。(若是常规的检查运行成功,则基本用不着EXTENDED。) 被CHECK TABLE报告的部分问题不会被自动修正: · 发现行。此行中,auto_increment列有0值。 这意味着,您在表中有一行,该行的AUTO_INCREMENT索引列包含0值。(能够经过使用UPDATE语句,明确 地把列设置为0,以建立一个AUTO_INCREMENT列为0的行。) 这自己不是一个错误,可是若是您决定转储表并恢复表,或对表进行ALTER TABLE,那么会致使出现麻烦。在 此状况下,AUTO_INCREMENT列会根据AUTO_INCREMENT列的结果更改值,这会致使出现问题,如重复关键 字错误等。 要消除警告,只需执行一个UPDATE语句,把列设置为除0之外的值。 13.5.2.4. CHECKSUM TABLE语法 CHECKSUM TABLE tbl_name [, tbl_name] ... [ QUICK | EXTENDED ] 报告一个表校验和。 若是指定了QUICK,则报告活性表校验和,不然报告NULL。这是很是快的。活性表经过指定CHECKSUM=1表 选项启用,目前只支持用于MyISAM表。请参见13.1.5节,“CREATE TABLE语法”。 在EXTENDED模式下,整个表被一行一行地读取,并计算校验和。对于大型表,这是很是慢的。 默认状况下,若是既没有指定QUICK,也没有指定EXTENDED,而且若是表存储引擎支持,则MySQL返回一个 活性校验和,不然会对表进行扫描。 CHECKSUM TABLE对于不存在的表会返回NULL。对于这种状况,会生成一个警告。 13.5.2.5. OPTIMIZE TABLE语法 OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... 若是您已经删除了表的一大部分,或者若是您已经对含有可变长度行的表(含有VARCHAR, BLOB或TEXT列的 表)进行了不少更改,则应使用OPTIMIZE TABLE。被删除的记录被保持在连接清单中,后续的INSERT操做会 从新使用旧的记录位置。您能够使用OPTIMIZE TABLE来从新利用未使用的空间,并整理数据文件的碎片。 在多数的设置中,您根本不须要运行OPTIMIZE TABLE。即便您对可变长度的行进行了大量的更新,您也不需 要常常运行,每周一次或每个月一次便可,只对特定的表运行。 OPTIMIZE TABLE只对MyISAM, BDB和InnoDB表起做用。 对于MyISAM表,OPTIMIZE TABLE按以下方式操做: 1. 若是表已经删除或分解了行,则修复表。 2. 若是未对索引页进行分类,则进行分类。 3. 若是表的统计数据没有更新(而且经过对索引进行分类不能实现修复),则进行更新。 对于BDB表,OPTIMIZE TABLE目前被映射到ANALYZE TABLE上。对于InnoDB表,OPTIMIZE TABLE被映射 到ALTER TABLE上,这会重建表。重建操做能更新索引统计数据并释放成簇索引中的未使用的空间。请参 见13.5.2.1节,“ANALYZE TABLE语法”。 使用—skip-new或—safe-mode选项能够启动mysqld。经过启动mysqld,您能够使OPTIMIZE TABLE对其它表 类型起做用。 注意,在OPTIMIZE TABLE运行过程当中,MySQL会锁定表。 OPTIMIZE TABLE语句被写入到二进制日志中,除非使用了自选的NO_WRITE_TO_BINLOG关键词(或其别 名LOCAL)。已经这么作了,所以,用于MySQL服务器的OPTIMIZE TABLE命令的做用至关于一个复制主服务 器,在默认状况下,这些命令将被复制到复制从属服务器中。 13.5.2.6. REPAIR TABLE语法 REPAIR [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... [QUICK] [EXTENDED] [USE_FRM] REPAIR TABLE用于修复被破坏的表。默认状况下,REPAIR TABLE与myisamchk --recover tbl_name具备相 同的效果。REPAIR TABLE对MyISAM和ARCHIVE表起做用。请参见15.1节,“MyISAM存储引擎”, 15.8节,“ARCHIVE存储引擎”。 一般,您基本上没必要运行此语句。可是,若是灾难发生,REPAIR TABLE颇有可能从MyISAM表中找回全部数 据。若是您的表常常被破坏,您应该尽力找到缘由,以免使用REPAIR TALBE。请参见A.4.2节,“如 果MySQL依然崩溃,应做些什么”。同时也见15.1.4节,“MyISAM表方面的问题”。 本语句会返回一个含有如下列的表: 列值 Table 表名称 Op 进行修复 Msg_type 状态、错误、信息或警告之一 Msg_text 消息 对于每一个被修复的表,REPAIR TABLE语句会产生多行的信息。上一行含有一个Msg_type状态值。Msg_test通 常应为OK。若是您没有获得OK,您应该尝试使用myisamchk --safe-recover修复表,由于REPAIR TABLE尚不会执行全部的myisamchk选项。咱们计划在未来使它的灵活性更强。 若是给定了QUICK,则REPAIR TABLE会尝试只修复索引树。这种类型的修复与使用myisamchk --recover - -quick类似。 若是您使用EXTENDED,则MySQL会一行一行地建立索引行,代替使用分类一次建立一个索引。这种类型的修 复与使用myisamchk --safe-recover类似。 对于REPAIR TABLE,还有一种USE_FRM模式能够利用。若是.MYI索引文件缺失或标题被破坏,则使用此模 式。在这种模式下,MySQL能够使用来自.frm文件从新建立.MYI文件。这种修复不能使用myisamchk来完 成。注释:只能在您不能使用常规REPAIR模式是,才能使用此模式。.MYI标题包含重要的表元数据(特别 是,当前的AUTO_INCREMENT值和Delete连接)。这些元数据在REPAIR...USE_FRM中丢失。若是表被压缩, 则不能使用USE_FRM。由于本信息也存储在.MYI文件中。 REPAIR TABLE语句被写入二进制日志中,除非使用了自选的NO_WRITE_TO_BINLOG关键词(或其别 名LOCAL)。 警告:若是在REPAIR TABLE运行过程当中,服务器停机,则在从新启动以后,在执行其它操做以前,您必须立 刻对表再执行一个REPAIR TABLE语句。(经过制做一个备份来启动是一个好办法。)再最不利状况下,您可 以有一个新的干净的索引文件,不含有关数据文件的信息。而后,您执行的下一个操做会覆盖数据文件。这很 少发生,可是是有可能的。 13.5.2.7. RESTORE TABLE语法 RESTORE TABLE tbl_name [, tbl_name] ... FROM '/path/to/backup/directory' 用于恢复来自用BACKUP TABLE制做的备份的表。原有的表不会被覆盖;若是您试图覆盖一个原有的表,会发 生错误。和BACKUP TABLE同样,RESTORE TABLE目前只对MyISAM表起做用。目录应被指定为一个完整路径 名。 每一个表的备份包括其.frm格式文件和.MYD数据文件。恢复操做会恢复这些文件,而后使用这些文件来重 建.MYI索引文件。恢复操做比备份操做花的时间更长,这是由于须要重建索引。表含有的索引越多,花的时间 就越长。 该语句会返回一个含有如下列的表: 列值 Table 表名称 Op 进行恢复 Msg_type 状态、错误、信息或警告之一 Msg_text 消息 SHOW语法 13.5.4.1. SHOW CHARACTER SET语法 13.5.4.2. SHOW COLLATION语法 13.5.4.3. SHOW COLUMNS语法 13.5.4.4. SHOW CREATE DATABASE语法 13.5.4.5. SHOW CREATE TABLE语法 13.5.4.6. SHOW DATABASES语法 13.5.4.7. SHOW ENGINE语法 13.5.4.8. SHOW ENGINES语法 13.5.4.9. SHOW ERRORS语法 13.5.4.10. SHOW GRANTS语法 13.5.4.11. SHOW INDEX语法 13.5.4.12. SHOW INNODB STATUS语法 13.5.4.13. SHOW LOGS语法 13.5.4.14. SHOW OPEN TABLES语法 13.5.4.15. SHOW PRIVILEGES语法 13.5.4.16. SHOW PROCESSLIST语法 13.5.4.17. SHOW STATUS语法 13.5.4.18. SHOW TABLE STATUS语法 13.5.4.19. SHOW TABLES语法 13.5.4.20. SHOW TRIGGERS语法 13.5.4.21. SHOW VARIABLES语法 13.5.4.22. SHOW WARNINGS语法 SHOW有多种形式,能够提供有关数据库、表、列或服务器状态的信息。本节叙述如下内容: SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [LIKE 'pattern'] SHOW CREATE DATABASE db_name SHOW CREATE TABLE tbl_name SHOW DATABASES [LIKE 'pattern'] SHOW ENGINE engine_name {LOGS | STATUS } SHOW [STORAGE] ENGINES SHOW ERRORS [LIMIT [offset,] row_count] SHOW GRANTS FOR user SHOW INDEX FROM tbl_name [FROM db_name] SHOW INNODB STATUS SHOW [BDB] LOGS SHOW PRIVILEGES SHOW [FULL] PROCESSLIST SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern'] SHOW TABLE STATUS [FROM db_name] [LIKE 'pattern'] SHOW [OPEN] TABLES [FROM db_name] [LIKE 'pattern'] SHOW TRIGGERS SHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern'] SHOW WARNINGS [LIMIT [offset,] row_count] SHOW语句还有一些形式,能够提供有关复制型主服务器和从属服务器的信息。这些形式在13.6节,“复制语 句”中进行了叙述。 SHOW BINLOG EVENTS SHOW MASTER LOGS SHOW MASTER STATUS SHOW SLAVE HOSTS SHOW SLAVE STATUS 若是一个给定的SHOW语句的语法包括一个LIKE 'pattern'部分,则'pattern'是一个能够包含SQL ‘%’和‘_’通配 符的字符串。对于把语句输出值限定为匹配值,本样式是有用的。 13.5.4.1. SHOW CHARACTER SET语法 SHOW CHARACTER SET [LIKE 'pattern'] SHOW CHARACTER SET语句用于显示全部可用的字符集。该语句取一个自选的LIKE子句。该子句指示哪些字 符集名称能够匹配。举例说明: 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 | +---------+-----------------------------+-------------------+--------+ Maxlen列显示用于存储一个字符的最大的字节数目。 13.5.4.2. SHOW COLLATION语法 SHOW COLLATION [LIKE 'pattern'] 来自SHOW COLLATION的输出包括全部可用的字符集。该语句取一个自选的LIKE子句。该子句的pattern指示 哪些整序名称能够匹配。举例说明: mysql> SHOW COLLATION LIKE 'latin1%'; +-------------------+---------+----+---------+----------+---------+ | Collation | Charset | Id | Default | Compiled | Sortlen | +-------------------+---------+----+---------+----------+---------+ | latin1_german1_ci | latin1 | 5 | | | 0 | | latin1_swedish_ci | latin1 | 8 | Yes | Yes | 0 | | latin1_danish_ci | latin1 | 15 | | | 0 | | latin1_german2_ci | latin1 | 31 | | Yes | 2 | | latin1_bin | latin1 | 47 | | Yes | 0 | | latin1_general_ci | latin1 | 48 | | | 0 | | latin1_general_cs | latin1 | 49 | | | 0 | | latin1_spanish_ci | latin1 | 94 | | | 0 | +-------------------+---------+----+---------+----------+---------+ Default列指示对于其字符集,整序值是不是默认值。Compiled指示字符集是否被编辑到服务器中。Sortlen与 对字符串(在字符集中表达)分类所需的存储器的数量有关。 13.5.4.3. SHOW COLUMNS语法 SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [LIKE 'pattern'] SHOW COLUMNS显示在一个给定表中的各列的信息。对于试图,本语句也起做用。 若是列类型与根据您的CREATE TABLE语句所预期的列类型不一样,则需注意,当您建立或更改表时,MySQL有 时会更改列类型。出现这种状况的条件在13.1.5.1节,“沉寂的列规格变动”中进行了描述。 FULL关键词会使得输出中包含您拥有的权限,并包含对每一列各自的评注。 您能够使用db_name.tbl_name做为tbl_name FROM db_name语法的另外一种形式。换句话说,这两个语句是等 价的: mysql> SHOW COLUMNS FROM mytable FROM mydb; mysql> SHOW COLUMNS FROM mydb.mytable; SHOW FIELDS是SHOW COLUMNS的同义词。您也能够使用mysqlshow db_name tbl_name命令列举表的各 列。 DESCRIBE语句提供与SHOW COLUMNS相近的信息。请参见13.3.1节,“DESCRIBE语法(获取关于列的信 息)”。 13.5.4.4. SHOW CREATE DATABASE语法 SHOW CREATE {DATABASE | SCHEMA} db_name 显示用于建立给定数据库CREATE DATABASE语句。也能够使用SHOW CREATE SCHEMA。 mysql> SHOW CREATE DATABASE test\G *************************** 1. row *************************** Database: test Create Database: CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */ mysql> SHOW CREATE SCHEMA test\G *************************** 1. row *************************** Database: test Create Database: CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */ 13.5.4.5. SHOW CREATE TABLE语法 SHOW CREATE TABLE tbl_name 显示用于建立给定表的CREATE TABLE语句。本语句对视图也起做用。 mysql> SHOW CREATE TABLE t\G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE t ( id INT(11) default NULL auto_increment, s char(60) default NULL, PRIMARY KEY (id) ) ENGINE=MyISAM 根据SQL_QUOTE_SHOW_CREATE选项,SHOW CREATE TABLE会对表名称和列名称加引号。请参 见13.5.3节,“SET语法”。 13.5.4.6. SHOW DATABASES语法 SHOW {DATABASES | SCHEMAS} [LIKE 'pattern'] SHOW DATABASES能够在MySQL服务器主机上列举数据库。您也能够使用mysqlshow命令获得此清单。您只 能看到您拥有某些权限的数据库,除非您拥有全局SHOW DATABASES权限。 若是服务器以--skip-show-database选项为起始,则您根本不能使用本语句,除非您拥有SHOW DATABASES权 限。 也能够使用SHOW SCHEMAS。 13.5.4.7. SHOW ENGINE语法 SHOW ENGINE engine_name {LOGS | STATUS } SHOW ENGINE显示存储引擎的日志或状态信息。目前支持如下语句: SHOW ENGINE BDB LOGS SHOW ENGINE INNODB STATUS SHOW ENGINE BDB LOGS显示原有BDB日志文件的状态信息。它会返回如下字段: · File 通向日志文件的完整路径。 · Type 日志文件类型(用于Berkeley DB日志文件的BDB)。 · Status 日志文件的状态(若是文件能够被取消,则为FREE。若是文件被事务子系统须要,则为IN USE) SHOW ENGINE INNODB STATUS显示InnoDB存储引擎状态的全面信息。 这些语句的旧的同义词(如今不同意使用)是SHOW [BDB] LOGS和SHOW INNODB STATUS。 SHOW ENGINE能够从MySQL 4.1.2起使用。 13.5.4.8. SHOW ENGINES语法 SHOW [STORAGE] ENGINES SHOW ENGINES显示存储引擎的状态信息。对于检查一个存储引擎是否被支持,或者对于查看默认引擎是什 么,本语句十分有用。SHOW TABLE TYPES是同义词,但不同意使用。 mysql> SHOW ENGINES\G *************************** 1. row *************************** Engine: MyISAM Support: DEFAULT Comment: Default engine as of MySQL 3.23 with great performance *************************** 2. row *************************** Engine: MEMORY Support: YES Comment: Hash based, stored in memory, useful for temporary tables *************************** 3. row *************************** Engine: HEAP Support: YES Comment: Alias for MEMORY *************************** 4. row *************************** Engine: MERGE Support: YES Comment: Collection of identical MyISAM tables *************************** 5. row *************************** Engine: MRG_MYISAM Support: YES Comment: Alias for MERGE *************************** 6. row *************************** Engine: ISAM Support: NO Comment: Obsolete storage engine, now replaced by MyISAM *************************** 7. row *************************** Engine: MRG_ISAM Support: NO Comment: Obsolete storage engine, now replaced by MERGE *************************** 8. row *************************** Engine: InnoDB Support: YES Comment: Supports transactions, row-level locking, and foreign keys *************************** 9. row *************************** Engine: INNOBASE Support: YES Comment: Alias for INNODB *************************** 10. row *************************** Engine: BDB Support: NO Comment: Supports transactions and page-level locking *************************** 11. row *************************** Engine: BERKELEYDB Support: NO Comment: Alias for BDB *************************** 12. row *************************** Engine: NDBCLUSTER Support: DISABLED Comment: Clustered, fault-tolerant, memory-based tables *************************** 13. row *************************** Engine: NDB Support: DISABLED Comment: Alias for NDBCLUSTER *************************** 14. row *************************** Engine: EXAMPLE Support: NO Comment: Example storage engine *************************** 15. row *************************** Engine: ARCHIVE Support: YES Comment: Archive storage engine *************************** 16. row *************************** Engine: CSV Support: YES Comment: CSV storage engine *************************** 17. row *************************** Engine: FEDERATED Support: NO Comment: Federated MySQL storage engine *************************** 18. row *************************** Engine: BLACKHOLE Support: YES Comment: /dev/null storage engine (anything you write to it disappears) Support值指示某个存储引擎是否被支持,并指示哪一个是默认引擎。例如,若是服务器以--default-tabletype= InnoDB选项为起始,则InnoDB行的Support值为DEFAULT值。请参见第15章:存储引擎和表类型。 13.5.4.9. SHOW ERRORS语法 SHOW ERRORS [LIMIT [offset,] row_count] SHOW COUNT(*) ERRORS 本语句与SHOW WARNINGS接近,不过该语句只显示错误,不一样时显示错误、警告和注意。 LIMIT子句与SELECT语句具备相同的语法,请参见13.2.7节,“SELECT语法”。 SHOW COUNT(*) ERRORS语句显示错误的数目。您也能够从error_count变量中找回此数目: SHOW COUNT(*) ERRORS; SELECT @@error_count; 要了解更多信息,请参见13.5.4.22节,“SHOW WARNINGS语法”。 13.5.4.10. SHOW GRANTS语法 SHOW GRANTS FOR user 本语句列出了在为MySQL用户帐户复制权限时必须发布的GRANT语句。 mysql> SHOW GRANTS FOR 'root'@'localhost'; +---------------------------------------------------------------------+ | Grants for root@localhost | +---------------------------------------------------------------------+ | GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION | +---------------------------------------------------------------------+ 要对当前的会话列出权限,您能够使用如下语句之一: SHOW GRANTS; SHOW GRANTS FOR CURRENT_USER; SHOW GRANTS FOR CURRENT_USER(); 13.5.4.11. SHOW INDEX语法 SHOW INDEX FROM tbl_name [FROM db_name] SHOW INDEX会返回表索引信息。其格式与ODBC中的SQLStatistics调用类似。 SHOW INDEX会返回如下字段: · Table 表的名称。 · Non_unique 若是索引不能包括重复词,则为0。若是能够,则为1。 · Key_name 索引的名称。 · Seq_in_index 索引中的列序列号,从1开始。 · Column_name 列名称。 · Collation 列以什么方式存储在索引中。在MySQL中,有值‘A’(升序)或NULL(无分类)。 · Cardinality 索引中惟一值的数目的估计值。经过运行ANALYZE TABLE或myisamchk -a能够更新。基数根据被存储为整数 的统计数据来计数,因此即便对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用 该索引的机会就越大。 · Sub_part 若是列只是被部分地编入索引,则为被编入索引的字符的数目。若是整列被编入索引,则为NULL。 · Packed 指示关键字如何被压缩。若是没有被压缩,则为NULL。 · Null 若是列含有NULL,则含有YES。若是没有,则该列含有NO。 · Index_type 用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。 · Comment 多种评注。 您能够使用db_name.tbl_name做为tbl_name FROM db_name语法的另外一种形式。这两个语句是等价的: mysql> SHOW INDEX FROM mytable FROM mydb; mysql> SHOW INDEX FROM mydb.mytable; SHOW KEYS是SHOW INDEX的同义词。您也能够使用mysqlshow -k db_name tbl_name命令列举一个表的 索引。 13.5.4.12. SHOW INNODB STATUS语法 SHOW INNODB STATUS 在MySQL 5.1中,这是SHOW ENGINE INNODB STATUS的同义词,但不同意使用。请参见13.5.4.7节,“SHOW ENGINE语法”。 13.5.4.13. SHOW LOGS语法 SHOW [BDB] LOGS 在MySQL 5.1中,这是SHOW ENGINE BDB LOGS的同义词,可是不同意使用。请参见13.5.4.7节,“SHOW ENGINE语法”。 13.5.4.14. SHOW OPEN TABLES语法 SHOW OPEN TABLES [FROM db_name] [LIKE 'pattern'] SHOW OPEN TABLES列举在表缓存中当前被打开的非TEMPORARY表。请参见7.4.9节,“MySQL如何打开和关 闭表”。 SHOW OPEN TABLES会返回如下字段: · Database 含有该表的数据库。 · Table 表名称。 · In_use 表当前被查询使用的次数。若是该数为零,则表是打开的,可是当前没有被使用。 · Name_locked 表名称是否被锁定。名称锁定用于取消表或对表进行重命名等操做。 13.5.4.15. SHOW PRIVILEGES语法 SHOW PRIVILEGES SHOW PRIVILEGES显示MySQL服务器支持的系统权限清单。确切的输出根据您的服务器的版本而定。 mysql> SHOW PRIVILEGES\G *************************** 1. row *************************** Privilege: Alter Context: Tables Comment: To alter the table *************************** 2. row *************************** Privilege: Alter routine Context: Functions,Procedures Comment: To alter or drop stored functions/procedures *************************** 3. row *************************** Privilege: Create Context: Databases,Tables,Indexes Comment: To create new databases and tables *************************** 4. row *************************** Privilege: Create routine Context: Functions,Procedures Comment: To use CREATE FUNCTION/PROCEDURE *************************** 5. row *************************** Privilege: Create temporary tables Context: Databases Comment: To use CREATE TEMPORARY TABLE *************************** 6. row *************************** Privilege: Create view Context: Tables Comment: To create new views *************************** 7. row *************************** Privilege: Create user Context: Server Admin Comment: To create new users *************************** 8. row *************************** Privilege: Delete Context: Tables Comment: To delete existing rows *************************** 9. row *************************** Privilege: Drop Context: Databases,Tables Comment: To drop databases, tables, and views *************************** 10. row *************************** Privilege: Execute Context: Functions,Procedures Comment: To execute stored routines *************************** 11. row *************************** Privilege: File Context: File access on server Comment: To read and write files on the server *************************** 12. row *************************** Privilege: Grant option Context: Databases,Tables,Functions,Procedures Comment: To give to other users those privileges you possess *************************** 13. row *************************** Privilege: Index Context: Tables Comment: To create or drop indexes *************************** 14. row *************************** Privilege: Insert Context: Tables Comment: To insert data into tables *************************** 15. row *************************** Privilege: Lock tables Context: Databases Comment: To use LOCK TABLES (together with SELECT privilege) *************************** 16. row *************************** Privilege: Process Context: Server Admin Comment: To view the plain text of currently executing queries *************************** 17. row *************************** Privilege: References Context: Databases,Tables Comment: To have references on tables *************************** 18. row *************************** Privilege: Reload Context: Server Admin Comment: To reload or refresh tables, logs and privileges *************************** 19. row *************************** Privilege: Replication client Context: Server Admin Comment: To ask where the slave or master servers are *************************** 20. row *************************** Privilege: Replication slave Context: Server Admin Comment: To read binary log events from the master *************************** 21. row *************************** Privilege: Select Context: Tables Comment: To retrieve rows from table *************************** 22. row *************************** Privilege: Show databases Context: Server Admin Comment: To see all databases with SHOW DATABASES *************************** 23. row *************************** Privilege: Show view Context: Tables Comment: To see views with SHOW CREATE VIEW *************************** 24. row *************************** Privilege: Shutdown Context: Server Admin Comment: To shut down the server *************************** 25. row *************************** Privilege: Super Context: Server Admin Comment: To use KILL thread, SET GLOBAL, CHANGE MASTER, etc. *************************** 26. row *************************** Privilege: Update Context: Tables Comment: To update existing rows *************************** 27. row *************************** Privilege: Usage Context: Server Admin Comment: No privileges - allow connect only 13.5.4.16. SHOW PROCESSLIST语法 SHOW [FULL] PROCESSLIST SHOW PROCESSLIST显示哪些线程正在运行。您也能够使用mysqladmin processlist语句获得此信息。若是 您有SUPER权限,您能够看到全部线程。不然,您只能看到您本身的线程(也就是,与您正在使用的MySQL帐 户相关的线程)。请参见13.5.5.3节,“KILL语法”。若是您不使用FULL关键词,则只显示每一个查询的前100个 字符。 本语句报告TCP/IP链接的主机名称(采用host_name:client_port格式),以方便地断定哪一个客户端正在作什 么。 若是您获得“too many connections”错误信息,而且想要了解正在发生的状况,本语句是很是有用 的。MySQL保留一个额外的链接,让拥有SUPER权限的帐户使用,以确保管理员可以随时链接和检查系统 (假设您没有把此权限给予全部的用户)。 在来自SHOW PROCESSLIST的输出中常见的一些状态: · Checking table 线程正在执行(自动)表格检查。 · Closing tables 意味着线程正在刷新更改后的表数据,并正在关闭使用过的表。这应该是一个快速的操做。若是不快,则您应 该验证您的磁盘没有充满,而且磁盘没有被超负荷使用。 · Connect Out 链接到主服务器上的从属服务器。 · Copying to tmp table on disk 临时结果集合大于tmp_table_size。线程把临时表从存储器内部格式改变为磁盘模式,以节约存储器。 · Creating tmp table 线程正在建立一个临时表,以保持部分结果。 · deleting from main table 服务器正在执行多表删除的第一部分,只从第一个表中删除。 · deleting from reference tables 服务器正在执行多表删除的第二部分,从其它表中删除匹配的行。 · Flushing tables 线程正在执行FLUSH TABLES,并正在等待全部线程,以关闭表。 · FULLTEXT initialization 服务器正在准备执行一个天然语言全文本搜索。 · Killed 有人已经向线程发送了一个KILL命令。在下一次检查终止标记时,应放弃。该标记在MySQL的每一个大循环中都 检查,可是在有些状况下,线程终止只须要较短的时间。若是该线程被其它线程锁定,则只要其它线程接触锁 定,终止操做就会生效。 · Locked 该查询被其它查询锁定。 · Sending data 线程正在为SELECT语句处理行,同时正在向客户端发送数据。 · Sorting for group 线程正在进行分类,以知足GROUP BY要求。 · Sorting for order 线程正在进行分类,以知足ORDER BY要求。 · Opening tables 线程正在试图打开一个表。这应该是很是快的过程,除非打开操做受到阻止。例如,一个ALTER TABLE或一 个LOCK TABLE语句能够阻止打开一个表,直到语句完成为止。 · Removing duplicates 查询正在使用SELECT DISTINCT。使用时,在早期阶段,MySQL不能优化不一样的操做。所以,MySQL要求一个 额外的阶段,以便在把结果发送给客户端以前取消全部的复制行。 · Reopen table 线程获得一个表锁定,可是在获得锁定后被通知带下方的表结构已更改了。它已经释放了锁定,关闭了表,并 试图从新打开它。 · Repair by sorting 修复代码正在使用一个分类来建立索引。 · Repair with keycache 修复代码正在经过关键缓存一个接一个地使用建立关键字。这比经过分类修复要慢不少。 · Searching rows for update 线程正在进行第一阶段,以在更新以前,查找全部匹配的行。若是UPDATE正在更改用于查找相关行的索引, 则必须这么作。 · Sleeping 线程正在等待客户端,以向它发送一个新语句。 · System lock 线程正在等待获得一个用于表的外部系统锁定。若是您没有正在使用多个正在访问同一个表的mysqld服务器, 则您能够使用--skip-external-locking选项禁用系统锁定。 · Upgrading lock INSERT DELAYED管理程序正在试图获得一个表锁定,以插入行。 · Updating 线程正在搜索行,并正在更新这些行。 · User Lock 线程正在等待GET_LOCK()。 · Waiting for tables 线程获得一个通知,表的底层结构已经改变,须要从新打开表以获得新的结构。可是,为了能从新打开表,必 须等待,直到全部其它的线程已经关闭了正在被质询的表。 若是其它线程已经对正在被质询的表使用了FLUSH TABLES或如下语句之一:FLUSH TABLES tbl_name, ALTER TABLE, RENAME TABLE, REPAIR TABLE, ANALYZE TABLE或OPTIMIZE TABLE;则会出现通知。 · waiting for handler insert INSERT DELAYED管理程序已经处理了全部处于等待状态的插入,并正在等待新插入。 多数状态对应于很是快的操做。若是一个线程在这些状态下停留了数秒,则多是有问题,须要进行调查。 有一些其它的状态,在前面的清单中没有说起,可是其中有不少状态对于查找服务器中的程序错误是有用的。 13.5.4.17. SHOW STATUS语法 SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern'] SHOW STATUS提供服务器状态信息。此信息也能够使用mysqladmin extended-status命令得到。 此处显示了局部的输出。对于您的服务器,变量和值的清单能够是不一样的。在5.3.4节,“服务器状态变量”中给 出了每一个变量的意义。 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> SHOW STATUS LIKE 'Key%'; +--------------------+----------+ | Variable_name | Value | +--------------------+----------+ | Key_blocks_used | 14955 | | Key_read_requests | 96854827 | | Key_reads | 162040 | | Key_write_requests | 7589728 | | Key_writes | 3813196 | +--------------------+----------+ 使用GLOBAL选项,您能够获得全部MySQL链接的状态值。使用SESSION,您能够获得全部当前链接的状态 值。若是您两个选项都不使用,则默认值为SESSION。LOCAL是SESSION的同义词。 注意,有些状态变量只有一个全局值。对于这些变量,使用GLOBAL和SESSION会获得一样的值。 13.5.4.18. SHOW TABLE STATUS语法 SHOW TABLE STATUS [FROM db_name] [LIKE 'pattern'] SHOW TABLE STATUS的性质与SHOW TABLE相似,不过,能够提供每一个表的大量信息。您也能够使 用mysqlshow --status db_name命令获得此清单。 本语句也显示视图信息。 对于NDB Cluster表,本语句的输出显示Avg_row_length和Data_length列的适当值,不过BLOB列没有被考虑进 来。另外,复制数量在Comment列中显示(做为number_of_replicas)。 SHOW TABLE STATUS会返回如下字段: · Name 表的名称。 · Engine 表的存储引擎。在MySQL 4.1.2以前,本值被标记为Type。请参见第15章:存储引擎和表类型。 · Version 表的.frm文件的版本号。 · Row_format 行存储格式(Fixed, Dynamic, Compressed, Redundant, Compact)。InnoDB表的格式被报告 为Redundant或Compact。 · Rows 行的数目。部分存储引擎,如MyISAM,存储精确的数目。 对于其它存储引擎,好比InnoDB,本值是一个大约的数,与实际值相差可达40到50%。在这些状况下,使 用SELECT COUNT(*)来得到准确的数目。 对于在INFORMATION_SCHEMA数据库中的表,Rows值为NULL。 · Avg_row_length 平均的行长度。 · Data_length 数据文件的长度。 · Max_data_length 数据文件的最大长度。若是给定了数据指针的大小,这是能够被存储在表中的数据的字节总数。 · Index_length 索引文件的长度。 · Data_free 被整序,可是未使用的字节的数目。 · Auto_increment 下一个AUTO_INCREMENT值。 · Create_time 何时表被建立。 · Update_time 何时数据文件被最后一次更新。 · Check_time 何时表被最后一次检查。不是全部的存储引擎此时都更新,在此状况下,值为NULL。 · Collation 表的字符集和整序。 · Checksum 活性校验和值。 · Create_options 和CREATE TABLE同时使用的额外选项。 · Comment 建立表时使用的评注(或者有关为何MySQL能够访问表信息的说明)。 在表评注中,InnoDB表报告表所属的表空间的空闲空间。对于一个位于共享表空间中的表,这是共享表空间中 的空闲空间。若是您正在使用多个表空间,而且该表有本身的表空间,则空闲空间只用于此表。 对于MEMORY (HEAP)表,Data_length, Max_data_length和Index_length值近似于被整序的存储器的实际值。 整序算法预留了大量的存储器,以减小整序操做的数量。 对于视图,由SHOW TABLE STATUS显示的全部字段均为NULL。例外状况是Name指示为视图名称同 时Comment称为视图。 13.5.4.19. SHOW TABLES语法 SHOW [FULL] TABLES [FROM db_name] [LIKE 'pattern'] SHOW TABLES列举了给定数据库中的非TEMPORARY表。您也能够使用mysqlshow db_name命令获得此清 单。 本命令也列举数据库中的其它视图。支持FULL修改符,这样SHOW FULL TABLES就能够显示第二个输出列。对 于一个表,第二列的值为BASE TABLE;对于一个视图,第二列的值为VIEW。 注释:若是您对于一个表没有权限,则该表不会在来自SHOW TABLES或的mysqlshow db_name输出中显 示。 13.5.4.20. SHOW TRIGGERS语法 SHOW TRIGGERS [FROM db_name] [LIKE expr] SHOW TRIGGERS列出了目前被MySQL服务器定义的触发程序。 对于在21.3节,“使用触发程序”中定义的触发程序ins_sum,本语句的输出显示以下: mysql> SHOW TRIGGERS LIKE 'acc%'; +---------+--------+---------+-------------------------------+--------+---------+ | Trigger | Event | Table | Statement | Timing | Created | +---------+--------+---------+-------------------------------+--------+---------+ | ins_sum | INSERT | account | SET @sum = @sum + NEW.amount | BEFORE | NULL | +---------+--------+---------+-------------------------------+--------+---------+ 注释:当使用一个含有SHOW TRIGGERS的LIKE子句时,待匹配的表达式(expr)会与触发程序定义时所在的 表的名称相比较,而不与触发程序的名称相比较: mysql> SHOW TRIGGERS LIKE 'ins%'; Empty set (0.01 sec) 对本语句输出中的各列的简要解释以下: · Trigger: 触发程序的名称。 · Event: 调用触发程序的时间。必须为'INSERT', 'UPDATE'或'DELETE'.之一。 · Table: 触发程序定义时对应的表。 · Statement: 当触发程序被调用时执行的语句。这与 在INFORMATION_SCHEMA.TRIGGERS的ACTION_STATEMENT列中显示的文本同样。 · Timing: 'BEFORE'或'AFTER'两个值之一。 · Created: 目前,本列的值为NULL。 为了执行SHOW TRIGGERS,您必须拥有SUPER权限。 同时也见23.1.16节,“INFORMATION_SCHEMA TRIGGERS表”。 13.5.4.21. SHOW VARIABLES语法 SHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern'] SHOW VARIABLES显示了部门MySQL系统变量的值。本信息也能够使用mysqladmin variables命令得到。 使用GLOBAL选项,您能够得到被用于MySQL新链接的值。使用SESSION,您能够获得对于当前链接起效的 值。若是您两个选项都不使用,默认值为SESSION。 LOCAL是SESSION的同义词。 若是默认值不合适,当mysqld启动时或在SET语句运行过程当中,您能够使用命令行选项设置多数的这类变量。 请参见5.3.1节,“mysqld命令行选项”和13.5.3节,“SET语法。 此处显示了部分的输出。对于您的服务器,变量和值的清单会有所不一样。在5.3.3节,“服务器系统变量”中给出 了每一个变量的意义。在7.5.2节,“调节服务器参数”中提供了有关调整变量的信息。 mysql> SHOW VARIABLES; +---------------------------------+-----------------------------------------------+ | Variable_name | Value | +---------------------------------+-----------------------------------------------+ | auto_increment_increment | 1 | | auto_increment_offset | 1 | | automatic_sp_privileges | ON | | back_log | 50 | | basedir | /home/jon/bin/mysql-5.1/ | | binlog_cache_size | 32768 | | bulk_insert_buffer_size | 8388608 | | character_set_client | latin1 | | character_set_connection | latin1 | ... ... | max_user_connections | 0 | | max_write_lock_count | 4294967295 | | multi_range_count | 256 | | myisam_data_pointer_size | 6 | | myisam_max_sort_file_size | 2147483647 | | myisam_recover_options | OFF | | myisam_repair_threads | 1 | | myisam_sort_buffer_size | 8388608 | | ndb_autoincrement_prefetch_sz | 32 | | ndb_cache_check_time | 0 | | ndb_force_send | ON | ... ... ... | time_zone | SYSTEM | | timed_mutexes | OFF | | tmp_table_size | 33554432 | | tmpdir | | | transaction_alloc_block_size | 8192 | | transaction_prealloc_size | 4096 | | tx_isolation | REPEATABLE-READ | | updatable_views_with_limit | YES | | version | 5.1.2-alpha-log | | version_comment | Source distribution | | version_compile_machine | i686 | | version_compile_os | suse-linux | | wait_timeout | 28800 | +---------------------------------+-----------------------------------------------+ 使用LIKE子句,本语句只显示与样式相匹配的变量: mysql> SHOW VARIABLES LIKE 'have%'; +-----------------------+----------+ | Variable_name | Value | +-----------------------+----------+ | have_archive | YES | | have_bdb | NO | | have_blackhole_engine | YES | | have_compress | YES | | have_crypt | YES | | have_csv | YES | | have_example_engine | NO | | have_federated_engine | NO | | have_geometry | YES | | have_innodb | YES | | have_isam | NO | | have_ndbcluster | DISABLED | | have_openssl | NO | | have_partition_engine | YES | | have_query_cache | YES | | have_raid | NO | | have_rtree_keys | YES | | have_symlink | YES | +-----------------------+----------+ 13.5.4.22. SHOW WARNINGS语法 SHOW WARNINGS [LIMIT [offset,] row_count] SHOW COUNT(*) WARNINGS SHOW WARNINGS显示由上一个生成消息的语句致使的错误、警告和注意消息。若是上一个使用表的语句未生 成消息,则什么也不显示。SHOW ERRORS是其相关语句,只显示错误。请参见13.5.4.9节,“SHOW ERRORS语法”。 对于使用一个表的每一个新语句,消息清单均从新设置。 SHOW COUNT(*) WARNINGS语句显示错误、警告和注意的总数。您也能够从warning_count变量中找回此数 目。 SHOW COUNT(*) WARNINGS; SELECT @@warning_count; 若是max_error_count系统变量设置得太低,以至于有的消息没有被存储,则warning_count值可能比由SHOW WARNINGS显示的消息数目要大。本节后部显示的例子展现了这类状况是如何发生的。 LIMIT子句具备与SELECT语句相同的语法。请参见13.2.7节,“SELECT语法”。 MySQL服务器会发回由上一个语句引发的错误、警告和注意的总数。若是您正在使用C API,则此值能够经过 调用mysql_warning_count()来得到。请参见25.2.3.69节,“mysql_warning_count()”。 对于如LOAD DATA INFILE等语句和如INSERT, UPDATE, CREATE TABLE和ALTER TABLE等DML语句,会生成 警告。 如下DROP TABLE语句会致使一个注意: mysql> DROP TABLE IF EXISTS no_such_table; mysql> SHOW WARNINGS; +-------+------+-------------------------------+ | Level | Code | Message | +-------+------+-------------------------------+ | Note | 1051 | Unknown table 'no_such_table' | +-------+------+-------------------------------+ 如下是一个简单的例子,显示了对于CREATE TABLE的一个语法警告,和对于INSERT的转换警告: mysql> CREATE TABLE t1 (a TINYINT NOT NULL, b CHAR(4)) TYPE=MyISAM; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 1287 Message: 'TYPE=storage_engine' is deprecated, use 'ENGINE=storage_engine' instead 1 row in set (0.00 sec) mysql> INSERT INTO t1 VALUES(10,'mysql'),(NULL,'test'), -> (300,'Open Source'); Query OK, 3 rows affected, 4 warnings (0.01 sec) Records: 3 Duplicates: 0 Warnings: 4 mysql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 1265 Message: Data truncated for column 'b' at row 1 *************************** 2. row *************************** Level: Warning Code: 1263 Message: Data truncated, NULL supplied to NOT NULL column 'a' at row 2 *************************** 3. row *************************** Level: Warning Code: 1264 Message: Data truncated, out of range for column 'a' at row 3 *************************** 4. row *************************** Level: Warning Code: 1265 Message: Data truncated for column 'b' at row 3 4 rows in set (0.00 sec) 要存储的错误、警告和注意消息的最大数目由max_error_count系统变量控制。默认状况下,该值为64。要更 改您想要存储的信息的数目,需更改max_error_count值。在下面的例子中,ALTER TABLE语句会产生三个警 告消息,可是只有一个被存储,由于max_error_count被设置为1: mysql> SHOW VARIABLES LIKE 'max_error_count'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_error_count | 64 | +-----------------+-------+ 1 row in set (0.00 sec) mysql> SET max_error_count=1; Query OK, 0 rows affected (0.00 sec) mysql> ALTER TABLE t1 MODIFY b CHAR; Query OK, 3 rows affected, 3 warnings (0.00 sec) Records: 3 Duplicates: 0 Warnings: 3 mysql> SELECT @@warning_count; +-----------------+ | @@warning_count | +-----------------+ | 3 | +-----------------+ 1 row in set (0.01 sec) mysql> SHOW WARNINGS; +---------+------+----------------------------------------+ | Level | Code | Message | +---------+------+----------------------------------------+ | Warning | 1263 | Data truncated for column 'b' at row 1 | +---------+------+----------------------------------------+ 1 row in set (0.00 sec) 要禁用警告,需把max_error_count设置为0。在此状况下,warning_count仍然指示有多少警告已经发生,但 是这些消息不被存储。 您能够把SQL_NOTES会话变量设置为0,使“注意”级别的警告不被记录。 13.5.5. 其它管理语句 13.5.5.1. CACHE INDEX语法 13.5.5.2. FLUSH语法 13.5.5.3. KILL语法 13.5.5.4. LOAD INDEX INTO CACHE语法 13.5.5.5. RESET语法 13.5.5.1. CACHE INDEX语法 CACHE INDEX tbl_index_list [, tbl_index_list] ... IN key_cache_name tbl_index_list: tbl_name [[INDEX|KEY] (index_name[, index_name] ...)] CACHE INDEX语句把表索引分配给某个关键缓存。该语句只用于MyISAM表。 下列语句把索引从表t1, t2和t3分配到名为hot_cache的关键缓存: 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语法容许您指定,只有来自表的特定索引应被分配给缓存。可是,当前的实施会把全部的表索引 分配给缓存,因此必须指定表名称,不能指定其它的。 被引用到CACHE INDEX语句中的关键缓存能够这样建立,即经过使用一个参数设置语句或在服务器参数设置中 设置其大小。举例说明: mysql> SET GLOBAL keycache1.key_buffer_size=128*1024; 关键缓存参数能够被做为一个结构化系统变量的成分进行访问。请参见9.4.1节,“结构式系统变量”。 在您能够把索引分配给一个关键缓存之前,缓存必须存在: mysql> CACHE INDEX t1 IN non_existent_cache; ERROR 1284 (HY000): Unknown key cache 'non_existent_cache' 默认状况下,表索引被分配给在服务器启动时被建立的主(默认)键缓存。当一个键高速缓冲被破坏时,全部 被分配到此缓存中的索引会再次被分配给默认的键高速缓冲。 索引的分配会对服务器产生全局性影响:若是一个客户端把一个索引分配给一个给定的缓存,则不论什么客户 端发布查询,本缓存都被用于全部涉及索引的查询。 13.5.5.2. FLUSH语法 FLUSH [LOCAL | NO_WRITE_TO_BINLOG] flush_option [, flush_option] ... 若是您想要清除MySQL使用的部份内部缓存,您应该使用FLUSH语句。要执行FLUSH,您必须拥有RELOAD权 限。 flush_option能够为如下的任何一个: · HOSTS 用于清空主机缓存表。若是有的主机更改了IP号或若是您获得了错误信息Host host_name is blocked,则您应 该刷新主机表。当在链接到MySQL服务器时,若是对于一个给定的主机,接连出现错误“多 于max_connect_errors”,此时,MySQL会假定出现了错误,并阻止主机后续的链接申请。刷新主机表容许主 机尝试再次链接。请参见A.2.5节,“主机的host_name被屏蔽”。您能够使 用max_connect_errors=999999999启动mysqld,以免此错误信息。 · DES_KEY_FILE 用于在服务器启动时,从采用--des-key-file选项指定的文件从新载入DES关键字。 · LOGS 用于关闭并从新打开全部的日志文件。若是您已经指定了一个更新日志文件或一个二进制日志文件,同时没有 扩展,则相对于前一个文件,日志文件的扩展号增长1。若是您在文件名称中使用了一个扩展,则MySQL会关 闭并从新打开日志文件。在Unix中,当相mysqld服务器发送一个SIGHUP信号时,也会如此(例外状况是部 分Mac OS X 10.3版本。在这些版本中,mysqld忽略SIGHUP和SIGQUIT)。 若是服务器使用--log-error选项,则FLUSH LOGS会致使错误日志被重命名(使用后缀-old),同时mysqld会创 建一个新的空日志文件。若是没有给定--log-error选项,则不会进行重命名。 · PRIVILEGES 用于从mysql数据库中的受权表从新载入权限。 · QUERY CACHE 对查询缓存进行整理碎片,以更好得利用存储器。与RESET QUERY CACHE不一样,本语句不会从缓存中取消任 何查询。 · STATUS 用于把多数状态变量从新设置为零。只在当调试查询时,您才应该使用此项。请参见1.7.1.3节,“如何通报缺 陷和问题”。 · {TABLE | TABLES} [tbl_name [, tbl_name] ...] 当没有表被命名时,关闭全部打开的表,并迫使全部正在使用的表关闭。这也会刷新查询缓存。此项含有一个 或多个表名称,只刷新给定的表。和RESET QUERY CACHE语句同样,FLUSH TABLES还会取消来自查询缓存 的全部查询结果。 · TABLES WITH READ LOCK 对于全部带读取锁定的数据库,关闭全部打开的表,并锁定全部的表,直到您执行UNLOCK TABLES为止。如 果您拥有一个能够及时进行快照的文件系统,好比Veritas,则这是进行备份的很是方便的方法。 · USER_RESOURCES 用于把全部每小时用户资源从新设置为零。这能够使已经达到了每小时链接、查询或更新限值的客户端马上重 新恢复活性。FLUSH USER_RESOURCES不适用于同时链接的最大限值。请参 见13.5.1.3节,“GRANT和REVOKE语法”。 FLUSH语句被写入二进制日志,除非使用了自选的NO_WRITE_TO_BINLOG关键字(或其别名LOCAL)。注 释:在任何状况下,FLUSH LOGS, FLUSH MASTER, FLUSH SLAVE和FLUSH TABLES WITH READ LOCK都不会 被记入日志,由于若是它们被复制到一个从属服务器上,会致使出现问题。 您也能够使用flush-hosts, flush-logs, flush-privileges, flush-status或flush-tables命令访问含有mysqladmin应 用程序的语句。 注释:在MySQL 5.1.2-alpha中,不可能在已存储的函数或触发程序中发布FLUSH语句。不过,您能够在已存 储的过程当中使用FLUSH,只要它们不会从已存储的函数或触发程序中被调用。请参见I.1节,“对存储子程序和 触发程序的限制”。 要了解有关RESET语句与复制同时使用的信息,也能够见13.5.5.5节,“RESET语法”。 13.5.5.3. KILL语法 KILL [CONNECTION | QUERY] thread_id 每一个与mysqld的链接都在一个独立的线程里运行,您能够使用SHOW PROCESSLIST语句查看哪些线程正在运 行,并使用KILL thread_id语句终止一个线程。 KILL容许自选的CONNECTION或QUERY修改符: · KILL CONNECTION与不含修改符的KILL同样:它会终止与给定的thread_id有关的链接。 · KILL QUERY会终止链接当前正在执行的语句,可是会保持链接的原状。 若是您拥有PROCESS权限,则您能够查看全部线程。若是您拥有SUPER权限,您能够终止全部线程和语句。否 则,您只能查看和终止您本身的线程和语句。 您也能够使用mysqladmin processlist和mysqladmin kill命令来检查和终止线程。 注释:您不能同时使用KILL和Embedded MySQL Server库,由于内植的服务器只运行主机应用程序的线程。它 不能建立任何自身的链接线程。 当您进行一个KILL时,对线程设置一个特有的终止标记。在多数状况下,线程终止可能要花一些时间,这是因 为终止标记只会在在特定的间隔被检查: · 在SELECT, ORDER BY和GROUP BY循环中,在读取一组行后检查标记。若是设置了终止标记,则该语 句被放弃。 · 在ALTER TABLE过程当中,在每组行从原来的表中被读取前,检查终止标记。若是设置了终止标记,则语 句被放弃,临时表被删除。 · 在UPDATE或DELETE运行期间,在每一个组读取以后以及每一个已更行或已删除的行以后,检查终止标 记。若是终止标记被设置,则该语句被放弃。注意,若是您正在使用事务,则变动不会被回滚。 · GET_LOCK()会放弃和返回NULL。 · INSERT DELAYED线程会快速地刷新(插入)它在存储器中的全部的行,而后终止。 · 若是线程在表锁定管理程序中(状态:锁定),则表锁定被快速地放弃。 · 若是在写入调用中,线程正在等待空闲的磁盘空间,则写入被放弃,并伴随"disk full"错误消息。 · 警告:对MyISAM表终止一个REPAIR TABLE或OPTIMIZE TABLE操做会致使出现一个被损坏的没有用的 表。对这样的表的任何读取或写入都会失败,直到您再次优化或修复它(不中断)。 13.5.5.4. LOAD INDEX INTO CACHE语法 LOAD INDEX INTO CACHE tbl_index_list [, tbl_index_list] ... tbl_index_list: tbl_name [[INDEX|KEY] (index_name[, index_name] ...)] [IGNORE LEAVES] LOAD INDEX INTO CACHE语句会把一个表索引预载入到某个关键缓存中。它已经被一个明确的CACHE INDEX语句分配到此关键缓存中。或者,表索引被预载入到默认的关键缓存中。LOAD INDEX INTO CACHE只 用于MyISAM表。 IGNORE LEAVES修改符只会致使索引的非叶子节点被预载入。 对于表t1和t2,如下语句会预载入索引的节点(索引组): 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语法容许您指定,只有来自表的特定的索引应被预载入。可是,当前实施会把全部 的表索引预载入缓存中,因此必定要指定表名称,不能指定其它的。 13.5.5.5. RESET语法 RESET reset_option [, reset_option] ... RESET语句被用于清除不一样的服务器操做的状态。它也做为FLUSH语句的更强大的版本。请参 见13.5.5.2节,“FLUSH语法”。 为了执行RESET,您必须拥有RELOAD权限。 reset_option能够为如下的任何一项: · MASTER 能够删除列于索引文件中的全部二进制日志,把二进制日志索引文件从新设置为空,并建立一个新的二进制日 志文件。(在之前版本的MySQL中,被称为FLUSH MASTER。)见13.6.1节,“用于控制主服务器的SQL语 句”。 · QUERY CACHE 从查询缓存中取消全部的查询结果。 · SLAVE 能够使从属服务器忘记其在主服务器二进制日志中的复制位置,另外,也能够经过删除原有的中继日志文件和 开始一个新文件来从新设置中继日志。请参见13.6.2节,“用于控制从服务器的SQL语句” 复制语句 13.6.1. 用于控制主服务器的SQL语句 13.6.2. 用于控制从服务器的SQL语句 本节叙述了与复制有关的SQL语句。一组语句被用于控制主服务器。其它的被用于控制从属服务器。 13.6.1. 用于控制主服务器的SQL语句 13.6.1.1. PURGE MASTER LOGS语法 13.6.1.2. RESET MASTER语法 13.6.1.3. SET SQL_LOG_BIN语法 13.6.1.4. SHOW BINLOG EVENTS语法 13.6.1.5. SHOW MASTER LOGS语法 13.6.1.6. SHOW MASTER STATUS语法 13.6.1.7. SHOW SLAVE HOSTS语法 能够经过SQL界面控制复制。本节讨论了用于管理主复制服务器的语句。13.6.2节,“用于控制从服务器 的SQL语句”讨论了用于管理从属服务器的语句。 13.6.1.1. PURGE MASTER LOGS语法 PURGE {MASTER | BINARY} LOGS TO 'log_name' PURGE {MASTER | BINARY} LOGS BEFORE 'date' 用于删除列于在指定的日志或日期以前的日志索引中的全部二进制日志。这些日志也会从记录在日志索引文件 中的清单中被删除,这样被给定的日志成为第一个。 例如: PURGE MASTER LOGS TO 'mysql-bin.010'; PURGE MASTER LOGS BEFORE '2003-04-02 22:46:26'; BEFORE变量的date自变量能够为'YYYY-MM-DD hh:mm:ss'格式。MASTER和BINARY是同义词。 若是您有一个活性的从属服务器,该服务器当前正在读取您正在试图删除的日志之一,则本语句不会起做用, 而是会失败,并伴随一个错误。不过,若是从属服务器是休止的,而且您碰巧清理了其想要读取的日志之一, 则从属服务器启动后不能复制。当从属服务器正在复制时,本语句能够安全运行。您不须要中止它们。 要清理日志,需按照如下步骤: 1. 在每一个从属服务器上,使用SHOW SLAVE STATUS来检查它正在读取哪一个日志。 2. 使用SHOW MASTER LOGS得到主服务器上的一系列日志。 3. 在全部的从属服务器中断定最先的日志。这个是目标日志。若是全部的从属服务器是更新的,这是清单上 的最后一个日志。 4. 制做您将要删除的全部日志的备份。(这个步骤是自选的,可是建议采用。) 5. 清理全部的日志,可是不包括目标日志。 13.6.1.2. RESET MASTER语法 RESET MASTER 能够删除列于索引文件中的全部二进制日志,把二进制日志索引文件从新设置为空,并建立一个新的二进制日 志文件。 13.6.1.3. SET SQL_LOG_BIN语法 SET SQL_LOG_BIN = {0|1} 若是客户端使用一个有SUPER权限的帐户链接,则能够禁用或启用当前链接的二进制日志记录。若是客户端没 有此权限,则语句被拒绝,并伴随有错误。 13.6.1.4. SHOW BINLOG EVENTS语法 SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count] 用于在二进制日志中显示事件。若是您不指定'log_name',则显示第一个二进制日志。 LIMIT子句和SELECT语句具备相同的语法。请参见13.2.7节,“SELECT语法”。 注释:当服务器把二进制日志的完整内容(该日志包括多数的由MySQL执行的查询)转储到stdout时,发布一 个不含LIMIT子句的SHOW BINLOG EVENTS能够启动一个过程,该过程很是消耗时间并消耗资源。要把二进制 日志保存到一个文本文件中,用于之后的检查和分析,需使用mysqlbinlog应用程序。请参 见8.6节,“mysqlbinlog:用于处理二进制日志文件的实用工具”。 13.6.1.5. SHOW MASTER LOGS语法 SHOW MASTER LOGS SHOW BINARY LOGS 用于列出服务器中的二进制日志文件。本语句被用做13.6.1.1节,“PURGE MASTER LOGS语法”中所述的过程 的一部分,用于肯定哪些日志能够被清理。 mysql> SHOW BINARY LOGS; +---------------+-----------+ | Log_name | File_size | +---------------+-----------+ | binlog.000015 | 724935 | | binlog.000016 | 733481 | +---------------+-----------+ SHOW BINARY LOGS与SHOW MASTER LOGS至关。 13.6.1.6. SHOW MASTER STATUS语法 SHOW MASTER STATUS 用于提供主服务器二进制日志文件的状态信息。例如: mysql > SHOW MASTER STATUS; +---------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +---------------+----------+--------------+------------------+ | mysql-bin.003 | 73 | test | manual,mysql | +---------------+----------+--------------+------------------+ 13.6.1.7. SHOW SLAVE HOSTS语法 SHOW SLAVE HOSTS 用于显示当前使用主服务器注册的复制从属服务器的清单。不以--report-host=slave_name选项为开头的从属 服务器不会显示在本清单中。 13.6.2. 用于控制从服务器的SQL语句 13.6.2.1. CHANGE MASTER TO语法 13.6.2.2. LOAD DATA FROM MASTER语法 13.6.2.3. LOAD TABLE tbl_name FROM MASTER语法 13.6.2.4. MASTER_POS_WAIT()语法 13.6.2.5. RESET SLAVE语法 13.6.2.6. SET GLOBAL SQL_SLAVE_SKIP_COUNTER语法 13.6.2.7. SHOW SLAVE STATUS语法 13.6.2.8. START SLAVE语法 13.6.2.9. STOP SLAVE语法 复制操做能够经过SQL界面控制。本节讨论了用于管理从属复制服务器的语句。13.6.1节,“用于控制主服务器 的SQL语句”讨论了用于管理主服务器的语句。 13.6.2.1. CHANGE MASTER TO语法 CHANGE MASTER TO master_def [, master_def] ... master_def: MASTER_HOST = 'host_name' | MASTER_USER = 'user_name' | MASTER_PASSWORD = 'password' | MASTER_PORT = port_num | MASTER_CONNECT_RETRY = count | MASTER_LOG_FILE = 'master_log_name' | MASTER_LOG_POS = master_log_pos | 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_KEY = 'key_file_name' | MASTER_SSL_CIPHER = 'cipher_list' 能够更改从属服务器用于与主服务器进行链接和通信的参数。 MASTER_USER, MASTER_PASSWORD, MASTER_SSL, MASTER_SSL_CA, MASTER_SSL_CAPATH, MASTER_SSL_CERT, MASTER_SSL_KEY和MASTER_SSL_CIPHER用于向从属服务器提供有关如何与主服务器 链接的信息。 即便对于在编译时没有SSL支持的从属服务器,SSL选项(MASTER_SSL, MASTER_SSL_CA, MASTER_SSL_CAPATH, MASTER_SSL_CERT, MASTER_SSL_KEY和MASTER_SSL_CIPHER)也能够被更改。它 们被保存到master.info文件中,可是会被忽略,直到您使用一个SSL支持已启用的服务器。 若是您不指定一个给定的参数,则它会保持其原有的值。例外状况在后面的讨论中进行了说明。举例说明,如 果用于链接到您的MySQL主服务器的密码被更改了,您只需发布这些语句,就能够告知从属服务器新的密 码: mysql> STOP SLAVE; -- if replication was running mysql> CHANGE MASTER TO MASTER_PASSWORD='new3cret'; mysql> START SLAVE; -- if you want to restart replication 没有必要指定没有改变的参数(主机、接口、用户等)。 MASTER_HOST和MASTER_PORT是主服务器主机和其TCP/IP接口的主机名(或IP地址)。注意,如 果MASTER_HOST与localhost相等,那么,和MySQL的其它部分同样,接口能够被忽略(例如,若是能够使 用Unix插槽文件)。 若是您指定了MASTER_HOST或MASTER_PORT,则从属服务器会假定主服务器与之前不同(即便您指定的 主机或接口值与当前值是同样的。)在此状况下,主服务器二进制日志的名称和位置的原有值再也不适用,因 此,若是您不指定语句中 的MASTER_LOG_FILE和MASTER_LOG_POS,MASTER_LOG_FILE=''和MASTER_LOG_POS=4会被静默地添 加。 在MASTER_LOG_FILE和MASTER_LOG_POS坐标点,从属服务器I/O线程在启动以后从主服务器读取。若是您 只指定了其中一个,则从属服务器不能指定RELAY_LOG_FILE或RELAY_LOG_POS。如 果MSATER_LOG_FILE和MASTER_LOG_POS都没有被指定,则从属服务器会使用在CHANGE MASTER被发布前 的最后一个slave SQL thread坐标。当您只想改变要使用的密码时,这能够确保复制的连续性。即便从属服务 器SQL线程落后于从属服务器I/O线程,也能够确保复制的连续性。 CHANGE MASTER会删除全部的中继日志文件并启动一个新的日志,除非您指定 了RELAY_LOG_FILE或RELAY_LOG_POS。在此状况下,中继日志被保持;relay_log_purge全局变量被静默地 设置为0。 CHANGE MASTER TO能够更新master.info和relay-log.info文件的内容。 当您拥有主服务器快照并拥有日志和对应的偏移量时,CHANGE MASTER对于设置从属服务器是有用的。在把 快照载入从属服务器以后,您能够在从属服务器上运行CHANGE MASTER TO MASTER_LOG_FILE='log_name_on_master', MASTER_LOG_POS=log_offset_on_master。 举例说明: mysql> CHANGE MASTER TO -> MASTER_HOST='master2.mycompany.com', -> MASTER_USER='replication', -> MASTER_PASSWORD='bigs3cret', -> MASTER_PORT=3306, -> MASTER_LOG_FILE='master2-bin.001', -> MASTER_LOG_POS=4, -> MASTER_CONNECT_RETRY=10; mysql> CHANGE MASTER TO -> RELAY_LOG_FILE='slave-relay-bin.006', -> RELAY_LOG_POS=4025; 第一个例子能够更改主服务器及其二进制日志坐标。当想要设置从属服务器来复制主服务器时使用。 第二个例子显示了较少被使用的一个操做。当从属服务器含有中继日志,而且您出于某种缘由想要执行此日志 时使用。要这么作时,不须要链接主服务器。您只须要使用CHANGE MASTER TO并启动SQL线程(START SLAVE SQL_THREAD)。 您甚至能够在一个用于独立非从属服务器的非复制型设置中使用第二种操做,在崩溃以后进行复原。假设您的 服务器已崩溃,同时您已恢复了备份。您想要从新播放服务器本身的二进制日志(不是中继日志,而是正规的 二进制文件),例如名为myhost-bin.*。首先,应在安全的地方制做这些二进制日志的备份,以防您没有彻底 遵照如下步骤,意外地让服务器清理了二进制文件。使用SET GLOBAL relay_log_purge=0,进一步增长安全 性。而后启动不含--log-bin选项的服务器。使用--replicate-same-server-id, --relay-log=myhost-bin(让服务 器相信,这些正规的二进制日志是中继日志)和--skip-slave-start options选项。当服务器启动后,发布如下语 句: mysql> CHANGE MASTER TO -> RELAY_LOG_FILE='myhost-bin.153', -> RELAY_LOG_POS=410, -> MASTER_HOST='some_dummy_string'; mysql> START SLAVE SQL_THREAD; 服务器会读取并执行本身的二进制日志,完成崩溃复原。当复原完成后,运行STOP SLAVE,关闭服务器,删 除master.info和relay-log.info,并使用原来的选项从新启动服务器。 要让服务器认为它是一个从属服务器,须要指定MASTER_HOST(甚至使用假值)。 13.6.2.2. LOAD DATA FROM MASTER语法 LOAD DATA FROM MASTER 本命令用于对主服务器进行快照,并拷贝到从属服务器上。它能够更 新MASTER_LOG_FILE和MASTER_LOG_POS的值,这样,从属服务器就能够从正确的位置开始进行复制。使 用--replicate-*-do-*和--replicate-*-ignore-*选项指定的表和数据库排除规则均被兑现。--replicate-rewritedb 没有被考虑。这是由于使用本选项,用户就能够设置一个例如--replicate-rewrite-db=db1->db3和-- replicate-rewrite-db=db2->db3的非惟一映射。当从主服务器载入表时,该映射会使从属服务器发生混淆。 本语句的使用受如下条件的制约: · 只对MyISAM表起做用。若是试图载入一个非MyISAM表,会致使如下错误: · ERROR 1189 (08S01): Net error reading from master · 当拍摄快照时,会得到对主服务器的全局读取锁定。在载入操做期间,该锁定会阻止对主服务器的更 新。 若是您正在载入大表,您可能必须对主服务器和从属服务器均增长net_read_timeout和net_write_timeout值。 请参见5.3.3节,“服务器系统变量”。 注意,LOAD DATA FROM MASTER不从mysql数据库拷贝任何表。这能够更容易地让主服务器和从属服务器拥 有不一样的用户和权限。 LOAD DATA FROM MASTER语句要求用于链接主服务器的复制账户,以便让主服务器拥有RELOAD和SUPER权 限,并让全部您想要载入的主服务器表拥有SELECT权限。全部的用户不拥有SELECT权限的主服务器表均 被LOAD DATA FROM MASTER忽略。这是由于主服务器会对用户隐藏它们:LOAD DATA FROM MASTER会调 用SHOW DATABASES以了解要载入的主服务器数据库,可是SHOW DATABASES只会返回用户有部分权限的数 据库。请参见13.5.4.6节,“SHOW DATABASES语法”。在从属服务器方面,发布LOAD DATA FROM MASTER的用户应拥有受权,以取消或建立被复制的数据库和表。 13.6.2.3. LOAD TABLE tbl_name FROM MASTER语法 LOAD TABLE tbl_name FROM MASTER 用于把表的拷贝从主服务器转移到从属服务器。本语句的主要做用是调试LOAD DATA FROM MASTER。它要求 用于链接主服务器的账户拥有对主服务器的RELOAD和SUPER权限,并拥有对要载入的主服务器表的SELECT权 限。在从属服务器方面,发布LOAD TABLE FROM MASTER的用户应拥有取消和建立表的权限。 用于LOAD DATA FROM MASTER的条件也适用于这里。举例说明,LOAD TABLE FROM MASTER仅对 于MyISAM表起做用。对LOAD DATA FROM MASTER的暂停注意也适用。 13.6.2.4. MASTER_POS_WAIT()语法 SELECT MASTER_POS_WAIT('master_log_file', master_log_pos) 这其实是一个函数,而不是一个语句。它被用于确认,从属服务器已读取并执行了到达主服务器二进制日志 的给定位置。要了解完整的描述,请参见12.9.4节,“其余函数” 13.6.2.5. RESET SLAVE语法 RESET SLAVE 用于让从属服务器忘记其在主服务器的二进制日志中的复制位置。本语句被用于进行一个明确的启动:它会删 除master.info和relay-log.info文件,以及全部的中继日志,并启动一个新的中继日志。 注释:全部的中继日志被删除,即便它们没有被从属服务器SQL线程彻底的执行。(若是您已经发布了一 个SLAVE语句或若是从属服务器的载入量很大,则这对于一个复制从属服务器是一个极可能出现的状况。) 存储在master.info文件中的链接信息经过使用在对应的启动选项中指定的值,被当即从新设置了。此信息包括 主服务器主机、主服务器接口、主服务器用户和主服务器密码等值。当从属服务器SQL线程被停止时,它位于 正在复制的临时表的中间,而且发布了RESET SLAVE,则已被复制的临时表在从属服务器中被删除。 13.6.2.6. SET GLOBAL SQL_SLAVE_SKIP_COUNTER语法 SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n 从主服务器中跳事后面的n个事件。要复起因语句致使的复制停止,这是有用的。 仅当从属线程没有正在运行时,本语句时有效的。不然,会产生一个错误。 13.6.2.7. SHOW SLAVE STATUS语法 SHOW SLAVE STATUS 用于提供有关从属服务器线程的关键参数的信息。若是您使用mysql客户端发布此语句,则您能够使用一 个\G语句终止符来得到更便于阅读的竖向版面,而不是使用分号: mysql> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: localhost Master_User: root Master_Port: 3306 Connect_Retry: 3 Master_Log_File: gbichot-bin.005 Read_Master_Log_Pos: 79 Relay_Log_File: gbichot-relay-bin.005 Relay_Log_Pos: 548 Relay_Master_Log_File: gbichot-bin.005 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 79 Relay_Log_Space: 552 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 8 SHOW SLAVE STATUS会返回如下字段: · Slave_IO_State SHOW PROCESSLIST输出的State字段的拷贝。SHOW PROCESSLIST用于从属I/O线程。若是线程正在试图连 接到主服务器,正在等待来自主服务器的时间或正在链接到主服务器等,本语句会通知您。在6.3节,“复制实 施细节”中列出了可能的状态。旧版本的MySQL在链接主服务器不成功时,容许线程继续运行。对于旧版本 的MySQL,观看此字段是必须的。若是它正在运行,则无问题;若是它没有运行,则您会在Last_Error字段中 发现错误(后面有说明)。 · Master_Host 当前的主服务器主机。 · Master_User 被用于链接主服务器的当前用户。 · Master_Port 当前的主服务器接口。 · Connect_Retry --master-connect-retry选项的当前值 · 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(在4.1.14和5.0.12以前),若是I/O线 程已被启动,即便从属服务器仍没有链接到主服务器上,Slave_IO_Running也将被设置到YES。 · Slave_SQL_Running SQL线程是否被启动。 · Replicate_Do_DB, Replicate_Ignore_DB 使用--replicate-do-db和--replicate-ignore-db选项指定的数据库清单。 · Replicate_Do_Table, Replicate_Ignore_Table, Replicate_Wild_Do_Table, Replicate_Wild_Ignore_Table 使用--replicate-do-table, --replicate-ignore-table, --replicate-wild-do-table和--replicate-wild-ignore_table选 项指定的表清单。 · Last_Errno, Last_Error 被多数最近被执行的查询返回的错误数量和错误消息。错误数量为0而且消息为空字符串意味着“没有错误”。 若是Last_Error值不是空值,它也会在从属服务器的错误日志中做为消息显示。 举例说明: Last_Errno: 1051 Last_Error: error 'Unknown table 'z'' on query 'drop table z' 该消息指示,表z曾经存在于在主服务器中并已被取消了,可是它没有在从属服务器中存在过,所以对于从属 服务器,DROP TABLE失败。(举例说明,在设置复制时,若是您忘记了把此表拷贝到从属服务器中,则这有 可能发生。) · Skip_Counter 最近被使用的用于SQL_SLAVE_SKIP_COUNTER的值。 · Exec_Master_Log_Pos 来自主服务器的二进制日志的由SQL线程执行的上一个时间的位置(Relay_Master_Log_File)。在主服务器的 二进制日志中的(Relay_Master_Log_File, Exec_Master_Log_Pos)对应于在中继日志中的(Relay_Log_File, Relay_Log_Pos)。 · Relay_Log_Space 全部原有的中继日志结合起来的总大小。 · Until_Condition, Until_Log_File, Until_Log_Pos 在START SLAVE语句的UNTIL子句中指定的值。 Until_Condition具备如下值: o 若是没有指定UNTIL子句,则没有值 o 若是从属服务器正在读取,直到达到主服务器的二进制日志的给定位置为止,则值为Master o 若是从属服务器正在读取,直到达到其中继日志的给定位置为止,则值为Relay Until_Log_File和Until_Log_Pos用于指示日志文件名和位置值。日志文件名和位置值定义了SQL线程在哪一个点中 止执行。 · Master_SSL_Allowed, Master_SSL_CA_File, Master_SSL_CA_Path, Master_SSL_Cert, Master_SSL_Cipher, Master_SSL_Key 这些字段显示了被从属服务器使用的参数。这些参数用于链接主服务器。 Master_SSL_Allowed具备如下值: o 若是容许对主服务器进行SSL链接,则值为Yes o 若是不容许对主服务器进行SSL链接,则值为No o 若是容许SSL链接,可是从属服务器没有让SSL支持被启用,则值为Ignored。 与SSL有关的字段的值对应于--master-ca, --master-capath, --master-cert, --master-cipher和--master-key选 项的值。 · Seconds_Behind_Master 本字段是从属服务器“落后”多少的一个指示。当从属SQL线程正在运行时(处理更新),本字段为在主服务器 上由此线程执行的最近的一个事件的时间标记开始,已通过的秒数。当此线程被从属服务器I/O线程遇上,并 进入闲置状态,等待来自I/O线程的更多的事件时,本字段为零。总之,本字段测量从属服务器SQL线程和从属 服务器I/O线程之间的时间差距,单位以秒计。 若是主服务器和从属服务器之间的网络链接较快,则从属服务器I/O线程会很是接近主服务器,因此本字段能 够十分近似地指示,从属服务器SQL线程比主服务器落后多少。若是网络较慢,则这种指示不许确;从 属SQL线程常常会遇上读取速度较慢地从属服务器I/O线程,所以,Seconds_Behind_Master常常显示值为0。 即便I/O线程落后于主服务器时,也是如此。换句话说,本列只对速度快的网络有用。 即便主服务器和从属服务器不具备相同的时钟,时间差计算也会起做用(当从属服务器I/O线程启动时,计算 时间差。并假定今后时之后,时间差保持不变)。若是从属SQL线程不运行,或者若是从属服务器I/O线程不运 行或未与主服务器链接,则Seconds_Behind_Master为NULL(意义为“未知”)。举例说明,若是在从新链接之 前,从属服务器I/O线程休眠了master-connect-retry秒,则显示NULL,由于从属服务器不知道主服务器正在作 什么,也不能有把握地说落后多少。 本字段有一个限制。时间标记经过复制被保留,这意味着,若是一个主服务器M1自己是一个从属服务器M0, 则来自M1的binlog的任何事件(经过复制来自M0的binlog的事件而产生),与原事件具备相同的时间标记。这 能够使MySQL成功地复制TIMESTAMP。可是,Seconds_Behind_Master的缺点是,若是M1也收到来自客户端 的直接更新,则值会随机变化,由于有时最近的M1时间来自M0,有时来自直接更新,最近的时间标记也是如 此。 13.6.2.8. START SLAVE语法 START SLAVE [thread_type [, thread_type] ... ] START SLAVE [SQL_THREAD] UNTIL MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos START SLAVE [SQL_THREAD] UNTIL RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos thread_type: IO_THREAD | SQL_THREAD 不含选项的START SLAVE会同时启动两个从属服务器线程。I/O线程从主服务器中读取查询,并把它们存储在 中继日志中。SQL线程读取中继日志并执行查询。START SLAVE要求SUPER权限。 若是START SLAVE成功地启动了从属服务器线程,则会返回,不会出现错误。可是,即便在此状况下,也有可 能出现这样的现象——服务器线程启动了,而后又中止了(例如,由于它们没有成功地链接到主服务器上,或 者没有能读取二进制日志,或者出现了其它问题)。START SLAVE对此不会发出警告。您必须检查从属服务器 的错误日志,查看是否有由从属服务器线程产生的错误消息,或者使用SHOW SLAVE STATUS检查它们是否运 行正常。 您能够把IO_THREAD和SQL_THREAD选项添加到语句中,指明哪些线程将要启动。 能够添加一个UNTIL子句,指定从属服务器应启动并运行,直到SQL线程达到主服务器二进制日志中的一个给 定点为止。当SQL线程达到此点时,它会中止。若是在该语句中指定了SQL_THREAD选项,则它只会启 动SQL线程。不然,它会同时启动两个从属服务器线程。若是SQL线程正在运行,则UNTIL子句被忽略,并发 布一个警告。 对于一个UNTIL子句,您必须同时指定一个日志文件名和位置。不要把主服务器和中继日志选项混合在一块儿。 UNTIL条件由一个后续的STOP SLAVE语句,或一个不包括UNTIL子句的START SLAVE语句,或一个服务器重启 命令从新设置。 UNTIL子句对于调试复制操做是有用的,或者可用于促使复制操做继续,直到接近一个特定的点时为止,在此 点,您想要避免让从属服务器复制一个语句。举例说明,若是在主服务上执行了一个不明智的DROP TABLE语 句,您能够使用UNTIL来告知从属服务器,执行到此点就中止,不要再继续了。要查找该事件是什么,需对主 服务器日志或从属中继日志使用mysqlbinlog,或经过使用SHOW BINLOG EVENTS语句。 若是您正在使用UNTIL,让从属服务器成段地处理已复制的查询,则建议您使用--skip-slave-start选项来启动 从属服务器,以防止当从属服务器启动时,SQL线程运行。最好在一个选项文件中使用此选项,而不是在命令 行中使用,这样,若是发生了意料外的服务器从新启动,它也不会被忘记。 SHOW SLAVE STATUS语句包括了输出字段。这些字段显示了UNTIL条件的当前值。 在之前版本的MySQL中,本语句被称为SLAVE START。在MySQL 5.1中仍然接受这种用法,以便与之前版本兼 容。但如今不同意使用。 13.6.2.9. STOP SLAVE语法 STOP SLAVE [thread_type [, thread_type] ... ] thread_type: IO_THREAD | SQL_THREAD 用于停止从属服务器线程。STOP SLAVE要求SUPER权限。 和START SLAVE类似,本语句在使用时能够加IO_THREAD和SQL_THREAD选项,指明将被停止的线程。 在之前版本的MySQL中,本语句被称为SLAVE STOP。在MySQL 5.1中仍然接受这种用法,以便与之前版本兼 容。可是如今不同意使用 用于预处理语句的SQL语法 MySQL 5.1对服务器一方的预制语句提供支持。若是您使用合适的客户端编程界面,则这种支持能够发挥 在MySQL 4.1中实施的高效客户端/服务器二进制协议的优点。候选界面包括MySQL C API客户端库(用于C程 序)、MySQL Connector/J(用于Java程序)和MySQL Connector/NET。例如,C API能够提供一套能组成预制 语句API的函数调用。请参见25.2.4节,“C API预处理语句”。其它语言界面能够对使用了二进制协议(经过 在C客户端库中连接)的预制语句提供支持。有一个例子是PHP 5.0中的mysqli扩展。 对预制语句,还有一个SQL界面能够利用。与在整个预制语句API中使用二进制协议相比,本界面效率没有那 么高,可是它不要求编程,由于在SQL层级,能够直接利用本界面: · 当您没法利用编程界面时,您能够使用本界面。 · 有些程序容许您发送SQL语句到将被执行的服务器中,好比mysql客户端程序。您能够从这些程序中使 用本界面。 · 即便客户端正在使用旧版本的客户端库,您也能够使用本界面。惟一的要求是,您可以链接到一个支持 预制语句SQL语法的服务器上。 预制语句的SQL语法在如下状况下使用: · 在编代码前,您想要测试预制语句在您的应用程序中运行得如何。或者也许一个应用程序在执行预制语 句时有问题,您想要肯定问题是什么。 · 您想要建立一个测试案例,该案例描述了您使用预制语句时出现的问题,以便您编制程序错误报告。 · 您须要使用预制语句,可是您没法使用支持预制语句的编程API。 预制语句的SQL语法基于三个SQL语句: PREPARE stmt_name FROM preparable_stmt; EXECUTE stmt_name [USING @var_name [, @var_name] ...]; Chapter 13. SQL Statement Syntax file:///D:/download/refman-5.1-zh.html-chapter/refman-5.1-zh.html-chapter/sql-syntax.html[2010/2/24 5:22:43] {DEALLOCATE | DROP} PREPARE stmt_name; PREPARE语句用于预备一个语句,并赋予它名称stmt_name,借此在之后引用该语句。语句名称对案例不敏 感。preparable_stmt能够是一个文字字符串,也能够是一个包含了语句文本的用户变量。该文本必须展示一个 单一的SQL语句,而不是多个语句。使用本语句,‘?’字符能够被用于制做参数,以指示当您执行查询时,数据 值在哪里与查询结合在一块儿。‘?’字符不该加引号,即便您想要把它们与字符串值结合在一块儿,也不要加引号。 参数制做符只能被用于数据值应该出现的地方,不用于SQL关键词和标识符等。 若是带有此名称的预制语句已经存在,则在新的语言被预备之前,它会被隐含地解除分配。这意味着,若是新 语句包含一个错误而且不能被预备,则会返回一个错误,而且不存在带有给定名称语句。 预制语句的范围是客户端会话。在此会话内,语句被建立。其它客户端看不到它。 在预备了一个语句后,您可以使用一个EXECUTE语句(该语句引用了预制语句名称)来执行它。若是预制语句包 含任何参数制造符,则您必须提供一个列举了用户变量(其中包含要与参数结合的值)的USING子句。参数值 只能有用户变量提供,USING子句必须准确地指明用户变量。用户变量的数目与语句中的参数制造符的数量一 样多。 您能够屡次执行一个给定的预制语句,在每次执行前,把不一样的变量传递给它,或把变量设置为不一样的值。 要对一个预制语句解除分配,需使用DEALLOCATE PREPARE语句。尝试在解除分配后执行一个预制语句会导 致错误。 若是您终止了一个客户端会话,同时没有对之前已预制的语句解除分配,则服务器会自动解除分配。 如下SQL语句能够被用在预制语句中:CREATE TABLE, DELETE, DO, INSERT, REPLACE, SELECT, SET, UPDATE和多数的SHOW语句。目前不支持其它语句。 如下例子显示了预备一个语句的两种方法。该语句用于在给定了两个边的长度时,计算三角形的斜边。 第一个例子显示如何经过使用文字字符串来建立一个预制语句,以提供语句的文本: 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; 预制语句的SQL语法不能被用于带嵌套的风格中。也就是说,被传递给PREPARE的语句自己不能是一 个PREPARE, EXECUTE或DEALLOCATE PREPARE语句。 预制语句的SQL语法与使用预制语句API调用不一样。例如,您不能使用mysql_stmt_prepare() C API函数来预备 一个PREPARE, EXECUTE或DEALLOCATE PREPARE语句。 预制语句的SQL语法能够在已存储的过程当中使用,可是不能在已存储的函数或触发程序中使用。 当使用预制语句时,能够在LIMIT子句中使用占位符。请参见13.2.7节,“SELECT语法”。 */ ?>