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)
,它存储具有 binary
字符集和排序规则的 5 字节二进制字符串。有关 binary
字符集的 binary
排序规则与非二进制字符集的 _bin
排序规则之间差异的信息,请参见 第 12.8.5 节,“binary 排序规则与 _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
数据类型存储二进制数据并且需要检索到的值与存储的值完全相同,那么您应该仔细考虑上述填充和删除特性。以下示例说明了 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
数据类型。
在 mysql 客户端中,二进制字符串使用十六进制表示法显示,具体取决于 --binary-as-hex
的值。有关该选项的更多信息,请参见 第 6.5.1 节,“mysql — MySQL 命令行客户端”。