第10章:字元編碼支援

目錄

10.1. 常規字元編碼和校對
10.2. MySQL中的字元編碼和校對
10.3. 確定預設字元編碼和校對
10.3.1. 伺服器字元編碼和校對
10.3.2. 資料庫字元編碼和校對
10.3.3. 資料表字元編碼和校對
10.3.4. 列字元編碼和校對
10.3.5. 字元編碼和校對分配示範
10.3.6. 連接字元編碼和校對
10.3.7. 字串文字字元編碼和校對
10.3.8. 在SQL語句中使用COLLATE
10.3.9. COLLATE子句優先
10.3.10. BINARY操作符
10.3.11. 校對確定較為複雜的一些特殊情況
10.3.12. 校對必須適合字元編碼
10.3.13. 校對效果的示範
10.4. 字元編碼支援影響到的操作
10.4.1. 結果字串
10.4.2. CONVERT()
10.4.3. CAST()
10.4.4. SHOW語句
10.5. Unicode支援
10.6. 用於元數據的UTF8
10.7. 與其它DBMS的相容性
10.8. 新字元編碼配置檔案格式
10.9. 國家特有字元編碼
10.10. MySQL支援的字元編碼和校對
10.10.1. Unicode字元編碼
10.10.2. 西歐字元編碼
10.10.3. 中歐字元編碼
10.10.4. 南歐與中東字元編碼
10.10.5. 波羅的海字元編碼
10.10.6. 西裡爾字元編碼
10.10.7. 亞洲字元編碼

本章討論以下主題:

·         什麼是字元編碼和校對規則?

·         多級預設系統

·         字元編碼語法

·         相關函數和運算

·         Unicode支援

·         每個字元編碼和校對規則的含義

MySQL5.1中的字元編碼支援包括在MyISAMMEMORYInnoDB儲存引擎中。

10.1. 常規字元編碼和校對

字元編碼是一套符號和編碼。校對規則是在字元編碼內用於比較字元的一套規則。讓我們使用一個假想字元編碼的例子來區別清楚。

假設我們有一個字母資料表使用了四個字母:『A』、『B』、『a』、『b』。我們為每個字母賦予一個數值:『A=0,『B= 1,『a= 2,『b= 3。字母『A』是一個符號,數字0是『A』的編碼,這四個字母和它們的編碼組合在一起是一個字元編碼

假設我們希望比較兩個字串的值:『A』和『B』。比較的最簡單的方法是搜尋編碼:『A』為0,『B』為1。因為0 小於1,我們可以說『A』小於『B』。我們做的僅僅是在我們的字元編碼上應用了一個 校對規則。校對規則是一套規則(在這種情況下僅僅是一套規則):「對編碼進行比較。」我們稱這種全部可能的規則中的最簡單的 校對規則為一個binary(二元)校對規則。

但是,如果我們希望小寫字母和大寫字母是等價的,應該怎樣?那麼,我們將至少有兩個規則:(1)把小寫字母『a』和『b』視為與『A』和『B』等價;(2)然後比較編碼。我們稱這是一個大小寫不敏感的 校對規則。比二元校對規則複雜一些。

在實際生活中,大多數字元編碼有許多字元:不僅僅是『A』和『B』,而是整個字母資料表,有時候有許多種字母資料表,或者一個東方的使用上千個字元的書寫系統,還有許多特殊符號和標點符號。並且在實際生活中,大多數 校對規則有許多個規則:不僅僅是大小寫不敏感,還包括重音符不敏感(「重音符」 是附屬於一個字母的符號,像德語的『O』符號)和多字節映射(例如,作為規則『O=OE』就是兩個德語 校對規則的一種)。

MySQL5.1能夠做這些事情:

·         使用多種字元編碼來儲存字串

·         使用多種校對規則來比較字串

·         在同一台伺服器、同一個資料庫或甚至在同一個資料表中使用不同字元編碼或校對規則來混合字串

·         允許定義任何級別的字元編碼和校對規則

在這些方面,MySQL5.1不僅比MySQL4.1以前的版本靈活得多,而且比其它大多數資料庫管理系統超前許多。但是,為了有效地使用這些功能,您需要瞭解哪些字元編碼和 校對規則是可用的,怎樣改變預設值,以及它們怎樣影響字元操作符和字串函數的行為。

10.2. MySQL中的字元編碼和校對

MySQL伺服器能夠支援多種字元編碼。可以使用SHOW CHARACTER SET語句列出可用的字元編碼:

mysql> SHOW CHARACTER SET;
+----------+-----------------------------+---------------------+--------+
| Charset  | Description                 | Default collation   | Maxlen |
+----------+-----------------------------+---------------------+--------+
| big5     | Big5 Traditional Chinese    | big5_chinese_ci     |      2 |
| dec8     | DEC West European           | dec8_swedish_ci     |      1 |
| cp850    | DOS West European           | cp850_general_ci    |      1 |
| hp8      | HP West European            | hp8_english_ci      |      1 |
| koi8r    | KOI8-R Relcom Russian       | koi8r_general_ci    |      1 |
| latin1   | cp1252     West European    | latin1_swedish_ci   |      1 |
| latin2   | ISO 8859-2 Central European | latin2_general_ci   |      1 |
| swe7     | 7bit Swedish                | swe7_swedish_ci     |      1 |
| ascii    | US ASCII                    | ascii_general_ci    |      1 |
| ujis     | EUC-JP Japanese             | ujis_japanese_ci    |      3 |
| sjis     | Shift-JIS Japanese          | sjis_japanese_ci    |      2 |
| hebrew   | ISO 8859-8 Hebrew           | hebrew_general_ci   |      1 |
| tis620   | TIS620 Thai                 | tis620_thai_ci      |      1 |
| euckr    | EUC-KR Korean               | euckr_korean_ci     |      2 |
| koi8u    | KOI8-U Ukrainian            | koi8u_general_ci    |      1 |
| gb2312   | GB2312 Simplified Chinese   | gb2312_chinese_ci   |      2 |
| greek    | ISO 8859-7 Greek            | greek_general_ci    |      1 |
| cp1250   | Windows Central European    | cp1250_general_ci   |      1 |
| gbk      | GBK Simplified Chinese      | gbk_chinese_ci      |      2 |
| latin5   | ISO 8859-9 Turkish          | latin5_turkish_ci   |      1 |
...

(完整列資料表參見10.10節,「MySQL支援的字元編碼和校對」。)

任何一個給定的字元編碼至少有一個校對規則。它可能有幾個校對規則。

要想列出一個字元編碼的校對規則,使用SHOW COLLATION語句。例如,要想查看latin1(「西歐ISO-8859-1)字元編碼的 校對規則,使用下面的語句搜尋那些名字以latin1開頭的 校對規則:

mysql> SHOW COLLATION LIKE 'latin1%';
+---------------------+---------+----+---------+----------+---------+
| Collation           | Charset | Id | Default | Compiled | Sortlen |
+---------------------+---------+----+---------+----------+---------+
| latin1_german1_ci   | latin1  |  5 |         |          |       0 |
| latin1_swedish_ci   | latin1  |  8 | Yes     | Yes      |       1 |
| latin1_danish_ci    | latin1  | 15 |         |          |       0 |
| latin1_german2_ci   | latin1  | 31 |         | Yes      |       2 |
| latin1_bin          | latin1  | 47 |         | Yes      |       1 |
| latin1_general_ci   | latin1  | 48 |         |          |       0 |
| latin1_general_cs   | latin1  | 49 |         |          |       0 |
| latin1_spanish_ci   | latin1  | 94 |         |          |       0 |
+---------------------+---------+----+---------+----------+---------+

latin1校對規則有下面的含義:

校對規則

含義

latin1_german1_ci

德國DIN-1

latin1_swedish_ci

瑞典/芬蘭

latin1_danish_ci

丹麥/挪威

latin1_german2_ci

德國 DIN-2

latin1_bin

符合latin1編碼的二進制

latin1_general_ci

多種語言(西歐)

latin1_general_cs

多種語言(西歐ISO),大小寫敏感

latin1_spanish_ci

現代西班牙

校對規則一般有這些特徵:

·         兩個不同的字元編碼不能有相同的校對規則。

·         每個字元編碼有一個預設校對規則。例如,latin1預設校對規則是latin1_swedish_ci

·         存在校對規則命名約定:它們以其相關的字元編碼名開始,通常包括一個語言名,並且以_ci(大小寫不敏感)、_cs(大小寫敏感)或_bin(二元)結束。

10.3. 確定預設字元編碼和校對

字元編碼和校對規則有4個級別的預設設置:伺服器級、資料庫級、資料表級和連接級。以下描述可能顯得複雜,但是在實際應用中可以發現使用多種級別會使結果自然而明顯。

10.3.1. 伺服器字元編碼和校對

MySQL伺服器有一個伺服器字元編碼和一個伺服器校對規則,它們均不能設置為空。

MySQL按照如下方法確定伺服器字元編碼和伺服器校對規則:

·         當伺服器啟動時根據有效的選項設置

·         根據運行時的設定值

在伺服器級別,確定方法很簡單。當啟動mysqld時,根據使用的初始選項設置來確定伺服器字元編碼和 校對規則。可以使用--default-character-set設置字元編碼,並且可以在字元編碼後面為 校對規則新增--default-collation。如果沒有指定一個字元編碼,那就與--default-character-set=latin1相同。如果您僅指定了一個字元編碼(例如,latin1),但是沒有指定一個 校對規則,那就與--default-charset=latin1 --default-collation=latin1_swedish_ci相同因為latin1_swedish_cilatin1預設校對規則。因此,以下三個命令有相同的效果:

shell> mysqld

shell> mysqld --default-character-set=latin1

shell> mysqld --default-character-set=latin1 \

           --default-collation=latin1_swedish_ci

更改設定值的一個方法是通過重新編譯。如果希望在從源程式構建時更改預設伺服器字元編碼和校對規則,使用:--with-charset--with-collation作為configure的參量。例如:

shell> ./configure --with-charset=latin1

或者:

shell> ./configure --with-charset=latin1 \

           --with-collation=latin1_german1_ci

mysqldconfigure都驗證字元編碼/校對規則組合是否有效。如果無效,每個程式都顯示一個錯誤訊息,然後終止。

當前的伺服器字元編碼和校對規則可以用作character_set_servercollation_server系統變數的值。在運行時能夠改變這些變數的值。

10.3.2. 資料庫字元編碼和校對

每一個資料庫有一個資料庫字元編碼和一個資料庫校對規則,它不能夠為空。CREATE DATABASEALTER DATABASE語句有一個可選的子句來指定資料庫字元編碼和校對規則:
CREATE DATABASE db_name
    [[DEFAULT] CHARACTER SET charset_name]
    [[DEFAULT] COLLATE collation_name]
 
ALTER DATABASE db_name
    [[DEFAULT] CHARACTER SET charset_name]
    [[DEFAULT] COLLATE collation_name]

例如:

CREATE DATABASE db_name
    DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;

MySQL這樣選擇資料庫字元編碼和資料庫校對規則:

·         如果指定了CHARACTER SET XCOLLATE Y,那麼採用字元編碼X和校對規則Y

·         如果指定了CHARACTER SET X而沒有指定COLLATE Y,那麼採用CHARACTER SET XCHARACTER SET X的預設校對規則。

·         否則,採用伺服器字元編碼和伺服器校對規則。

MySQLCREATE DATABASE ... DEFAULT CHARACTER SET ...語法與標準SQLCREATE SCHEMA ... CHARACTER SET ...語法類似。因此,可以在同一個MySQL伺服器上建立使用不同字元編碼和 校對規則的資料庫。

如果在CREATE TABLE語句中沒有指定資料表字元編碼和校對規則,則使用資料庫字元編碼和校對規則作為預設值。它們沒有其它目的。

預設資料庫的字元編碼和校對規則可以用作character_set_databasecollation_database系統變數。無論何時預設資料庫更改了,伺服器都設置這兩個變數的值。如果沒有 預設資料庫,這兩個變數與相應的伺服器級別的變數(character_set_servercollation_server)具有相同的值。

10.3.3. 資料表字元編碼和校對

每一個資料表有一個資料表字元編碼和一個校對規則,它不能為空。為指定資料表字元編碼和校對規則,CREATE TABLE ALTER TABLE語句有一個可選的子句:
CREATE TABLE tbl_name (column_list)
    [DEFAULT CHARACTER SET charset_name [COLLATE collation_name]]
 
ALTER TABLE tbl_name
    [DEFAULT CHARACTER SET charset_name] [COLLATE collation_name]

例如:

CREATE TABLE t1 ( ... )

DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci;

MySQL按照下面的方式選擇資料表字元編碼和 校對規則:

·         如果指定了CHARACTER SET XCOLLATE Y,那麼採用CHARACTER SET XCOLLATE Y

·         如果指定了CHARACTER SET X而沒有指定COLLATE Y,那麼採用CHARACTER SET XCHARACTER SET X的預設校對規則。

·         否則,採用伺服器字元編碼和伺服器校對規則。

如果在列定義中沒有指定列字元編碼和校對規則,則預設使用資料表字元編碼和校對規則。資料表字元編碼和校對規則是MySQL的延伸;在標準SQL中沒有。

10.3.4. 列字元編碼和校對

每一個「字元」列(即,CHARVARCHARTEXT類型的列)有一個列字元編碼和一個列 校對規則,它不能為空。列定義語法有一個可選子句來指定列字元編碼和校對規則:
col_name {CHAR | VARCHAR | TEXT} (col_length)
    [CHARACTER SET charset_name [COLLATE collation_name]]

例如:

CREATE TABLE Table1

(

    column1 VARCHAR(5) CHARACTER SET latin1 COLLATE latin1_german1_ci

);

MySQL按照下面的方式選擇列字元編碼和校對規則:

·         如果指定了CHARACTER SET XCOLLATE Y,那麼採用CHARACTER SET XCOLLATE Y

·         如果指定了CHARACTER SET X而沒有指定COLLATE Y,那麼採用CHARACTER SET XCHARACTER SET X的預設校對規則。

·         否則,採用資料表字元編碼和伺服器校對規則。

CHARACTER SETCOLLATE子句是標準的SQL

10.3.5. 字元編碼和校對分配示範

以下例子顯示了MySQL怎樣確定預設字元編碼和校對規則。

示範1:資料表和列定義

CREATE TABLE t1
(
    c1 CHAR(10) CHARACTER SET latin1 COLLATE latin1_german1_ci
) DEFAULT CHARACTER SET latin2 COLLATE latin2_bin;

在這裡我們有一個列使用latin1字元編碼和latin1_german1_ci校對規則。是顯式的定義,因此簡單明瞭。需要注意的是,在一個latin2資料表中儲存一個latin1列不會存在問題。

示範2:資料表和列定義

CREATE TABLE t1
(
    c1 CHAR(10) CHARACTER SET latin1
) DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci;

這次我們有一個列使用latin1字元編碼和一個預設校對規則。儘管它顯得自然,預設校對規則卻不是資料表級。相反,因為latin1的預設校對規則總是latin1_swedish_ci,列c1有一個校對規則latin1_swedish_ci(而不是latin1_danish_ci)。

示範3:資料表和列定義

CREATE TABLE t1
(
    c1 CHAR(10)
) DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci;

我們有一個列使用一個預設字元編碼和一個預設校對規則。在這種情況下,MySQL搜尋資料表級別來確定列字元編碼和 校對規則。因此,列c1的字元編碼是latin1,它的 校對規則是latin1_danish_ci

示範4:資料庫、資料表和列定義

CREATE DATABASE d1
    DEFAULT CHARACTER SET latin2 COLLATE latin2_czech_ci;
USE d1;
CREATE TABLE t1
(
    c1 CHAR(10)
);

我們建立了一個沒有指定字元編碼和校對規則的列。我們也沒有指定資料表級字元編碼和校對規則。在這種情況下,MySQL搜尋資料庫級的相關設置。(資料庫的設置變為資料表的設置,其後變為列的設置。)因此,列c1的字元編碼為是latin2它的 校對規則是latin2_czech_ci

10.3.6. 連接字元編碼和校對

一些字元編碼和校對規則系統變數與客戶端和伺服器的交互有關。在前面的章節中已經提到過部分內容:

·         伺服器字元編碼和校對規則可以用作character_set_servercollation_server變數的值。

·         預設資料庫的字元編碼和校對規則可以用作character_set_databasecollation_database變數的值。

在客戶端和伺服器的連接處理中也涉及了字元編碼和校對規則變數。每一個客戶端有一個連接相關的字元編碼和校對規則變數。

考慮什麼是一個「連接」:它是連接伺服器時所作的事情。客戶端發送SQL語句,例如查詢,通過連接發送到伺服器。伺服器通過連接發送響應給客戶端,例如結果集。對於客戶端連接,這樣會導致一些關於連接的字元編碼和 校對規則的問題,這些問題均能夠通過系統變數來解決:

·         當查詢離開客戶端後,在查詢中使用哪種字元編碼?

伺服器使用character_set_client變數作為客戶端發送的查詢中使用的字元編碼。

·         伺服器接收到查詢後應該轉換為哪種字元編碼?

轉換時,伺服器使用character_set_connectioncollation_connection系統變數。它將客戶端發送的查詢從character_set_client系統變數轉換到character_set_connection(除非字串文字具有象_latin1_utf8的引介詞)。collation_connection對比較文字字串是重要的。對於列值的字串比較,它不重要,因為列具有更高的 校對規則優先級。

·         伺服器發送結果集或返回錯誤訊息到客戶端之前應該轉換為哪種字元編碼?

character_set_results變數指示伺服器返回查詢結果到客戶端使用的字元編碼。包括結果數據,例如列值和結果元數據(如列名)。

您能夠調整這些變數的設置,或可以依賴預設值(這樣,您可以跳過本章)。

有兩個語句影響連接字元編碼:

SET NAMES 'charset_name'
SET CHARACTER SET charset_name

SET NAMES顯示客戶端發送的SQL語句中使用什麼字元編碼。因此,SET NAMES 'cp1251'語句告訴伺服器「將來從這個客戶端傳來的訊息採用字元編碼cp1251。它還為伺服器發送回客戶端的結果指定了字元編碼。(例如,如果您使用一個SELECT語句它資料表示列值使用了什麼字元編碼。)

SET NAMES 'x'語句與這三個語句等價:

mysql> SET character_set_client = x;
mysql> SET character_set_results = x;
mysql> SET character_set_connection = x;

x設置為character_set_connection也就設置了collation_connectionx的預設校對規則。

SET CHARACTER SET語句是類似的,但是為 預設資料庫設置連接字元編碼和校對規則。SET CHARACTER SET x語句與這三個語句等價:

mysql> SET character_set_client = x;
mysql> SET character_set_results = x;
mysql> SET collation_connection = @@collation_database;

當一個客戶端連接時,它向伺服器發送希望使用的字元編碼名稱。伺服器為那個字元編碼設置character_set_clientcharacter_set_resultscharacter_set_connection變數。(實際上,伺服器為使用該字元編碼執行一個SET NAMES操作。)

對於mysql客戶端,如果您希望使用與預設字元編碼不同的字元編碼,不需要每次啟動時執行SET NAMES語句。可以在mysql語句行中或者選項檔案中新增一個--default-character-set選項設置。例如,您每次運行mysql時,以下的選項檔案設置把三個字元編碼變數修改為koi8r

[mysql]

default-character-set=koi8r

例如:假設column1定義為CHAR(5) CHARACTER SET latin2。如果沒有設定SET NAMESSET CHARACTER SET,那麼對於SELECT column1 FROM t,當連接後,伺服器使用客戶端指定的字元編碼返回列column1的所有值。另一方面,如果您設定SET NAMES 'latin1'SET CHARACTER SET latin1,那麼發送結果之前,伺服器轉換latin2值到latin1。轉換可能會丟失那些不屬於兩種字元編碼的字元。

如果不希望伺服器執行任何轉換,設置character_set_resultsNULL

mysql> SET character_set_results = NULL;

10.3.7. 字串文字字元編碼和校對

每一字串字元文字有一個字元編碼和一個校對規則,它不能為空。

一個字串文字可能有一個可選的字元編碼引介詞和COLLATE子句:

[_charset_name]'string' [COLLATE collation_name]

例如:

SELECT 'string';
SELECT _latin1'string';
SELECT _latin1'string' COLLATE latin1_danish_ci;

對於簡單的語句SELECT 'string',字串使用由character_set_connectioncollation_connection系統變數定義的字元編碼和 校對規則。

_charset_name資料表達式正式稱做一個引介詞。它告訴解析程式,「後面將要出現的字串使用字元編碼X」因為以前人們對此感到困惑,我們強調引介詞不導致任何轉換; 它僅是一個符號,不改變字串的值。引介詞在標準十六進制字母和數字十六進制符號(x'literal'0xnnnn)中是合法的,以及(當在一個編程語言接口中使用預處理的語句時進行參數替換)。

例如:

SELECT _latin1 x'AABBCC';
SELECT _latin1 0xAABBCC;
SELECT _latin1 ?;

MySQL這樣確定一個文字字元編碼和校對規則:

·         如果指定了CHARACTER SET XCOLLATE Y,那麼使用CHARACTER SET XCOLLATE Y

·         如果指定了CHARACTER SET X而沒有指定COLLATE Y,那麼使用CHARACTER SET XCHARACTER SET X的預設校對規則。

·         否則,使用通過character_set_connection collation_connection系統變數給出的字元編碼和 校對規則。

例如:

·         使用latin1字元編碼和latin1_german1_ci校對規則的字串:

·                SELECT _latin1'Muller' COLLATE latin1_german1_ci;

·         使用latin1字元編碼和其預設校對規則的字串(即,latin1_swedish_ci):

·                SELECT _latin1'Muller';

·         使用連接預設字元編碼和校對規則的字串:

·                SELECT 'Muller';

字元編碼引介詞和COLLATE子句是根據標準SQL規範實現的。

10.3.8. 在SQL語句中使用COLLATE

  • 使用COLLATE子句,能夠為一個比較覆蓋任何預設校對規則。COLLATE可以用於多種SQL語句中。下面是一些例子:

    ·         使用ORDER BY

    ·                SELECT k
    ·                FROM t1
    ·                ORDER BY k COLLATE latin1_german2_ci;

    ·         使用AS

    ·                SELECT k COLLATE latin1_german2_ci AS k1
    ·                FROM t1
    ·                ORDER BY k1;

    ·         使用GROUP BY

    ·                SELECT k
    ·                FROM t1
    ·                GROUP BY k COLLATE latin1_german2_ci;

    ·         使用聚合函數:

    ·                SELECT MAX(k COLLATE latin1_german2_ci)
    ·                FROM t1;

    ·         使用DISTINCT

    ·                SELECT DISTINCT k COLLATE latin1_german2_ci
    ·                FROM t1;

    ·         使用WHERE

    ·                     SELECT *
    ·                     FROM t1
    ·                     WHERE _latin1 'Muller' COLLATE latin1_german2_ci = k;
    ·                     SELECT *
    ·                     FROM t1
    ·                     WHERE k LIKE _latin1 'Muller' COLLATE latin1_german2_ci;

    ·         使用HAVING

    ·                SELECT k
    ·                FROM t1
    ·                GROUP BY k
    ·                HAVING k = _latin1 'Muller' COLLATE latin1_german2_ci;

10.3.9. COLLATE子句優先

COLLATE子句有較高的優先級(高於||),因此下面兩個資料表達式是等價的:

x || y COLLATE z
x || (y COLLATE z)

10.3.10. BINARY操作符

BINARY操作符是COLLATE子句的一個速記符。BINARY 'x'等價與'x' COLLATE y,這裡y是字元編碼'x'二元 校對規則的名字。每一個字元編碼有一個二元校對規則。例如,latin1字元編碼的二元 校對規則是latin1_bin,因此,如果列a是字元編碼latin1,以下兩個語句有相同效果:
SELECT * FROM t1 ORDER BY BINARY a;
SELECT * FROM t1 ORDER BY a COLLATE latin1_bin;

10.3.11. 校對確定較為複雜的一些特殊情況

在絕大多數查詢中,MySQL使用哪種校對規則進行比較是很顯然的。例如,在下列情況中,校對規則明顯的是「x的列校對規則」:

SELECT x FROM T ORDER BY x;
SELECT x FROM T WHERE x = x;
SELECT DISTINCT x FROM T;

但是,當涉及多個操作數時,可能不明確。例如:

SELECT x FROM T WHERE x = 'Y';

這個查詢應該使用列x的 校對規則,還是字串文字'Y'的 校對規則?

標準化SQL使用「可壓縮性」規則解決這種問題。基本上,這個意思是:既然x'Y'都有 校對規則,哪個校對規則優先?這可能比較難解決,但是以下規則適合大多數情況:

·         一個外在的COLLATE子句可壓縮性是0(根本不能壓縮。)

·         使用不同校對規則的兩個字串連接的可壓縮性是1

·         列校對規則的可壓縮性是2

·         系統常數」(如USER()VERSION()函數返回的字串)可壓縮性是3

·         文字規則的可壓縮性是4

·         NULL或從NULL派生的資料表達式的可壓縮性是 5

上述可壓縮性值是MySQL5.1當前所用的。

這樣上述規則可以模糊解決:

·         使用最低的可壓縮性值的校對規則。

·         如果兩側有相同的可壓縮性,那麼如果校對規則不同則發生錯誤。

例如:

column1 = 'A'

使用column1的校對規則

column1 = 'A' COLLATE x

使用'A'的校對規則

column1 COLLATE x = 'A' COLLATE y

錯誤

使用COERCIBILITY()函數確定一個字串資料表達式的可壓縮性:

mysql> SELECT COERCIBILITY('A' COLLATE latin1_swedish_ci);
        -> 0
mysql> SELECT COERCIBILITY(VERSION());
        -> 3
mysql> SELECT COERCIBILITY('A');
        -> 4

12.9.3節,「訊息函數」

沒有系統常數或可忽略的壓縮性。函數如USER()的可壓縮性是2而不是3,文字的可壓縮性是3而不是4

10.3.12. 校對必須適合字元編碼

請注意每個字元編碼有一個或多個校對規則,並且每個校對規則只能屬於一個字元編碼。因此,以下語句會產生一個錯誤訊息,因為校對規則latin2_bin對於字元編碼latin1非法:

mysql> SELECT _latin1 'x' COLLATE latin2_bin;

ERROR 1251: COLLATION 'latin2_bin' is not valid

for CHARACTER SET 'latin1'

10.3.13. 校對效果的示範

假設資料表T中的列X有這些latin1列值:

Muffler

Muller

MX Systems

MySQL

假設使用下面的語句獲取列值:

SELECT X FROM T ORDER BY X COLLATE collation_name;

使用不同校對規則的列值結果排序見下資料表:

latin1_swedish_ci

latin1_german1_ci

latin1_german2_ci

Muffler

Muffler

Muller

MX系統

Muller

Muffler

Muller

MX系統

MX系統

MySQL

MySQL

MySQL

本資料表顯示了我們在ORDER BY字句中使用不同所校對規則的效果的示範。在本例中導致不同排序的字元是上面帶有兩個圓點的Uu),它在德語中發音為"U-umlaut"

·         第一列顯示的是使用瑞典/芬蘭校對規則的SELECT語句的結果,它被稱作U-umlaut使用Y排序。

·         第二列顯示的是使用德語DIN-1校對規則的SELECT語句的結果,它被稱作U-umlaut使用U排序。

·         第三列顯示的是使用德語DIN-2校對規則的SELECT語句的結果,它被稱作U-umlaut使用UE排序。

10.4. 字元編碼支援影響到的操作

本節討論在MySQL5.1中考慮到字元編碼訊息的操作。

10.4.1. 結果字串

MySQL中有許多操作符和函數可以返回字串。本節回答這個問題:返回的字串使用什麼字元編碼和 校對規則?

對於簡單的函數,即接收字串輸入然後返回一個字串結果作為輸出的函數,輸出的字元編碼和校對規則與原始輸入的相同。例如,UPPERX返回一個字串,其字元和 校對規則與X相同。類似的函數還有INSTR()LCASE()LOWER()LTRIM()MID()REPEAT()REPLACE()REVERSE()RIGHT()RPAD()RTRIM()SOUNDEX()SUBSTRING()TRIM()UCASE()UPPER()。(還需要注意:REPLACE()函數不同於其它函數,它總是忽略輸入字串的 校對規則,並且進行大小寫不敏感的比較。)

對於合併多個字串輸入並且返回單個字串輸出的運算,應用標準SQL「聚合規則」:

·         如果存在顯式的校對規則X,那麼使用X

·         如果存在顯式的校對規則XY,那麼產生一個錯誤。

·         否則,如果全部校對規則是X,那麼使用X

·         其它情況,結果沒有校對規則。

例如,使用CASE ... WHEN a THEN b WHEN b THEN c COLLATE X END。結果校對規則是X。對於CASEUNION||CONCAT()ELT()GREATEST()IF()LEAST()情況相同。

對於轉換為字元數據的運算,從運算得到的結果字串的字元編碼和校對規則由character_set_connectioncollation_connection系統變數定義。這適用於CAST()CHAR()CONV()FORMAT()HEX()SPACE()函數。

10.4.2. CONVERT()

CONVERT()提供一個在不同字元編碼之間轉換數據的方法。語法是:
CONVERT(expr USING transcoding_name)

MySQL中,轉換代碼名與相應的字元編碼名相同。

例子:

SELECT CONVERT(_latin1'Muller' USING utf8);
INSERT INTO utf8table (utf8column)
    SELECT CONVERT(latin1field USING utf8) FROM latin1table;

CONVERT(... USING ...)根據標準SQL規範實施。

在傳統SQL模式中,如果您轉換一個「0」日期字串到日期類型,CONVERT()函數返回NULL。在MySQL5.1中還產生一條警告。

10.4.3. CAST()

您也可以使用CAST()函數將一個字串轉換到一個不同的字元編碼。語法是:

CAST(character_string AS character_data_type CHARACTER SET charset_name)

例如:

SELECT CAST(_latin1'test' AS CHAR CHARACTER SET utf8);

如果使用CAST()時沒有指定CHARACTER SET,結果字元編碼和校對規則通過character_set_connection collation_connection系統變數定義。如果用CAST()並帶有CHARACTER SET X選項,那麼結果字元編碼和校對規則是X和其 預設的校對規則。

您可能不能在CAST()中使用COLLATE子句,但是您可以在外部使用它。也就是說,不是CAST(... COLLATE ...),而是CAST(...) COLLATE ...

例如:

SELECT CAST(_latin1'test' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin;

在傳統SQL模式中,如果您轉換一個「0」日期字串到日期類型,CAST()函數返回NULL。在MySQL5.1中還產生一條警告。

10.4.4. SHOW語句

一些SHOW語句提供額外的字元編碼訊息。這些語句包括SHOW CHARACTER SETSHOW COLLATIONSHOW CREATE DATABASESHOW CREATE TABLESHOW COLUMNS

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 |

+---------+-----------------------------+-------------------+--------+

13.5.4.1節,「SHOW CHARACTER SET語法」

SHOW COLLATION語句的輸出包括全部可用的字元編碼。它帶有一個可選的LIKE子句來指示匹配哪些 校對規則名。例如:

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

13.5.4.2節,「SHOW COLLATION語法」

SHOW CREATE DATABASE語句顯示建立給定資料庫的CREATE DATABASE語句。結果包括全部資料庫選項。支援DEFAULT CHARACTER SETCOLLATE。全部資料庫選項儲存在命名為db.Opt的文本檔案中,該檔案能夠在資料庫目錄中找到。

mysql> SHOW CREATE DATABASE test;
+----------+-----------------------------------------------------------------+
| Database | Create Database                                                 |
+----------+-----------------------------------------------------------------+
| test     | CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */ |
+----------+-----------------------------------------------------------------+

13.5.4.4節,「SHOW CREATE DATABASE語法」

SHOW CREATE TABLESHOW CREATE DATABASE相似,但是顯示建立給定資料庫的CREATE TABLE語句。列定義顯示任何字元編碼規格,並且資料表選項包括字元編碼訊息。

13.5.4.5節,「SHOW CREATE TABLE語法」

當以SHOW FULL COLUMNS使用時,SHOW COLUMNS語句顯示資料表中列的校對規則。具有CHARVARCHARTEXT數據類型的列有非NULL的 校對規則。數值列和其它非字元類型的列有NULL校對規則。例如:

mysql> SHOW FULL COLUMNS FROM person\G

*************************** 1. row ***************************

     Field: id

      Type: smallint(5) unsigned

 Collation: NULL

      Null: NO

       Key: PRI

   Default: NULL

     Extra: auto_increment

Privileges: select,insert,update,references

   Comment:

*************************** 2. row ***************************

     Field: name

      Type: char(60)

 Collation: latin1_swedish_ci

      Null: NO

       Key:

   Default:

     Extra:

Privileges: select,insert,update,references

   Comment:

字元編碼不是顯示的部分。(字元編碼名隱含在校對規則名中。)

13.5.4.3節,「SHOW COLUMNS語法」

10.5. Unicode支援

MySQL 5.1支援兩種字元編碼以保存Unicode數據:

·         ucs2UCS-2 Unicode字元編碼。

·         utf8Unicode字元編碼的UTF8編碼。

UCS-2(二進制Unicode資料表示法)中,每一個字元用一個雙字節的Unicode編碼來資料表示的,第一個字節資料表示重要的意義。例如:"LATIN CAPITAL LETTER A"Unicode編碼是0x0041,它按順序儲存為兩個字節:0x00 0x41"CYRILLIC SMALL LETTER YERU"Unicode 0x044B)順序儲存為兩個字節:0x04 0x4B。對於Unicode字元和它們的編碼,請參見Unicode 主頁

當前,UCS-2還不能夠用作為客戶端字元編碼,這意味著SET NAMES 'ucs2'不起作用。

UTF8字元編碼(轉換Unicode資料表示)是儲存Unicode數據的一種可選方法。它根據 RFC 3629執行。UTF8字元編碼的思想是不同Unicode字元採用變長字節序列編碼:

·         基本拉丁字母、數字和標點符號使用一個字節。

·         大多數的歐洲和中東手寫字母適合兩個字節序列:延伸的拉丁字母(包括發音符號、長音符號、重音符號、低音符號和其它音符)、西裡爾字母、希臘語、亞美尼亞語、希伯來語、阿拉伯語、敘利亞語和其它語言。

·         韓語、中文和日本象形文字使用三個字節序列。

RFC 3629說明了採用一到四個字節的編碼序列。當前,MySQLUTF8不支援四個字節。(UTF8編碼的舊標準是由RFC 2279給出,它描述了從一到六個字節的UTF8編碼序列。RFC 3629補充了作廢的RFC 2279;因此,不再使用5個字節和6個字節的編碼序列。)

提示:使用UTF8時為了節省空間,使用VARCHAR而不要用CHAR。否則,MySQL必須為一個CHAR(10) CHARACTER SET utf8列預備30個字節,因為這是可能的最大長度。

10.6. 用於元數據的UTF8

元數據是「關於數據的數據」。描述資料庫的任何數據—作為資料庫內容的對立面—是元數據。因此,列名、資料庫名、帳號、版本名以及從SHOW語句得到的結果中的大部分字串是元數據。還包括INFORMATION_SCHEMA資料庫中的資料表中的內容,因為定義的那些資料表儲存關於資料庫對象的訊息。

元數據資料表述必須滿足這些需求:

·         全部元數據必須在同一字元編碼內。否則,對INFORM一個TION_SCHEMA資料庫中的資料表執行的SHOW命令和SELECT查詢不能正常工作,因為這些運算結果中的同一列的不同行將會使用不同的字元編碼。

·         元數據必須包括所有語言的所有字元。否則,用戶將不能夠使用它們自己的語言來命名列和資料表。

為了滿足這兩個需求,MySQL使用Unicode字元編碼儲存元數據,即UTF8。如果您從不使用重音字元,這不會導致任何破壞。但如果您使用重音字元,應該注意的是元數據是用UTF8儲存。

這意味著,USER()CURRENT_USER()DATABASE()VERSION()函數的返回值被 預設設置為UTF8字元編碼,這與同義函數如SESSION_USER() SYSTEM_USER()的結果相同。

伺服器將character_set_system系統變數設置為元數據字元編碼的名:

mysql> SHOW VARIABLES LIKE 'character_set_system';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| character_set_system | utf8  |
+----------------------+-------+

儲存元數據使用Unicode並不意味著列頭和DESCRIBE函數的結果預設在character_set_system字元編碼中。當您使用SELECT column1 FROM t語句時,名字為column1的列從伺服器返回客戶端並使用由SET NAMES語句確定的字元編碼。更明確地說,使用的字元編碼是由character_set_results系統變數的值確定的。如果這個系統變數設置為NULL,不執行字元轉換,伺服器使用最初的字元編碼(字元編碼由character_set_system系統變數設置)返回元數據。

如果您希望伺服器不使用UTF8字元編碼返回元數據結果,那麼使用SET NAMES語句強制伺服器執行字元編碼轉換(見10.3.6節,「連接字元編碼和校對」),或者在客戶端執行轉換。在客戶端執行轉換效率較高,但這種選項並不能使用於全部客戶端。

如果您正在一個語句中使用(例如)USER()函數進行比較或賦值,不要擔心。MySQL為您執行一些原子轉換。

SELECT * FROM Table1 WHERE USER() = latin1_column;

這是可以的,因為在比較之前latin1_column列的內容會自動轉換到UTF8

INSERT INTO Table1 (latin1_column) SELECT USER();

這是可以的,因為賦值之前USER()函數返回的內容自動轉換為latin1。至今,自動轉換沒有全部實施,但是以後的版本中應該工作正常。

儘管自動轉換不屬於SQL標準,SQL標準化文檔中說每一個字元編碼是(根據支援的字元)Unicode的「子集」。因此,一個知名的原則是,「適用超集的字元編碼能夠應用於其子集」,我們相信Unicode的 校對規則能夠應用於非Unicode字串的比較。

註釋:在MySQL5.1中,errmsg.txt檔案全部使用UTF8。客戶端字元編碼的轉換是自動進行的,如同元數據。

10.7. 與其它DBMS的相容性

對於MaxDB相容性,下面兩個語句是相同的:

CREATE TABLE t1 (f1 CHAR(n) UNICODE);
CREATE TABLE t1 (f1 CHAR(n) CHARACTER SET ucs2);

10.8. 新字元編碼配置檔案格式

字元編碼配置儲存在XML檔案中,一個字元編碼對應一個檔案。

10.9. 國家特有字元編碼

ANSI SQL定義了NCHAR或者NATIONAL CHAR作為一個方法來指示CHAR類型的列應該使用某些預定義的字元編碼。MySQL5.1使用utf8作為預定義的字元編碼。例如,這些列類型聲明是等價的:
CHAR(10) CHARACTER SET utf8
NATIONAL CHARACTER(10)
NCHAR(10)

下面同樣:

VARCHAR(10) CHARACTER SET utf8
NATIONAL VARCHAR(10)
NCHAR VARCHAR(10)
NATIONAL CHARACTER VARYING(10)
NATIONAL CHAR VARYING(10)

您能夠使用N'literal'來建立一個使用國家特有字元編碼的字串。這兩個語句是等價的:

SELECT N'some text';
SELECT _utf8'some text';

關於MySQL4.1以前的版本到5.1版本字元編碼升級的訊息,請參見MySQL4.1參考手冊

10.10. MySQL支援的字元編碼和校對

MySQL支援30多種字元編碼的70多種 校對規則。字元編碼和它們的預設校對規則可以通過SHOW CHARACTER SET語句顯示:

mysql> SHOW CHARACTER SET;
+----------+-----------------------------+---------------------+
| Charset  | Description                 | Default collation   |
+----------+-----------------------------+---------------------+
| big5     | Big5 Traditional Chinese    | big5_chinese_ci     |
| dec8     | DEC West European           | dec8_swedish_ci     |
| cp850    | DOS West European           | cp850_general_ci    |
| hp8      | HP West European            | hp8_english_ci      |
| koi8r    | KOI8-R Relcom Russian       | koi8r_general_ci    |
| latin1   | cp1252 West European        | latin1_swedish_ci   |
| latin2   | ISO 8859-2 Central European | latin2_general_ci   |
| swe7     | 7bit Swedish                | swe7_swedish_ci     |
| ascii    | US ASCII                    | ascii_general_ci    |
| ujis     | EUC-JP Japanese             | ujis_japanese_ci    |
| sjis     | Shift-JIS Japanese          | sjis_japanese_ci    |
| hebrew   | ISO 8859-8 Hebrew           | hebrew_general_ci   |
| tis620   | TIS620 Thai                 | tis620_thai_ci      |
| euckr    | EUC-KR Korean               | euckr_korean_ci     |
| koi8u    | KOI8-U Ukrainian            | koi8u_general_ci    |
| gb2312   | GB2312 Simplified Chinese   | gb2312_chinese_ci   |
| greek    | ISO 8859-7 Greek            | greek_general_ci    |
| cp1250   | Windows Central European    | cp1250_general_ci   |
| gbk      | GBK Simplified Chinese      | gbk_chinese_ci      |
| latin5   | ISO 8859-9 Turkish          | latin5_turkish_ci   |
| armscii8 | ARMSCII-8 Armenian          | armscii8_general_ci |
| utf8     | UTF-8 Unicode               | utf8_general_ci     |
| ucs2     | UCS-2 Unicode               | ucs2_general_ci     |
| cp866    | DOS Russian                 | cp866_general_ci    |
| keybcs2  | DOS Kamenicky Czech-Slovak  | keybcs2_general_ci  |
| macce    | Mac Central European        | macce_general_ci    |
| macroman | Mac West European           | macroman_general_ci |
| cp852    | DOS Central European        | cp852_general_ci    |
| latin7   | ISO 8859-13 Baltic          | latin7_general_ci   |
| cp1251   | Windows Cyrillic            | cp1251_general_ci   |
| cp1256   | Windows Arabic              | cp1256_general_ci   |
| cp1257   | Windows Baltic              | cp1257_general_ci   |
| binary   | Binary pseudo charset       | binary              |
| geostd8  | GEOSTD8 Georgian            | geostd8_general_ci  |
| cp932    | SJIS for Windows Japanese   | cp932_japanese_ci   |
| eucjpms  | UJIS for Windows Japanese   | eucjpms_japanese_ci |
+----------+-----------------------------+---------------------+

10.10.1. Unicode字元編碼

MySQL有兩種Unicode字元編碼。您能夠使用這些字元編碼保存大約650種語言的文本。

·         ucs2 (UCS-2 Unicode)校對規則:

  • mysql> SHOW COLLATION LIKE 'ucs2%';
    +--------------------+---------+-----+---------+----------+---------+
    | Collation          | Charset | Id  | Default | Compiled | Sortlen |
    +--------------------+---------+-----+---------+----------+---------+
    | ucs2_general_ci    | ucs2    |  35 | Yes     | Yes      |       1 |
    | ucs2_bin           | ucs2    |  90 |         | Yes      |       1 |
    | ucs2_unicode_ci    | ucs2    | 128 |         | Yes      |       8 |
    | ucs2_icelandic_ci  | ucs2    | 129 |         | Yes      |       8 |
    | ucs2_latvian_ci    | ucs2    | 130 |         | Yes      |       8 |
    | ucs2_romanian_ci   | ucs2    | 131 |         | Yes      |       8 |
    | ucs2_slovenian_ci  | ucs2    | 132 |         | Yes      |       8 |
    | ucs2_polish_ci     | ucs2    | 133 |         | Yes      |       8 |
    | ucs2_estonian_ci   | ucs2    | 134 |         | Yes      |       8 |
    | ucs2_spanish_ci    | ucs2    | 135 |         | Yes      |       8 |
    | ucs2_swedish_ci    | ucs2    | 136 |         | Yes      |       8 |
    | ucs2_turkish_ci    | ucs2    | 137 |         | Yes      |       8 |
    | ucs2_czech_ci      | ucs2    | 138 |         | Yes      |       8 |
    | ucs2_danish_ci     | ucs2    | 139 |         | Yes      |       8 |
    | ucs2_lithuanian_ci | ucs2    | 140 |         | Yes      |       8 |
    | ucs2_slovak_ci     | ucs2    | 141 |         | Yes      |       8 |
    | ucs2_spanish2_ci   | ucs2    | 142 |         | Yes      |       8 |
    | ucs2_roman_ci      | ucs2    | 143 |         | Yes      |       8 |
    | ucs2_persian_ci    | ucs2    | 144 |         | Yes      |       8 |
    | ucs2_esperanto_ci  | ucs2    | 145 |         | Yes      |       8 |
    +--------------------+---------+-----+---------+----------+---------+
    
  • utf8 (UTF-8 Unicode)校對規則:

    mysql> SHOW COLLATION LIKE 'utf8%';
    +--------------------+---------+-----+---------+----------+---------+
    | Collation          | Charset | Id  | Default | Compiled | Sortlen |
    +--------------------+---------+-----+---------+----------+---------+
    | utf8_general_ci    | utf8    |  33 | Yes     | Yes      |       1 |
    | utf8_bin           | utf8    |  83 |         | Yes      |       1 |
    | utf8_unicode_ci    | utf8    | 192 |         | Yes      |       8 |
    | utf8_icelandic_ci  | utf8    | 193 |         | Yes      |       8 |
    | utf8_latvian_ci    | utf8    | 194 |         | Yes      |       8 |
    | utf8_romanian_ci   | utf8    | 195 |         | Yes      |       8 |
    | utf8_slovenian_ci  | utf8    | 196 |         | Yes      |       8 |
    | utf8_polish_ci     | utf8    | 197 |         | Yes      |       8 |
    | utf8_estonian_ci   | utf8    | 198 |         | Yes      |       8 |
    | utf8_spanish_ci    | utf8    | 199 |         | Yes      |       8 |
    | utf8_swedish_ci    | utf8    | 200 |         | Yes      |       8 |
    | utf8_turkish_ci    | utf8    | 201 |         | Yes      |       8 |
    | utf8_czech_ci      | utf8    | 202 |         | Yes      |       8 |
    | utf8_danish_ci     | utf8    | 203 |         | Yes      |       8 |
    | utf8_lithuanian_ci | utf8    | 204 |         | Yes      |       8 |
    | utf8_slovak_ci     | utf8    | 205 |         | Yes      |       8 |
    | utf8_spanish2_ci   | utf8    | 206 |         | Yes      |       8 |
    | utf8_roman_ci      | utf8    | 207 |         | Yes      |       8 |
    | utf8_persian_ci    | utf8    | 208 |         | Yes      |       8 |
    | utf8_esperanto_ci  | utf8    | 209 |         | Yes      |       8 |
    +--------------------+---------+-----+---------+----------+---------+
    

utf8_unicode_ci校對規則是根據Unicode校對規則算法(UCA)執行的, 校對規則描述見 http://www.unicode.org/reports/tr10/。此校對規則使用UCA 4.0.0版本砝碼鍵:http://www.unicode.org/Public/UC一個/4.0.0/一個llkeys-4.0.0.txt。(以下討論使用utf8_unicode_ci,但同樣適合ucs2_unicode_ci。)

當前,utf8_unicode_ci校對規則僅部分支援Unicode校對規則算法。一些字元還是不能支援。並且,不能完全支援組合的記號。這主要影響越南和俄羅斯的一些少數民族語言,如:Udmurt TatarBashkirMari

utf8_unicode_ci的最主要的特色是支援延伸,即當把一個字母看作與其它字母組合相等時。例如,在德語和一些其它語言中『s』等於『ss』。

utf8_general_ci是一個遺留的 校對規則,不支援延伸。它僅能夠在字元之間進行逐個比較。這意味著utf8_general_ci校對規則進行的比較速度很快,但是與使用utf8_unicode_ci的 校對規則相比,比較正確性較差)。

例如,使用utf8_general_ciutf8_unicode_ci兩種 校對規則下面的比較相等:

A = A
O = O
U = U

兩種校對規則之間的區別是,對於utf8_general_ci下面的等式成立:

s = s

但是,對於utf8_unicode_ci下面等式成立:

s = ss

對於一種語言僅當使用utf8_unicode_ci排序做的不好時,才執行與具體語言相關的utf8字元編碼 校對規則。例如,對於德語和法語,utf8_unicode_ci工作的很好,因此不再需要為這兩種語言建立特殊的utf8校對規則。

utf8_general_ci也適用與德語和法語,除了『s』等於『s』,而不是『ss』之外。如果您的應用能夠接受這些,那麼應該使用utf8_general_ci因為它速度快。否則,使用utf8_unicode_ci,因為它比較準確。

utf8_swedish_ci,與其它語言相關的utf8的校對規則相似,來源於utf8_unicode_ci使用額外的語言規則。例如,在瑞典語中,以下的關係式成立,它在德語和法語中不成立:

U = Y < O

utf8_spanish_ciutf8_spanish2_ci校對規則分別適用於現代和古典西班牙語。在兩種 校對規則中,n』(n-發音符)是『n』和『o』之間的間隔字母。另外,對於古典西班牙語,『ch』是『c』和d之間的間隔字母,並且『ll』是『l』和『m』之間的間隔字母。

10.10.2. 西歐字元編碼

西歐字元編碼覆蓋大多數西歐語言,如法語、西班牙語、加泰羅尼亞語、巴斯克人語、葡萄牙語、意大利語、阿而巴尼亞語、荷蘭語、德語、丹麥語、瑞典語、挪威語、芬蘭語、法羅人語、冰島語、愛爾蘭語、蘇格蘭語和英語。

·         asciiUS ASCII)校對規則:

o        ascii_bin

o        ascii_general_ci( 預設)

·         cp850DOS西歐) 校對規則:

o        cp850_bin

o        cp850_general_ci( 預設)

·         dec8DEC 西歐)校對規則:

o        dec8_bin

o        dec8_swedish_ci( 預設)

·         hp8HP 西歐)校對規則:

o        hp8_bin

o        hp8_english_ci( 預設)

·         latin1cp1252 西歐)校對規則:

o        latin1_bin

o        latin1_danish_ci

o        latin1_general_ci

o        latin1_general_cs

o        latin1_german1_ci

o        latin1_german2_ci

o        latin1_spanish_ci

o        latin1_swedish_ci( 預設)

latin1是 預設字元編碼。latin1_swedish_ci是 預設的校對規則,它用於大多數MySQL客戶。雖然經常說它以瑞典/芬蘭 校對規則為基礎,但瑞典和芬蘭人不同意這種說法。

latin1_german1_cilatin1_german2_ci校對規則基於DIN-1DIN-2標準,這裡DIN代資料表Deutsches Institut fur Normung(德語等價於ANSI)。DIN-1被叫做「字典校對規則」,DIN-2被叫做「電話簿校對規則」。

o        latin1_german1_ci(字典)規則:

o                     A = a
o                     O = O
o                     U = U
o                     s = s

o        latin1_german2_ci電話簿)規則:

o                     A = aE
o                     O = OE
o                     U = UE
o                     s = ss

latin1_spanish_ci校對規則中,『n』(n-tilde)是『n』和『o』之間的間隔字母。

·         macromaMac西歐) 校對規則:

o        macroman_bin

o        macroman_general_ci( 預設)

·         swe77位瑞典語) 校對規則:

o        swe7_bin

o        swe7_swedish_ci( 預設)

10.10.3. 中歐字元編碼

我們還提供一些用於捷克共和國、斯洛伐克、匈牙利、羅馬尼亞、斯羅紋尼亞、克羅地亞和波蘭的字元編碼支援。

·         cp1250Windows中歐) 校對規則:

o        cp1250_bin

o        cp1250_croatian_ci

o        cp1250_czech_cs

o        cp1250_general_ci( 預設)

·         cp852DOS 中歐)校對規則:

o        cp852_bin

o        cp852_general_ci( 預設)

·         keybcs2DOS Kamenicky Czech-Slovak)校對規則:

o        keybcs2_bin

o        keybcs2_general_ci( 預設)

·         latin2ISO 8859-2 中歐)校對規則:

o        latin2_bin

o        latin2_croatian_ci

o        latin2_czech_cs

o        latin2_general_ci( 預設)

o        latin2_hungarian_ci

·         macceMac 中歐)校對規則:

o        macce_bin

o        macce_general_ci( 預設)

10.10.4. 南歐與中東字元編碼

MySQL支援的南歐和中東字元編碼包括亞美尼亞語、阿拉伯語、喬治亞語、希臘語、希伯萊語和土耳其語:

·         armscii8ARMSCII-8 亞美尼亞語)校對規則:

o        armscii8_bin

o        armscii8_general_ci( 預設)

·         cp1256(阿拉伯語Windows) 校對規則:

o        cp1256_bin

o        cp1256_general_ci( 預設)

·         geostd8GEOSTD8喬治亞語) 校對規則:

o        geostd8_bin

o        geostd8_general_ci( 預設)

·         greekISO 8859-7希臘語)校對規則:

o        greek_bin

o        greek_general_ci( 預設)

·         hebrewISO 8859-8希伯萊語)校對規則:

o        hebrew_bin

o        hebrew_general_ci( 預設)

·         latin5ISO 8859-9 土耳其語)校對規則:

o        latin5_bin

o        latin5_turkish_ci( 預設)

10.10.5. 波羅的海字元編碼

波羅的海字元編碼覆蓋愛沙尼亞語、拉脫維亞語和立陶宛語言。當前支援的兩種波羅的海字元編碼:

·         cp1257Windows波羅的海) 校對規則:

o        cp1257_bin

o        cp1257_general_ci( 預設)

o        cp1257_lithuanian_ci

·         latin7ISO 8859-13波羅的海)校對規則:

o        latin7_bin

o        latin7_estonian_cs

o        latin7_general_ci( 預設)

o        latin7_general_cs

10.10.6. 西裡爾字元編碼

使用西裡爾字元編碼和校對規則的有Belarusian、保加利亞、俄語和烏克蘭語言。

·         cp1251Windows 西裡爾)校對規則:

o        cp1251_bin

o        cp1251_bulgarian_ci

o        cp1251_general_ci( 預設)

o        cp1251_general_cs

o        cp1251_ukrainian_ci

·         cp866DOS 俄語)校對規則:

o        cp866_bin

o        cp866_general_ci( 預設)

·         koi8rKOI8-R Relcom 俄語)校對規則:

o        koi8r_bin

o        koi8r_general_ci( 預設)

·         koi8uKOI8-U 烏克蘭語)校對規則:

o        koi8u_bin

o        koi8u_general_ci( 預設)

10.10.7. 亞洲字元編碼

我們支援的亞洲字元編碼包括中文、日語、韓語和泰國語。這些可能比較複雜。例如,中文字元編碼必須考慮到上千種不同的字元。

·         big5Big5傳統中文) 校對規則:

o        big5_bin

o        big5_chinese_ci( 預設)

·         cp932SJIS Windows日語)校對規則:

o        cp932_bin

o        cp932_japanese_ci( 預設)

·         eucjpmsUJIS Windows日語)校對規則:

o        eucjpms_bin

o        eucjpms_japanese_ci( 預設)

·         euckrEUC-KR 韓語)校對規則:

o        euckr_bin

o        euckr_korean_ci( 預設)

·         gb2312GB2312 簡體中文)校對規則:

o        gb2312_bin

o        gb2312_chinese_ci( 預設)

·         gbkGBK簡體中文) 校對規則:

o        gbk_bin

o        gbk_chinese_ci( 預設)

·         sjisShift-JIS 日語)校對規則:

o        sjis_bin

o        sjis_japanese_ci( 預設)

·         tis620TIS620 泰國語)校對規則:

o        tis620_bin

o        tis620_thai_ci( 預設)

·         ujisEUC-JP 日語)校對規則:

o        ujis_bin

o        ujis_japanese_ci( 預設)

10.10.7.1. cp932字元編碼

為什麼需要cp932

MySQL中,sjis字元編碼對應於由IANA定義的Shift_JIS字元編碼,它支援JIS X0201JIS X0208字元。(見 http://www.iana.org/assignments/character-sets。)

但是,「SHIFT JIS」作為描述性術語的含義變得非常含糊不清,並且它常常包括由不同供應商定義的Shift_JIS延伸部分。

例如,使用在日本Windows環境中使用的「SHIFT JIS」是MicrosoftShift_JISMicrosoft延伸,它的準確名字是Microsoft Windows Codepage: 932cp932除由Shift_JIS支援的字元之外,cp932支援延伸字元,如NEC選擇的IBM延伸字元和IBM延伸字元。

許多日本用戶在使用這些延伸字元過程中碰到過一些問題。這些問題是由於以下情況引起的:

·         MySQL自動轉換字元編碼。

·         字元編碼通過Unicode轉換(ucs2)。

·         sjis字元編碼不支援這些延伸字元轉換。

·         從號稱「SHIFT JIS」到Unicode的轉換,存在一些轉換規則,並且一些字元轉換到Unicode依賴不同的轉換規則。MySQL僅支援這些轉換規則中的一種(在後面描述)。

MySQLcp932字元編碼可以解決這些轉換問題。

因為MySQL支援字元編碼轉換,將IANA Shift_JIS cp932分離為兩種不同字元編碼是重要的,因為它們提供不同的轉換規則。

cp932sjis有什麼不同?

cp932字元編碼與sjis存在以下不同點:

·         cp932支援NEC特殊字元、NEC選擇的IBM延伸字元和IBM選擇的字元。

·         一些cp932字元有兩個不同的編碼點,這兩種編碼點轉換為相同Unicode編碼點。因此,當從Unicode轉換回到cp932時,必須選擇一個編碼點。對於這種「相互轉換使用由Microsoft推薦的轉換規則。(見 http//support.microsoft.com/kb/170559/EN-US/。)

轉換規則如下:

o        如果字元在JIS X 0208 NEC特殊字元中同時存在,使用JIS X 0208 的編碼點。

o        如果字元在NEC特殊字元和IBM選擇的字元中同時存在,使用NEC特殊字元的編碼點。

o        如果字元在IBM選擇的字元和NEC選擇的IBM延伸字元中同時存在,使用IBM延伸字元的編碼點。

關於cp932字元的Unicode 值的列資料表顯示訊息見http://www.microsoft.com/globaldev/reference/dbcs/932.htm。對於cp932資料表中的帶有下面有四位數字出現的字元的實體,數字代資料表相應的Unicodeucs2)編碼。對於資料表中有兩個帶下劃線的數字出現的實體,擇有一個以那兩個數字開頭的cp932字元值的範圍。點擊一個這種資料表的實體,將帶您到一個頁,該頁顯示每個以那些數字開頭的cp932字元的Unicode值。

以下連接很重要。它們與下列字元編碼的編碼相對應:

o        NEC特殊字元:

http://www.microsoft.com/globaldev/reference/dbcs/932/932_87.htm

o        NEC選擇的IBM延伸字元:

o                     http://www.microsoft.com/globaldev/reference/dbcs/932/932_ED.htm
o                     http://www.microsoft.com/globaldev/reference/dbcs/932/932_EE.htm

o        IBM選擇的字元:

o                     http://www.microsoft.com/globaldev/reference/dbcs/932/932_FA.htm
o                     http://www.microsoft.com/globaldev/reference/dbcs/932/932_FB.htm
o                     http://www.microsoft.com/globaldev/reference/dbcs/932/932_FC.htm

·         cp932eucjpms結合支援用戶自行定義字元的轉換,並且解決sjis/ujis轉換問題。詳細訊息,請參見http://www.opengroup.or.jp/jvc/cde/sjis-euc-e.html

·         對於一些字元,與ucs2之間的轉換與sjiscp932之間的轉換是不同的。下資料表舉例說明了這些不同。

轉換到ucs2

sjis/cp932

sjis ucs2轉換

cp932 ucs2轉換

5C

005C

005C

7E

007E

007E

815C

2015

2015

815F

005C

FF3C

8160

301C

FF5E

8161

2016

2225

817C

2212

FF0D

8191

00a2

FFE0

8192

00a3

FFE1

81Ca

00aC

FFE2

ucs2轉換:

ucs2

ucs2 sjis轉換

ucs2 cp932轉換

005C

815F

5C

007E

7E

7E

00a2

8191

3F

00a3

8192

3F

00aC

81Ca

3F

2015

815C

815C

2016

8161

3F

2212

817C

3F

2225

3F

8161

301C

8160

3F

FF0D

3F

817C

FF3C

3F

815F

FF5E

3F

8160

FFE0

3F

8191

FFE1

3F

8192

FFE2

3F

81Ca


這是MySQL參考手冊的翻譯版本,關於MySQL參考手冊,請訪問dev.mysql.com。 原始參考手冊為英文版,與英文版參考手冊相比,本翻譯版可能不是最新的。