如果我们使用varchar存储字符串并对不同的varchar列使用不同的排序规则,那么我们可能会在Sql查询中得到错误“排序规则混合无效”。 (例如,如果我们想要比较两个不兼容排序规则的字符串,或尝试将不同排序规则的数据选择到一个组合列中)。
但是,如果我们在查询中指定“COLLATE”,那么这可以被修复。例如:
WHERE 'A' COLLATE latin1_general_ci = 'A' COLLATE latin1_general_cs .
但是,这会破坏您可能拥有的任何INDEX。
为了防止“归类错误混合”错误,我们可以使用varbinary。
如果varchar列使用多字节归类,则varbinary会比varchar使用更少的空间。 (二进制字符串没有字符集和归类,二进制字符串只是一个字节值序列)。但是,如果您选择单字节字符集(对于ex,latin1)而不是多字节字符集(对于ex,utf8或ucs2),则varbinary和varchar的空间要求是相同的。
如果没有有效性检查,则VARBINARY优于VARCHAR。 例如,如果默认字符集是UTF8,那么这是非法的:
CREATE TABLE t9 (s1 VARCHAR(5));
INSERT INTO t9 VALUES (0xF4808283);
但是,由于字符集没有关系,这是合法的:
CREATE TABLE t10 (s1 VARBINARY(5));
INSERT INTO t10 VALUES (0xF4808283);
所以,VARCHAR比较使用的字符“排序”和VARBINARY比较字节。大多数排序规则是“不区分大小写”,所以大写和小写被认为是相等的。因为,varbinary不使用任何排序规则,所以在varbinary的情况下,搜索操作总是区分大小写。
我相信预期varbinary数据通常会比原始字符串的每个部分的varchar one(10或11,我认为)消耗更少的字节(5),因此,对于非常大量的组件,或比较发生,它应该更有效率。但是我也猜测,对于大多数用户来说效率并没有太大的实际差异。 – 2011-05-12 14:20:53
@Damien:为此欢呼。我很乐意接受并接受这个答案!如果你选择这样做,将会这样做。 – 2011-05-12 14:34:41
我会假设这是因为结果将用于排序,二进制可能更有效,因为它不必担心排序问题。但不确定这是否是真的,一般情况下也是如此,即使真的如此,也不知道如何比较使用二进制“collate”子句对字符串进行排序。 – 2011-05-12 15:31:31