Documentation Home
MySQL 8.0 参考手册  / 第 10 章字符集、排序规则、Unicode  / 10.8 整理问题  /  10.8.5 二进制排序规则与 _bin 排序规则的比较

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

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

二进制字符串(使用 、 和 数据类型存储 BINARYVARBINARYBLOB一个名为binary. 二进制字符串是字节序列,这些字节的数值决定比较和排序顺序。请参阅 第 10.10.8 节,“二进制字符集”

非二进制字符串(使用 、 和 数据类型存储 CHARVARCHARTEXT字符集和排序规则不是binary. 一个给定的非二进制字符集可以有多个排序规则,每个排序规则为该集中的字符定义一个特定的比较和排序顺序。其中之一是二进制归类,由_bin归类名称中的后缀表示。例如, 和 的二进制排序规则 分别命名 为 utf8和。latin1utf8_binlatin1_bin

binary排序规则在几个方面不同于 排序规则, 将_bin在以下部分中讨论:

比较排序单元

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

字符集转换

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

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

    UPDATE t1 SET utf8_bin_column=latin1_column;
    INSERT INTO t1 (latin1_column) SELECT utf8_bin_column FROM t2;
  • INSERT为或 UPDATE使用字符串文字 分配列值时 :

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

    SET NAMES latin1;
    SELECT utf8_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                                 |
+-------------+------------------------------------+

比较中的尾随空格处理

非二进制字符串PAD SPACE对所有归类都有行为,包括_bin 归类。尾随空格在比较中是微不足道的:

mysql> SET NAMES utf8 COLLATE utf8_bin;
mysql> SELECT 'a ' = 'a';
+------------+
| 'a ' = 'a' |
+------------+
|          1 |
+------------+

对于二进制字符串,所有字节在比较中都很重要,包括尾随空格:

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 utf8 COLLATE utf8_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    | x          | 78     | 78000000000000000000 |
| x    | x          | 78     | 78200000000000000000 |
+------+------------+--------+----------------------+