MySQL 實作了幾種校對規則類型
8 位元字元集的簡單校對規則
這種類型的校對規則是使用 256 個權重的陣列實作的,該陣列定義了從字元碼到權重的一對一映射。 latin1_swedish_ci
就是一個例子。它是一種不區分大小寫的校對規則,因此字元的大寫和小寫版本具有相同的權重,並且它們比較結果為相等。
mysql> SET NAMES 'latin1' COLLATE 'latin1_swedish_ci';
Query OK, 0 rows affected (0.01 sec)
mysql> SELECT HEX(WEIGHT_STRING('a')), HEX(WEIGHT_STRING('A'));
+-------------------------+-------------------------+
| HEX(WEIGHT_STRING('a')) | HEX(WEIGHT_STRING('A')) |
+-------------------------+-------------------------+
| 41 | 41 |
+-------------------------+-------------------------+
1 row in set (0.01 sec)
mysql> SELECT 'a' = 'A';
+-----------+
| 'a' = 'A' |
+-----------+
| 1 |
+-----------+
1 row in set (0.12 sec)
如需實作指示,請參閱 第 12.14.3 節,〈將簡單校對規則新增至 8 位元字元集〉。
8 位元字元集的複雜校對規則
這種類型的校對規則是使用 C 原始檔中的函式實作的,這些函式定義了如何排序字元,如 第 12.13 節,〈新增字元集〉中所述。
非 Unicode 多位元組字元集的校對規則
對於這種類型的校對規則,8 位元 (單位元組) 和多位元組字元的處理方式不同。對於 8 位元字元,字元碼以不區分大小寫的方式對應到權重。(例如,單位元組字元 'a'
和 'A'
都具有 0x41
的權重。) 對於多位元組字元,字元碼和權重之間有兩種關係
權重等於字元碼。
sjis_japanese_ci
就是這種類型校對規則的一個例子。多位元組字元'ぢ'
的字元碼為0x82C0
,權重也為0x82C0
。mysql> CREATE TABLE t1 (c1 VARCHAR(2) CHARACTER SET sjis COLLATE sjis_japanese_ci); Query OK, 0 rows affected (0.01 sec) mysql> INSERT INTO t1 VALUES ('a'),('A'),(0x82C0); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1; +------+---------+------------------------+ | c1 | HEX(c1) | HEX(WEIGHT_STRING(c1)) | +------+---------+------------------------+ | a | 61 | 41 | | A | 41 | 41 | | ぢ | 82C0 | 82C0 | +------+---------+------------------------+ 3 rows in set (0.00 sec)
字元碼一對一對應到權重,但代碼不一定等於權重。
gbk_chinese_ci
就是這種類型校對規則的一個例子。多位元組字元'膰'
的字元碼為0x81B0
,但權重為0xC286
。mysql> CREATE TABLE t1 (c1 VARCHAR(2) CHARACTER SET gbk COLLATE gbk_chinese_ci); Query OK, 0 rows affected (0.33 sec) mysql> INSERT INTO t1 VALUES ('a'),('A'),(0x81B0); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1; +------+---------+------------------------+ | c1 | HEX(c1) | HEX(WEIGHT_STRING(c1)) | +------+---------+------------------------+ | a | 61 | 41 | | A | 41 | 41 | | 膰 | 81B0 | C286 | +------+---------+------------------------+ 3 rows in set (0.00 sec)
如需實作指示,請參閱 第 12.13 節,〈新增字元集〉。
Unicode 多位元組字元集的校對規則
其中一些校對規則是基於 Unicode 校對演算法 (UCA),其他則不是。
非 UCA 校對規則具有從字元碼到權重的一對一映射。在 MySQL 中,此類校對規則不區分大小寫且不區分重音符號。 utf8mb4_general_ci
就是一個例子:'a'
、'A'
、'À'
和 'á'
各自具有不同的字元碼,但都具有 0x0041
的權重,並且比較結果為相等。
mysql> SET NAMES 'utf8mb4' COLLATE 'utf8mb4_general_ci';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t1
(c1 CHAR(1) CHARACTER SET UTF8MB4 COLLATE utf8mb4_general_ci);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t1 VALUES ('a'),('A'),('À'),('á');
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1;
+------+---------+------------------------+
| c1 | HEX(c1) | HEX(WEIGHT_STRING(c1)) |
+------+---------+------------------------+
| a | 61 | 0041 |
| A | 41 | 0041 |
| À | C380 | 0041 |
| á | C3A1 | 0041 |
+------+---------+------------------------+
4 rows in set (0.00 sec)
MySQL 中基於 UCA 的校對規則具有以下屬性
如果字元具有權重,則每個權重使用 2 個位元組 (16 位元)。
字元可能具有零個權重 (或空的權重)。在這種情況下,字元是可忽略的。範例:「U+0000 NULL」沒有權重,並且是可忽略的。
字元可能具有一個權重。範例:
'a'
的權重為0x0E33
。mysql> SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'; Query OK, 0 rows affected (0.05 sec) mysql> SELECT HEX('a'), HEX(WEIGHT_STRING('a')); +----------+-------------------------+ | HEX('a') | HEX(WEIGHT_STRING('a')) | +----------+-------------------------+ | 61 | 0E33 | +----------+-------------------------+ 1 row in set (0.02 sec)
字元可能具有多個權重。這是一種擴展。範例:德文字母
'ß'
(SZ 連字或 SHARP S) 的權重為0x0FEA0FEA
。mysql> SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'; Query OK, 0 rows affected (0.11 sec) mysql> SELECT HEX('ß'), HEX(WEIGHT_STRING('ß')); +-----------+--------------------------+ | HEX('ß') | HEX(WEIGHT_STRING('ß')) | +-----------+--------------------------+ | C39F | 0FEA0FEA | +-----------+--------------------------+ 1 row in set (0.00 sec)
許多字元可能具有一個權重。這是一種縮寫。範例:
'ch'
是捷克語中的單個字母,其權重為0x0EE2
。mysql> SET NAMES 'utf8mb4' COLLATE 'utf8mb4_czech_ci'; Query OK, 0 rows affected (0.09 sec) mysql> SELECT HEX('ch'), HEX(WEIGHT_STRING('ch')); +-----------+--------------------------+ | HEX('ch') | HEX(WEIGHT_STRING('ch')) | +-----------+--------------------------+ | 6368 | 0EE2 | +-----------+--------------------------+ 1 row in set (0.00 sec)
多字元對多權重映射也是可能的 (這是一種具有擴展的縮寫),但 MySQL 不支援。
如需實作指示,對於非 UCA 校對規則,請參閱 第 12.13 節,〈新增字元集〉。對於 UCA 校對規則,請參閱 第 12.14.4 節,〈將 UCA 校對規則新增至 Unicode 字元集〉。
其他校對規則
還有一些校對規則不屬於任何先前的類別。