BINARY
和 VARBINARY
类型与 CHAR
和 VARCHAR
相似,除了它们存储二进制字符串而不是非二进制字符串。也就是说,它们存储字节字符串而不是字符字符串。这意味着它们具有 binary
字符集和排序规则,并且比较和排序基于值中的字节的数字值。
允许的最大长度对于 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 字节的二进制字符串,具有 binary
字符集和排序规则。有关二进制排序规则与非二进制字符集的 _bin 排序规则之间的差异,请参阅 第 12.8.5 节,“二进制排序规则与 _bin 排序规则的比较”。
如果未启用严格 SQL 模式,并且您将值分配给 BINARY
或 VARBINARY
列,超过该列的最大长度,该值将被截断以适应,并生成警告。对于截断的情况,要使错误发生(而不是警告)并抑制值的插入,请使用严格 SQL 模式。请参阅 第 7.1.11 节,“服务器 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
排序在空格之前。
对于那些情况,尾随填充字节被删除或比较忽略它们,如果列有一个需要唯一值的索引,将不同的尾随填充字节的值插入到列中将导致重复键错误。例如,如果表中包含 'a'
,尝试存储 'a\0'
将导致重复键错误。
如果您计划使用 BINARY
数据类型来存储二进制数据,并且需要检索的值与存储的值完全相同,那么请仔细考虑前面的填充和删除特性。以下示例说明了 0x00
-填充对 BINARY
值比较的影响:
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
数据类型可能更好。
在 mysql 客户端中,二进制字符串使用十六进制表示法,取决于 --binary-as-hex
选项的值。有关该选项的更多信息,请参阅 第 6.5.1 节,“mysql — The MySQL Command-Line Client”。