文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


12.14.1 排序规则实现类型

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 节“向 Unicode 字符集添加 UCA 排序规则”

其他排序规则

还有一些排序规则不属于上述任何类别。