与_bin相比的二进制校验
本节描述binary
二进制字符串的_bin
校验规则与非二进制字符串的校验规则相比。
二进制字符串(如使用所存储的BINARY
,VARBINARY
和BLOB
数据类型)有一个字符集和归类命名binary
。二进制字符串是字节序列,这些字节的数字值确定比较和校验顺序。请参见“二进制字符集”。
非二进制字符串(如使用所存储的CHAR
,VARCHAR
和TEXT
数据类型)有一个字符集和比其他校验规则binary
。给定的非二进制字符集可以具有多个校验规则,每个校验规则都定义了该字符集中的特定比较和校验顺序。对于大多数字符集,其中之一是二进制校验规则,由_bin
校验规则名称中的后缀表示。例如,对于二进制核对utf8
和latin1
被命名utf8_bin
和latin1_bin
分别。utf8mb4
是具有两个二进制校验规则的例外,utf8mb4_bin
并且utf8mb4_0900_bin
;看到“ Unicode字符集”。
该binary
核对不同于_bin
在几个方面,在以下部分中讨论的归类:
- 比较和校验单位
- 字符集转换
- 字母转换
- 比较中的尾随空间处理
- 插入和检索的尾随空间处理
比较和校验单位
二进制字符串是字节序列。对于binary
校验规则,比较和校验基于数字字节值。非二进制字符串是字符序列,可能是多字节。非二进制字符串的校验规则定义了用于比较和校验的字符值的顺序。对于_bin
归类,此校验基于数字字符代码值,类似于二进制字符串的校验,不同之处在于字符代码值可能是多字节。
字符集转换
非二进制字符串具有字符集,并且即使在字符串具有_bin
校验规则的情况下,在许多情况下也会自动将其转换为另一个字符集:
将列值分配给具有不同字符集的另一列时:
UPDATE t1SET utf8_bin_column=latin1_column;INSERT INTO t1 (latin1_column)SELECT utf8_bin_columnFROM t2;为
INSERT
或UPDATE
使用字符串文字分配列值时:SET NAMES latin1;INSERT INTO t1 (utf8_bin_column)VALUES ('string-in-latin1');从服务器向客户端发送结果时:
SET NAMES latin1;SELECT utf8_bin_columnFROM t2;
对于二进制字符串列,不会进行任何转换。对于与前面类似的情况,字符串值将按字节复制。
字母转换
非二进制字符集的校验规则提供有关字符字母大小写的信息,因此即使对于_bin
忽略字母大小写校验的校验规则,非二进制字符串中的字符也可以从一个字母大小写转换为另一个字母大小写:
mysql>SET NAMES utf8mb4COLLATE 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 SPACE
或NO PAD
:
- 大多数MySQL归类的pad属性为
PAD SPACE
。 - 基于UCA 9.0.0及更高版本的Unicode归类具有pad属性
NO PAD
;请参见“ Unicode字符集”。
对于非二进制字符串(CHAR
,VARCHAR
和TEXT
值),pad属性确定在比较中如何处理尾随空格:
- 对于
PAD SPACE
归类,尾随空格在比较中微不足道;比较字符串时不考虑任何尾随空格。 NO PAD
归类将字符串末尾的空格与其他任何字符一样对待。
可以使用两种utf8mb4
二进制校验规则来证明不同的行为,其中一种是PAD SPACE
,另一种是NO PAD
。该示例还显示了如何使用该INFORMATION_SCHEMA
COLLATIONS
表确定校验规则的pad属性。
mysql>SELECT COLLATION_NAME, PAD_ATTRIBUTEFROM INFORMATION_SCHEMA.COLLATIONSWHERE COLLATION_NAME LIKE 'utf8mb4%bin'; +------------------ +--------------- + | COLLATION_NAME | PAD_ATTRIBUTE | +------------------ +--------------- + | utf8mb4_bin | PAD SPACE | | utf8mb4_0900_bin | NO PAD | +------------------ +--------------- + mysql>SET NAMES utf8mb4COLLATE utf8mb4_bin; mysql>SELECT 'a ' = 'a'; +------------ + | 'a ' = 'a' | +------------ + | 1 | +------------ + mysql>SET NAMES utf8mb4COLLATE utf8mb4_0900_bin; mysql>SELECT 'a ' = 'a'; +------------ + | 'a ' = 'a' | +------------ + | 0 | +------------ +
对于二进制字符串(BINARY
,VARBINARY
和BLOB
值),所有字符在比较中都有效,包括结尾空格:
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 utf8COLLATE utf8_bin, b BINARY(10) ); mysql>INSERT INTO t1VALUES ('x','x'); mysql>INSERT INTO t1VALUES ('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 | +------ +------------ +-------- +---------------------- +