mysql5.5手冊讀書日記(3)

<?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語法」。




*/
?>
相關文章
相關標籤/搜索