MySQL中的"VARCHAR BINARY"和"VARBINARY"有什么区别?

9

我创建了以下测试表:

CREATE TABLE t (
   a VARCHAR(32) BINARY,
   b VARBINARY(32)
);

INSERT INTO t (a, b) VALUES ( 'test    ', 'test    ');
INSERT INTO t (a, b) VALUES ( 'test    \0', 'test    \0');

但是这个查询没有显示出这两种类型之间的差异:
SELECT a, LENGTH(a), HEX(a), b, LENGTH(b), HEX(b) FROM t;

a          LENGTH(a)  HEX(a)              b          LENGTH(b)  HEX(b)              
---------  ---------  ------------------  ---------  ---------  --------------------
test               8  7465737420202020    test               8  7465737420202020    
test               9  746573742020202000  test               9  746573742020202000  

1
请阅读 https://dev.mysql.com/doc/refman/5.0/en/binary-varbinary.html 的第一段。 - Barmar
1
@Barmer 我认为你需要继续阅读第一段之后才能弄清楚它们之间的区别。如果这不是一个重复的问题,我认为我们需要在stackoverflow上提供一个好的答案。你在问题中看不到差异,但要了解它的影响,请查看手册的这个页面:https://dev.mysql.com/doc/refman/5.0/en/charset-binary-collations.html 那里有一些例子。 - Martin Burch
2个回答

10

以下是我通过阅读文档找到的区别:

VARCHAR BINARY

  • BINARY属性会使用字符集的二进制排序规则,并且该列本身包含非二进制字符字符串而不是二进制字节字符串。
  • 存储BINARY值时,它们将被右填充到指定长度。
  • 如果您计划使用BINARY数据类型存储二进制数据并且需要检索的值与存储的值完全相同,则应仔细考虑前面的填充和剥离特性。

VARBINARY

  • 如果未启用严格的SQL模式并尝试分配超过列最大长度的值,则该值将被截断以适应,并生成警告。
  • 插入时没有填充,在选择时没有字节被剥离。在比较中所有字节都是重要的。
  • 当检索的值必须与存储的值相同且不填充时,使用更好。

2
谢谢您的回答。但是填充处理仅存在于CHAR和BINARY中,而不在VARCHAR或VARBINARY中。我刚在https://dev.mysql.com/doc/refman/5.0/en/charset-binary-collations.html找到了答案。总的来说,字符集转换和大小写转换是主要区别。 - Clarence
@Clarence,说得对。在VARBINARY部分,我指定了没有填充。我只提到了VARCHAR + BINARY类型的填充。 - Jean-François Savard

6
根据MySQL手册中的String Data Type Syntax页面所述,VARBINARY相当于VARCHAR CHARACTER SET binary,而VARCHAR BINARY相当于VARCHAR CHARACTER SET latin1 COLLATE latin1_bin(或具有相应二进制排序规则的其他非二进制字符集;这取决于表设置):
引用块: 指定字符类型数据类型的CHARACTER SET binary属性会导致该列作为相应的二进制字符串数据类型创建:CHAR变成BINARY,VARCHAR变成VARBINARY,TEXT变成BLOB。 BINARY属性是MySQL的非标准扩展,它是为指定列字符集的二进制(_bin)排序规则(或如果未指定列字符集,则为表默认字符集)提供的简写。
因此,VARBINARY存储字节;VARCHAR BINARY存储字符编码,但像字节一样进行排序(几乎如下)。
这在实践中意味着什么,在手册页The binary Collation Compared to _bin Collations中有解释:
  • VARBINARY通过逐字节比较进行排序;VARCHAR BINARY比较对应于字符的字节组(对于大多数编码来说,没有太大区别)
  • VARCHAR BINARY在从具有不同编码的另一列赋值或由具有不同编码的客户端插入/更新值时执行字符集转换;VARBINARY仅将该值作为原始字节字符串。
  • SQL中的大小写转换(即LOWER/UPPER函数)对VARBINARY没有影响(字节没有大小写之分)。
  • VARCHAR BINARY比较中通常会忽略尾随空格(即,'x ' = 'x'将为true)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接