11.3.3 BINARY 和 VARBINARY 类型
BINARY
和VARBINARY
类型与CHAR和VARCHAR类似,除了它们存储二进制字符串而不是非二进制字符串。即,它们存储字节字符串而不是字符串。这意味着它们具有binary
字符集和排序规则,并且比较和排序基于值中字节的数字值。
BINARY
和VARBINARY
的最大允许长度与CHAR和VARCHAR的最大长度相同,除了BINARY
和VARBINARY
的长度以字节而不是字符为单位。
BINARY
和VARBINARY
数据类型不同于CHAR BINARY
和VARCHAR BINARY
数据类型。对于后一种类型,BINARY
属性不会导致该列被视为二进制字符串列。相反,它将导致使用列字符集(如果未指定列字符集,则使用 table 默认字符集)的二进制(_bin
)排序规则,并且列本身存储非二进制字符串,而不是二进制字节字符串。例如,如果默认字符集为latin1
,则CHAR(5) BINARY
被视为CHAR(5) CHARACTER SET latin1 COLLATE latin1_bin
。这不同于BINARY(5)
,后者存储具有binary
字符集和排序规则的 5 字节二进制字符串。有关binary
字符集的binary
归类和非二进制字符集的_bin
归类之间的差异的信息,请参见第 10.8.5 节“与_bin 归类相比的二进制归类”。
如果未启用严格的 SQL 模式,并且您为BINARY
或VARBINARY
列分配的值超过了该列的最大长度,则该值将被截断以适合并生成警告。对于截断的情况,要导致发生错误(而不是警告)并禁止插入值,请使用严格的 SQL 模式。参见第 5.1.10 节“服务器 SQL 模式”。
存储BINARY
个值时,将使用填充值将其右填充到指定的长度。填充值为0x00
(零字节)。值用0x00
右填充以进行插入,并且不删除尾随字节以进行检索。所有字节在比较中都是有效的,包括ORDER BY
和DISTINCT
操作。 0x00
和空格在比较中有所不同,0x00
在空格之前排序。
示例:对于BINARY(3)
列,插入时'a '
变为'a \0'
。插入时,'a\0'
变为'a\0\0'
。两个插入的值均保持不变以进行检索。
对于VARBINARY
,插入没有填充,也没有剥离任何字节以进行检索。所有字节在比较中都是有效的,包括ORDER BY
和DISTINCT
操作。 0x00
和空格在比较中有所不同,0x00
在空格之前排序。
对于剥离尾随字节或比较忽略它们的情况,如果一列具有要求唯一值的索引,则将仅尾随字节数不同的值插入该列会导致重复键错误。例如,如果 table 包含'a'
,则尝试存储'a\0'
会导致重复键错误。
如果打算使用BINARY
数据类型存储二进制数据,并且要求检索的值与存储的值完全相同,则应仔细考虑上述填充和剥离特性。以下示例说明了BINARY
值的0x00
填充如何影响列值比较:
mysql> CREATE TABLE t (c BINARY(3));
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t SET c = 'a';
Query OK, 1 row affected (0.01 sec)
mysql> SELECT HEX(c), c = 'a', c = 'a\0\0' from t;
+--------+---------+-------------+
| HEX(c) | c = 'a' | c = 'a\0\0' |
+--------+---------+-------------+
| 610000 | 0 | 1 |
+--------+---------+-------------+
1 row in set (0.09 sec)
如果检索到的值必须与为存储指定的值相同且没有填充,则最好使用VARBINARY
或BLOB数据类型之一。