BINARY 和 VARBINARY 类型
该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
字符集和校验规则。有关之间的差异信息binary
的核对binary
字符集和_bin
的非二进制字符集的校验规则,请参见“加密二进制日志文件”。
如果未启用严格的SQL模式,并且您为BINARY
或VARBINARY
列分配的值超过了列的最大长度,则该值将被截断以适合并生成警告。对于截断的情况,要导致发生错误(而不是警告)并抑制该值的插入,请使用严格的SQL模式。请参见“服务器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 tSET 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
数据类型来代替。