11.3.3 BINARY 和 VARBINARY 类型

BINARYVARBINARY类型与CHARVARCHAR类似,除了它们存储二进制字符串而不是非二进制字符串。即,它们存储字节字符串而不是字符串。这意味着它们具有binary字符集和排序规则,并且比较和排序基于值中字节的数字值。

BINARYVARBINARY的最大允许长度与CHARVARCHAR的最大长度相同,除了BINARYVARBINARY的长度以字节而不是字符为单位。

BINARYVARBINARY数据类型不同于CHAR BINARYVARCHAR 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 模式,并且您为BINARYVARBINARY列分配的值超过了该列的最大长度,则该值将被截断以适合并生成警告。对于截断的情况,要导致发生错误(而不是警告)并禁止插入值,请使用严格的 SQL 模式。参见第 5.1.10 节“服务器 SQL 模式”

存储BINARY个值时,将使用填充值将其右填充到指定的长度。填充值为0x00(零字节)。值用0x00右填充以进行插入,并且不删除尾随字节以进行检索。所有字节在比较中都是有效的,包括ORDER BYDISTINCT操作。 0x00和空格在比较中有所不同,0x00在空格之前排序。

示例:对于BINARY(3)列,插入时'a '变为'a \0'。插入时,'a\0'变为'a\0\0'。两个插入的值均保持不变以进行检索。

对于VARBINARY,插入没有填充,也没有剥离任何字节以进行检索。所有字节在比较中都是有效的,包括ORDER BYDISTINCT操作。 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)

如果检索到的值必须与为存储指定的值相同且没有填充,则最好使用VARBINARYBLOB数据类型之一。

首页