Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  The binary Collation Compared to _bin Collations

12.8.5 二进制排序规则与_bin 排序规则的比较

本节描述了二进制字符串(使用BINARYVARBINARYBLOB数据类型)对非二进制字符串的《bin》排序规则进行比较。

二进制字符串(以BINARYVARBINARYBLOB数据类型)有一个名为binary的字符集和排序规则。二进制字符串是字节序列,字节的数字值确定比较和排序顺序。见第12.10.8节,“二进制字符集”

非二进制字符串(使用CHARVARCHARTEXT数据类型存储)具有字符集和排序规则,除非是binary。给定的非二进制字符集可以有多个排序规则,每个规则都定义了该集中的字符比较和排序顺序。对于大多数字符集,其中一个是二进制排序规则,通过在排序规则名称中添加_bin后缀来表示。例如,latin1和big5的二进制排序规则分别为latin1_binbig5_bin;utf8mb4是一个例外,它有两个二进制排序规则,分别是utf8mb4_binutf8mb4_0900_bin;见第12.10.1节,“Unicode字符集”

二进制排序规则与_bin 排序规则在以下部分有所不同:

二进制字符串是字节序列。对于binary排序,比较和排序基于数字字节值。非二进制字符串是字符序列,可能是多字节的。非二进制字符串的排序定义了字符值的顺序用于比较和排序。对于_bin排序,这个顺序基于数字字符代码值,类似于二进制字符串排序,但字符代码值可能是多字节。

非二进制字符串具有字符集,在许多情况下自动转换到另一个字符集,即使该字符串具有_bin排序:

  • 将列值分配给具有不同字符集的列:

    UPDATE t1 SET utf8mb4_bin_column=latin1_column;
    INSERT INTO t1 (latin1_column) SELECT utf8mb4_bin_column FROM t2;
  • 将列值分配给INSERTUPDATE使用字符串字面量:

    SET NAMES latin1;
    INSERT INTO t1 (utf8mb4_bin_column) VALUES ('string-in-latin1');
  • 将结果从服务器发送到客户端:

    SET NAMES latin1;
    SELECT utf8mb4_bin_column FROM t2;

对于二进制字符串列,不进行转换。对于前面类似的情况,字符串值将以字节方式复制。

非二进制字符集的排序规则提供了字符的字母大小写信息,因此非二进制字符串中的字符可以从一个字母大小写转换到另一个,甚至是忽略字母大小写的_bin 排序规则:

mysql> SET NAMES utf8mb4 COLLATE utf8mb4_bin;
mysql> SELECT LOWER('aA'), UPPER('zZ');
+-------------+-------------+
| LOWER('aA') | UPPER('zZ') |
+-------------+-------------+
| aa          | ZZ          |
+-------------+-------------+

字母大小写不适用于二进制字符串。要执行字母大小写转换,必须首先将字符串转换为非二进制字符串,使用适合存储在字符串中的数据的字符集:

mysql> SET NAMES binary;
mysql> SELECT LOWER('aA'), LOWER(CONVERT('aA' USING utf8mb4));
+-------------+------------------------------------+
| LOWER('aA') | LOWER(CONVERT('aA' USING utf8mb4)) |
+-------------+------------------------------------+
| aA          | aa                                 |
+-------------+------------------------------------+

MySQL 排序规则具有一个pad 属性,值为PAD SPACENO PAD

对于非二进制字符串(CHARVARCHARTEXT 值),字符串排序规则的 pad 属性确定了在比较字符串末尾空格时的处理:

  • 对于 PAD SPACE 排序规则,末尾空格是无关紧要的,在比较时不考虑末尾空格。

  • NO PAD 字符集将尾部空格视为比较中的其他字符。

不同行为可以使用两个 utf8mb4 二进制字符集来演示,其中一个是 PAD SPACE,另一个是 NO PAD。示例还展示了如何使用 INFORMATION_SCHEMA COLLATIONS 表来确定字符集的 pad 属性。

mysql> SELECT COLLATION_NAME, PAD_ATTRIBUTE
       FROM INFORMATION_SCHEMA.COLLATIONS
       WHERE COLLATION_NAME LIKE 'utf8mb4%bin';
+------------------+---------------+
| COLLATION_NAME   | PAD_ATTRIBUTE |
+------------------+---------------+
| utf8mb4_bin      | PAD SPACE     |
| utf8mb4_0900_bin | NO PAD        |
+------------------+---------------+
mysql> SET NAMES utf8mb4 COLLATE utf8mb4_bin;
mysql> SELECT 'a ' = 'a';
+------------+
| 'a ' = 'a' |
+------------+
|          1 |
+------------+
mysql> SET NAMES utf8mb4 COLLATE utf8mb4_0900_bin;
mysql> SELECT 'a ' = 'a';
+------------+
| 'a ' = 'a' |
+------------+
|          0 |
+------------+
Note

比较 在这个上下文中,不包括 LIKE 模式匹配操作符,无论字符集,尾部空格都是重要的。

对于二进制字符串(BINARYVARBINARYBLOB 值),所有字节在比较中都是重要的,包括尾部空格:

mysql> SET NAMES binary;
mysql> SELECT 'a ' = 'a';
+------------+
| 'a ' = 'a' |
+------------+
|          0 |
+------------+

CHAR(N) 列存储非二进制字符串 N 个字符长。对于插入,值短于 N 个字符将被扩展为空格。对于检索,尾部空格将被删除。

BINARY(N) 列存储二进制字符串,长度为 N 字节。对于插入操作,值短于 N 字节将以 0x00 字节扩展。对于查询操作,不会删除任何内容;声明的长度总是返回。

mysql> CREATE TABLE t1 (
         a CHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin,
         b BINARY(10)
       );
mysql> INSERT INTO t1 VALUES ('x','x');
mysql> INSERT INTO t1 VALUES ('x ','x ');
mysql> SELECT a, b, HEX(a), HEX(b) FROM t1;
+------+------------------------+--------+----------------------+
| a    | b                      | HEX(a) | HEX(b)               |
+------+------------------------+--------+----------------------+
| x    | 0x78000000000000000000 | 78     | 78000000000000000000 |
| x    | 0x78200000000000000000 | 78     | 78200000000000000000 |
+------+------------------------+--------+----------------------+