10.14.1 归类实施类型
MySQL 实现了几种类型的排序规则:
8 位字符集的简单归类
这种归类是使用 256 个权重的数组实现的,该数组定义了从字符代码到权重的一对一 Map。 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)
有关实现说明,请参见第 10.14.3 节“向 8 位字符集添加简单归类”。
8 位字符集的复杂归类
此类排序是使用 C 源文件中的函数实现的,该函数定义了如何对字符进行排序,如第 10.13 节“添加字符集”中所述。
非 Unicode 多字节字符集的排序规则
对于这种类型的排序规则,对 8 位(单字节)和多字节字符的处理方式有所不同。对于 8 位字符,字符代码以不区分大小写的方式 Map 到权重。 (例如,单字节字符'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)
有关实现说明,请参见第 10.13 节“添加字符集”。
Unicode 多字节字符集的排序规则
这些归类中的一些归类基于 Unicode 归类算法(UCA),而其他则不基于。
非 UCA 归类具有从字符代码到权重的一对一 Map。在 MySQL 中,此类归类不区分大小写和变音。 utf8_general_ci
是一个示例:'a'
,'A'
,'À'
和'á'
各自具有不同的字符代码,但权重均为0x0041
且比较相等。
mysql> SET NAMES 'utf8' COLLATE 'utf8_general_ci';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t1
(c1 CHAR(1) CHARACTER SET UTF8 COLLATE utf8_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 'utf8' COLLATE 'utf8_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 'utf8' COLLATE 'utf8_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 'utf8' COLLATE 'utf8_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)
多字符到多权重的 Map 也是可能的(这是扩展的收缩),但是 MySQL 不支持。
有关实施说明,对于非 UCA 整理,请参见第 10.13 节“添加字符集”。有关 UCA 归类,请参见第 10.14.4 节“将 UCA 归类添加到 Unicode 字符集”。
Miscellaneous collations
还有一些归类不属于任何先前的类别。