BINARY和VARBINARY类型与CHAR和VARCHAR类似,只是它们存储的是二进制字符串而不是非二进制字符串。也就是说,它们存储字节字符串而不是字符串。这意味着它们具有二进制字符集和排序规则,并且比较和排序基于值中字节的数值。
对于BINARY和VARBINARY,允许的最大长度与CHAR和VARCHAR相同,只是BINARY和VARBINARY的长度是以字节而不是字符度量的。
BINARY和VARBINARY数据类型不同于CHAR BINARY和VARCHAR BINARY数据类型。对于后一种类型,BINARY属性不会将列视为二进制字符串列。相反,它将使用列字符集(如果未指定列字符集,则使用表默认字符集)的二进制`(_bin)'排序规则,并且列本身存储非二进制字符串,而不是二进制字节字符串。例如,如果默认字符集是utf8mb4,则CHAR(5)BINARY被视为CHAR(5)character set utf8mb4 COLLATE utf8mb4_bin。这与BINARY(5)不同,后者存储具有二进制字符集和排序规则的5字节二进制字符串。
如果未启用严格的SQL模式,并且您为BINARY或VARBINARY列分配的值 超过了列的最大长度,则该值将被截断以适合并生成警告。对于截断的情况,要导致发生错误(而不是警告)并抑制该值的插入,请使用严格的SQL模式。
当存储二进制值时,它们用pad值填充到指定的长度。pad值为0x00(零字节)。值用0x00右填充以进行插入,并且不删除用于检索的尾随字节。所有字节在比较中都是重要的,包括按顺序和不同的操作。0x00和space的比较不同,0x00在space之前排序。
示例:对于BINARY(3)列, 在插入时'a '变为 'a \0'。 插入时'a\0'变为'a\0\0'。两个插入的值均保持不变以进行检索。
对于VARBINARY,不存在插入的填充,也不剥离用于检索的字节。所有字节在比较中都是重要的,包括按顺序和不同的操作。0x00和space的比较不同,0x00在space之前排序。
对于剥离尾随字节或比较忽略它们的情况,如果一列具有要求唯一值的索引,则将仅尾随字节数不同的值插入该列会导致重复键错误。例如,如果表包含'a',则尝试存储'a\0'会导致重复键错误。
如果打算使用BINARY数据类型存储二进制数据并且要求检索的值与存储的值完全相同,则应仔细考虑上述填充和剥离特性 。以下示例说明了 值的0x00填充如何影响 YBINAR列值比较:
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数据类型来代替。