|
|||||||||||||||||||||||||||||||||||||||||||||||
文章所屬標簽: 科技IT | |||||||||||||||||||||||||||||||||||||||||||||||
字符集支持
輸出實際上包含另一列,這里為了讓例子在頁面上顯示更合適,沒顯示出來 任一給出的字符集至少包含一個collation. 它可能包含多個 collations. 要列出一個字符集的 collations , 使用 SHOW COLLATION 語句. 例如, 要看latin1 (``ISO-8859-1 West European‘‘)的collations, 使用這個語句來找到哪些名字以latin1 開頭的collation
latin1 collations 有下列含義: Collation 含義
Collations 有這些一般特性: ·兩個不同字符集沒法擁有同一個collation. ·每個字符集有一個默認 collation. 例如, latin1 的默認 collation 是 latin1_swedish_ci. ·collation 的命名有個約定: 他們由所關(guān)聯(lián)的字符集的名字打頭,他們通常包含一個 語言名, 并以 _ci (case insensitive大小寫不敏感), 或者 _cs (case sensitive大小寫敏感), 或者 _bin (binary二進制). 10.3 決定默認字符集和 Collation 有四個級別上的默認字符集和collation設(shè)置: 服務(wù)器,數(shù)據(jù)庫,表和連接。下面的描述 可能看起來復雜,不過實踐中得出多級默認設(shè)置可以帶來自然而然的結(jié)果。 10.3.1 服務(wù)器級字符集和 Collation MySQL服務(wù)器有一個服務(wù)器級別的字符集和 collation, 不能為空。 MySQL 這樣決定服務(wù)器級的字符集和collation ·當服務(wù)器開始按照有效選項設(shè)置 ·運行期間按照變量 在服務(wù)器級別,決定是很簡單的,依靠你執(zhí)行mysqld時使用的選項來決定服務(wù)器字符集 和collation。你可以使用--default-character-set 來指定字符集,并且和這個一起 還可以為collation加上--default-collation 。如果你不指定字符集,就相當于說 --default-character-set=latin1。如果你只指定了字符集(例如,latin1)但是沒有指定 collation,就相當于 --default-charset=latin1 --default-collation=latin1_swedish_ci 因為 latin1_swedish_ci是latin1字符集的默認collation, 因此下面三個命令都具有 同樣效果:
有個改變這個設(shè)置的方法是重新編譯,如果你想編譯源碼來改變默認的服務(wù)器字符集和 collation,在configure使加上參數(shù)--with-charset 和 --with-collation ,例如:
或者:
mysqld 和configure 都會核實字符集/collation的結(jié)合是否有效,如果無效,這兩個 程序都會報錯并中止。 現(xiàn)行服務(wù)器字符集和collation 是和character_set_server 和 collation_server 這兩個系統(tǒng)變量的值一樣,這些變量可以在運行時更改 10.3.2 數(shù)據(jù)庫字符集和 Collation 每個數(shù)據(jù)庫都有一個數(shù)據(jù)庫字符集和數(shù)據(jù)庫collation,并且不能為空,create DATABASE 和 alter DATABASE 語句有專門指明數(shù)據(jù)庫字符集和collation的可選子句:
例子:
MySQL可以這樣選擇數(shù)據(jù)庫字符集和數(shù)據(jù)庫collation: ·如果 CHARACTER SET X 和 COLLATE Y 被指定了, 那么字符集是 X collation 是 Y. ·如果 CHARACTER SET X 被指定,但是沒有指定 COLLATE, 那么字符集是 X collation 是默認collation. ·否則, 就用服務(wù)器字符集和服務(wù)器 collation. MySQL 的 create DATABASE ... DEFAULT CHARACTER SET ... 語法類似于標準 SQL 的 create SCHEMA ... CHARACTER SET ... 語法. 因為這樣, 就可能在同一個MySQL 服務(wù)器上創(chuàng)建具有不同字符集和collation的數(shù)據(jù)庫。 如果在建表的語句里沒有指定表的字符集和collation,那么數(shù)據(jù)庫字符集和 collation 就作為表的字符集和collation的默認值. 它們沒有別的作用。 默認數(shù)據(jù)庫的字符集和 collation是和 character_set_database 以及 collation_database 這兩個系統(tǒng)變量的值一樣。 當默認數(shù)據(jù)庫更改時服務(wù)程序會設(shè)置 這些變量的值。如果沒有默認數(shù)據(jù)庫, 變量的值會和配套的服務(wù)器級系統(tǒng)變量 character_set_server 以及 collation_server的值一致. 10.3.3 表字符集和 Collation 每個表有一個表字符集以及一個表collation,不能為空。create TABLE 和 alter TABLE 語句有可選子句指定表字符集和collation。
例子:
MySQL 通過下面的方法選擇表字符集和collation: ·如果 CHARACTER SET X 和 COLLATE Y 都被指定了, 那么字符集就是 X collation 是Y ·如果只指定了CHARACTER SET X 而沒有指定 COLLATE, 那么字符集為 X 并配默認的 collation. ·否則就使用數(shù)據(jù)庫字符集和 collation. 表字符集和 collation 用來在沒有指定個別列字符集和列collation的時候做為它們 的默認值。表字符集和 collation 是MySQL 的擴展;在標準SQL里沒有這種東西 10.3.4 列字符集和 Collation 每個``character‘‘ 列(是指列屬性為CHAR, VARCHAR, 或 TEXT的)都有一個列字符集 和一個列collation,不能為空。列定義語句有可選子句指定列字符集和collation:
MySQL 這樣選擇列字符集和collation: ·如果 CHARACTER SET X 和 COLLATE Y 都被指定了, 那么字符集就是 X collation 就是 Y. ·如果指定了 CHARACTER SET X 但沒有指定 COLLATE, 那么字符集是 X 并配默認的collation. ·否則,就用表字符集和 collation. CHARACTER SET 和 COLLATE 子句是標準SQL. 10.3.5 字符集和 Collation 分配的例子 下面的例子顯示了 MySQL 怎樣決定默認的字符集和collation的值: 例子1:表+列定義
這里我們有一個用latin1的字符集和latin1_german1_ci collation的列。 定義非常明顯,所以很簡單。注意把一個latin1 的列存到一個latin2的表里不會有問題 例子2:表+列定義
這次我們有一列是latin1字符集加默認的collation?,F(xiàn)在,雖然它看上去很自然, 但是默認的collation卻不是從表級繼承而來。事實上,因為latin1的默認collation 始終是latin1_swedish_ci,所以c1列的collation是latin1_swedish_ci (而不是 latin1_danish_ci). 例子3:表+列定義
我們有一個默認字符集和默認collation的列。在這個環(huán)境下,MySQL向上到表級決定 列字符集和collation。所以,c1的列字符集是latin1,它的collation是 latin1_danish_ci 例子4:數(shù)據(jù)庫+表+列定義
我們創(chuàng)建了一個沒有指定列字符集和collation的列。我們也沒有指定表級字符集和 collation。在這個條件下,MySQL向上到數(shù)據(jù)庫級決定。(數(shù)據(jù)庫的設(shè)置變?yōu)楸淼脑O(shè)置, 之后成為列的設(shè)置),所以c1的列字符集是latin2,collation是latin2_czech_ci 10.3.6 連接的字符集和Collations 一些字符集和collation和用戶對服務(wù)器的作用結(jié)合。有些在前面已經(jīng)提及了: ·服務(wù)器的字符集和collation和 character_set_server 及 collation_server 變量 的值一樣 ·默認數(shù)據(jù)庫的字符集和collation和 character_set_database 及 collation_database 變量的值一樣. 附加的字符集和collation 變量被引入用來處理服務(wù)器和客戶端之間連接得通信。每個 客戶端都有連接相關(guān)的字符集和collation變量。 想想"連接"是什么:是你連到服務(wù)器時作的事情??蛻舳送ㄟ^這條連接發(fā)送SQL語句, 比如查詢,服務(wù)器則通過這條連接給客戶端送回回應(yīng),比如查詢結(jié)果結(jié)果集合,這導致 了客戶端處理字符集和collation的一些問題,它們每個都可以按照系統(tǒng)變量來回答: ·當查詢離開客戶端的時候應(yīng)該是什么字符集的?服務(wù)器用character_set_client 這個變量來作為客戶端發(fā)送查詢所用的字符集 ·服務(wù)器端在接收到了查詢以后應(yīng)該把它翻譯到社么字符集里?對于這個,服務(wù)程序 用的是character_set_connection 和 collation_connection 這兩個變量。 它把客戶端送來的查詢從character_set_client 轉(zhuǎn)換成character_set_connection (除了latin1或者utf8 的字符串)。collation_connection 對于比較字符串非常 重要,對于列值比較字符串是沒有關(guān)系的,因為列擁有高優(yōu)先級 ·當服務(wù)程序要送回結(jié)果集合或者錯誤信息給客戶端時應(yīng)該用什么字符集? character_set_results 變量指示了這個值,這包括了列值,或者列名等結(jié)果數(shù)據(jù)。 你可以調(diào)整這些變量的值,或者就使用默認的(那樣就可以省略這節(jié)了) 有兩個語句影響連接字符集設(shè)置: SET NAMES ‘charset_name‘ SET CHARACTER SET charset_name SET NAMES 指出客戶端送出的SQL語句里是什么。因此,SET NAMES ‘cp1251‘ 就告訴服務(wù) 程序"下面將要從這個客戶端送來的信息將是使用‘cp1251‘這個字符集。這也指定了 服務(wù)程序送回的結(jié)果所用的字符集,(例如如果你用了一個select語句它會指出列值 擁有的字符集) SET NAMES ‘x‘ 語句相當于下面三個語句:
把character_set_connection 設(shè)置成x也會把collation_connection 設(shè)置成默認 collation x SET CHARACTER SET 是類似的,不過是把連接字符集和collation設(shè)置成那些默認數(shù)據(jù)庫。 SET CHARACTER SET x 語句相當于這三個語句:
當一個客戶連接,它向服務(wù)程序發(fā)送它想使用的字符集的名字,服務(wù)程序把 character_set_client, character_set_results, 和 character_set_connection 這些變量設(shè)置成那個字符集(事實上,服務(wù)程序使用字符集執(zhí)行了SET NAMES 操作) 如果你不想用默認字符集,使用 Mysql 客戶端程序不需要每次啟動時執(zhí)行SET NAMES 。 你可以在mysql 執(zhí)行語句行加上--default-character-set 這個選項,或者在你的選項 文件里加上。比如,下面的選項文件設(shè)置使你每次執(zhí)行mysql程序時把默認字符集變量 改成 koi8r:
例如:假設(shè)column1定義是 CHAR(5) CHARACTER SET latin2。如果你不用SET NAMES 或者 SET CHARACTER SET,那么對于你的 select column1 FROM t 請求,服務(wù)程序 會把column1 的所有值用連接建立時客戶端指定的字符集來回送。另一方面,如果你 用了 SET NAMES ‘latin1‘ or SET CHARACTER SET latin1 ,那么在送回結(jié)果之前, 服務(wù)程序會把 latin2 的值轉(zhuǎn)成latin1,如果里面有兩種字符集里都沒有的字符, 轉(zhuǎn)化會有損耗。 如果你不希望服務(wù)程序作任何轉(zhuǎn)換,就把character_set_results 設(shè)置成 NULL
10.3.7. 字符串文字字符集和collation 每個字符串文字都有自己的字符集和collation,不能為空 一個字符串文字可能有一個可選字符集introducer和COLLATION子句:
例如:
對于簡單語句 select ‘string‘,字符串的字符集和collation是由兩個系統(tǒng)變量 character_set_connection 和 collation_connection 定義的。 _charset_name 表達式正式情況下被叫做 introducer .它告訴分析器"下面的字符串 是使用 X 字符集的。"因為這在以前造成很多人的困擾,我們強調(diào)一下introducer 并不作任何轉(zhuǎn)換,嚴格來講并不改變字符串的值,只是一個符號。introducer 在 標準16進制文字前和數(shù)字16進制記法前都是合法的(x‘literal‘ 和 0xnnnn), 在?前面也是合法的(當在程序設(shè)計語言接口里使用預備語句時作參數(shù)替換) 例如:
MySQL 這樣決定一個文字的字符集和collation: ·如果 _X 和 COLLATE Y 都被指定了,那么字符集就是 X collation 是 Y ·如果 指定了 _X 而沒有指定 COLLATE ,那么字符集是 X collation 是 X 的默認 collation ·否則,由系統(tǒng)變量 character_set_connection 和 collation_connection 決定字符集 和collation 例如: ·一個字符集是 latin1 而collation是 latin1_german1_ci 的字符串:
·一個字符集是 latin1 以及其配套默認collation的(latin1_swedish_ci)字符串:
·一個連接默認字符集和collation的字符串:
字符集 introducer 和 COLLATE 子句是符合標準 SQL 規(guī)則的工具 10.3.8. 在 SQL 語句里使用 COLLATE 通過 COLLATE 子句,你可以在比較時覆蓋替換掉任何默認collation, COLLATE 可以用 在SQL 語句的很多部分里,這里是一些例子: ·在 ORDER BY 里:
·在 AS 里:
·在GROUP BY里 :
·在集合函數(shù)里:
·在DISTINCT里
·在where 里:
·在HAVING里:
User Comments Posted by [name withheld] on January 14 2005 2:33pm 在不同的列/表里:
在collation 之間比較列的時候能夠避免出錯信息。 10.3.9. COLLATE 子句優(yōu)先級 COLLATE子句具有高優(yōu)先級(比||高),所以下面兩個表達式是相同的:
10.3.10. BINARY 運算 BINARY 運算是COLLATE 子句的速記法,BINARY ‘x‘ 和 ‘x‘ COLLATE y 是相同的, y 是字符集 ‘x‘ 的二元collation 的名字。每個字符集都有二元 collation。例如, latin1 字符集的 collation 是latin1_bin,所以如果列 a 是latin1 字符集,下面 兩個語句有同樣效果:
10.3.11. 一些決定collation 比較棘手的情況 在絕大多數(shù)查詢里,MySQL 用什么collation來進行比較操作都是很顯而易見的,例如, 在下面的情況里,很顯然collation 應(yīng)該是"列 x 的列 collation":
但是,當卷入了多操作數(shù)時,就很難搞了,例如:
這個查詢應(yīng)該使用列 x 的collation 呢,還是使用字符串‘Y‘ 的? 標準SQL 使用被叫做``coercibility‘‘ 的規(guī)則來解決這個問題。本質(zhì)就是:因為 x 和 ‘Y‘ 都有collation ,優(yōu)先使用誰的collation呢?這很復雜,不過下面的規(guī)則能 應(yīng)付大多數(shù)情況: ·一個COLLATE 子句的 coercibility 是0 (也就是根本不coercible) ·兩個具有不同collation 的字符串連結(jié)的 coercibility 是1 ·一個列的 collation 的 coercibility 是 2 ·一個文字型的collation 的 coercibility 是3。 那些規(guī)則這樣解決含混: ·使用具有最低 coercibility 值的collation ·如果兩邊具有相同的 coercibility, 如果兩個collation 不同那就是錯誤。 例如:
COERCIBILITY() 函數(shù)可以用來判斷一個字符串表達式的coercibility:
User Comments Posted by Thierry Danard on November 5 2004 10:34pm 對于數(shù)據(jù)庫引擎來說顯而易見的排序并不是總那么顯而易見(version 4.1). 一個沒有帶類似于"select concat(mycolumn, ‘%‘) from mytable "這樣的排序指令 的查詢在"mycolumn" 和"%"的字符集不相同的情況下不會工作。 在我這里,整個數(shù)據(jù)庫使用 UTF-8, 默認情況下, ‘%‘ 假設(shè)是 latin1, causing an error to be triggered。 10.3.12. Collations Must Be for the Right Character Set 記得說過每個字符集都有一個或者多個collation,每個collation只和一個字符集關(guān)聯(lián)。 因此,下面的語句會導致錯誤,因為 latin2_bin 這個collation 和 latin1 這個字符集 不配套。
在某些情況下,在 MySQL 4.1 前工作的表達式會在MySQL 4.1以后的版本失敗, 如果你在賬號里沒有字符集和collation的話。例如,在 MySQL 4.1 前,這個語句 會這樣工作:
升級到MySQL 4.1 以后,語句失效:
發(fā)生這個的原因是username 使用utf8存儲(參看10.6節(jié)),因此, USER() 函數(shù) 和文字型字符串‘@‘具有不同的字符集(當然也是不同collation):
解決的一個方法是告訴MySQL把文字型字符串翻譯成utf8:
另一個方法是把連接的字符集和collation改成utf8,你可以使用SET NAMES ‘utf8‘ 或者直接設(shè)置兩個系統(tǒng)變量character_set_connection 和 collation_connection 的值來達到這個目的。 10.3.13. Collation 的效果的一個例子 假設(shè)表 T 里的列 X 具有這些 latin1 的列值:
并且假設(shè)這些列值可以用下列語句找回:
在這張表中列出了不同collation 的結(jié)果值的結(jié)果排序
這張表顯示了如果我們在一個 ORDER BY 子句里使用不同collation 會有什么樣的效果 的例子,導致這種不同排序結(jié)果的字符是上面有兩個點的 U,在德語里叫做U-曲音, 不過我們叫做U-分音符 ·第一列顯示了使用瑞典/芬蘭 collation 規(guī)則的 select 的結(jié)果,U-分音符 通過Y歸類 ·第二列顯示了使用德語DIN-1 規(guī)則的select 語句的結(jié)果,U-分音符通過U歸類 ·第三列顯示了使用德語DIN-2 規(guī)則的select 語句的結(jié)果,U-分音符通過UE歸類 三種不同的collation ,三種不同的結(jié)果,這是MySQL 在這里的處理。通過使用合適的 collation,你可以選擇你想要的排序次序。 |