10.8.5 二进制排序规则与_bin 排序规则相比

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

二进制字符串(使用BINARYVARBINARYBLOB数据类型存储)具有字符集和排序规则binary。二进制字符串是字节序列,这些字节的数字值确定比较和排序 Sequences。参见第 10.10.8 节“二进制字符集”

非二进制字符串(使用CHARVARCHARTEXT数据类型存储)具有除binary以外的字符集和排序规则。给定的非二进制字符集可以具有多个排序规则,每个排序规则定义该字符集中的字符的特定比较和排序 Sequences。其中一种是二进制排序规则,由排序规则名称中的_bin后缀 table 示。例如,utf8latin1的二进制排序规则分别命名为utf8_binlatin1_bin

binary归类与_bin归类在以下几个方面有所不同:

比较和排序单位

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

字符集转换

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

  • 将列值分配给具有不同字符集的另一列时:
UPDATE t1 SET utf8_bin_column=latin1_column;
INSERT INTO t1 (latin1_column) SELECT utf8_bin_column FROM t2;
  • 使用字符串 Literals 为INSERTUPDATE分配列值时:
SET NAMES latin1;
INSERT INTO t1 (utf8_bin_column) VALUES ('string-in-latin1');
  • 将结果从服务器发送到 Client 端时:
SET NAMES latin1;
SELECT utf8_bin_column FROM t2;

对于二进制字符串列,不会进行任何转换。对于与前面类似的情况,字符串值将按字节复制。

Lettercase Conversion

非二进制字符集的排序规则提供有关字符的字母大小写的信息,因此即使对于忽略字母大小写排序的_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                                 |
+-------------+------------------------------------+

比较中的尾随空间处理

非二进制字符串的所有归类(包括_bin归类)都具有PAD SPACE行为。在比较中,尾随空格无关紧要:

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