# 11.3.3 BINARY 和 VARBINARY 类型

二进制变量类型类似于字符VARCHAR,除了它们存储二进制字符串而不是非二进制字符串。也就是说,它们存储字节字符串而不是字符串。这意味着他们拥有二进制字符集和排序规则,以及比较和排序基于值中字节的数值。

允许的最大长度是相同的二进制变量因为它是为了字符VARCHAR,除了长度为二进制变量以字节而不是字符来衡量。

二进制变量数据类型不同于字符二进制VARCHAR 二进制数据类型。对于后一种类型,二进制属性不会导致该列被视为二进制字符串列。相反,它会导致二进制文件 (_bin) 要使用的列字符集(或表默认字符集,如果未指定列字符集)的排序规则,并且列本身存储非二进制字符串而不是二进制字节字符串。例如,如果默认字符集是utf8mb4,CHAR(5) 二进制被视为CHAR(5) 字符集 utf8mb4 整理 utf8mb4_bin.这不同于二进制(5),它存储 5 字节的二进制字符串,其中二进制字符集和排序规则。有关两者之间差异的信息二进制整理的二进制字符集和_bin非二进制字符集的排序规则,请参见第 10.8.5 节,“与_分类整理”.

如果未启用严格 SQL 模式并且您将值分配给二进制要么变量超过列的最大长度的列,该值将被截断以适应并生成警告。对于截断的情况,要导致发生错误(而不是警告)并禁止插入值,请使用严格的 SQL 模式。看第 5.1.11 节,“服务器 SQL 模式”.

什么时候二进制值被存储,它们用填充值右填充到指定的长度。垫值是0x00(零字节)。值右填充0x00插入,并且不删除尾随字节以进行检索。所有字节在比较中都很重要,包括订购方式清楚的操作。0x00和空间不同的比较,与0x00在空间之前排序。

示例:对于一个二进制(3)柱子,'一种 '变成'一个\0'插入时。'一个\0'变成'a\0\0'插入时。两个插入的值在检索时保持不变。

为了变量,插入没有填充,也没有字节被剥离以进行检索。所有字节在比较中都很重要,包括订购方式清楚的操作。0x00和空间不同的比较,与0x00在空间之前排序。

对于去除尾随填充字节或比较忽略它们的情况,如果列具有需要唯一值的索引,则将仅在尾随填充字节数不同的值插入列中会导致重复键错误。例如,如果一个表包含'一种', 尝试存储'一个\0'导致重复键错误。

如果您打算使用二进制存储二进制数据的数据类型,并且您要求检索的值与存储的值完全相同。以下示例说明了如何0x00-填充二进制values 影响列值比较:

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)

如果检索到的值必须与为没有填充的存储指定的值相同,则最好使用变量或其中之一斑点而是数据类型。

笔记

mysql客户端,二进制字符串使用十六进制表示法显示,具体取决于--binary-as-hex.有关该选项的更多信息,请参阅第 4.5.1 节,“mysql - MySQL 命令行客户端”.