文档主页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
信息 (Gzip) - 4.0Mb
信息 (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  二进制排序规则与 _bin 排序规则的比较

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

本节介绍二进制字符串的 binary 排序规则与非二进制字符串的 _bin 排序规则的比较。

二进制字符串(使用 BINARYVARBINARYBLOB 数据类型存储)具有名为 binary 的字符集和排序规则。二进制字符串是字节序列,这些字节的数值决定了比较和排序顺序。请参阅 第 12.10.8 节“二进制字符集”

非二进制字符串(使用 CHARVARCHARTEXT 数据类型存储)具有 binary 以外的字符集和排序规则。给定的非二进制字符集可以有多个排序规则,每个排序规则都定义了该字符集中字符的特定比较和排序顺序。对于大多数字符集,其中一个是二进制排序规则,由排序规则名称中的 _bin 后缀表示。例如,latin1big5 的二进制排序规则分别命名为 latin1_binbig5_binutf8mb4 是一个例外,它有两个二进制排序规则,utf8mb4_binutf8mb4_0900_bin;请参阅 第 12.10.1 节“Unicode 字符集”

binary 排序规则在以下几个方面与 _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 SPACENO PAD

  • 大多数 MySQL 排序规则的填充属性为 PAD SPACE

  • 基于 UCA 9.0.0 及更高版本的 Unicode 排序规则的填充属性为 NO PAD;请参阅 第 12.10.1 节“Unicode 字符集”

对于非二进制字符串(CHARVARCHARTEXT 值),字符串排序规则填充属性决定了在比较字符串末尾的尾随空格时的处理方式。

  • 对于 PAD SPACE 排序规则,尾随空格在比较中不重要;比较字符串时不考虑尾随空格。

  • NO PAD 排序规则将尾随空格视为比较中的重要字符,就像任何其他字符一样。

可以使用两个 utf8mb4 二进制排序规则来演示不同的行为,其中一个是 PAD SPACE,另一个是 NO PAD。该示例还显示了如何使用 INFORMATION_SCHEMA COLLATIONS 表来确定排序规则的填充属性。

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

在这种情况下,“比较 不包括 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 |
+------+------------------------+--------+----------------------+