前段时间我在SQL Server中询问了有关层次结构/版本号排序的问题。 ( How Can I Sort A 'Version Number' Column Generically Using a SQL Server Query)。
提交的答案中有this link to a TSQL Coding challenge with much the same puzzle。
在SQL2000解决方案中,作者演示了两个变体,一个使用并返回varchar和另一个varbinary。作者解释说他没有解释为什么这样做。
所以,我的问题是,方法上的差异有哪些主要差异/优点(如果有的话)?即为什么使用varbinary而不是varchar?
我省略了发布代码,因为它在上面的文章中总结得最为优雅。
答案 0 :(得分:14)
我相信期望varbinary数据通常比原始字符串的每个部分的varchar one(10或11)消耗更少的字节(5),因此,对于非常大量的组件,或者进行比较,它应该更有效率。
但是我建议如果你想要使用任何一个解决方案,你实现两个(它们很短),并尝试对你的真实数据(和查询模式)进行一些分析,看看是否有实用差异(我不希望如此)。
(Crafty Steal):正如Martin指出的那样,二进制比较将更有效率,因为它不会涉及处理排序规则的所有代码。 : - )
答案 1 :(得分:4)
如果我们对不同的varchar列使用不同的排序规则来存储字符串并在sql查询中使用多个这样的列,那么sql查询可能会抛出错误"无效的排序组合"。 (例如,如果我们想要比较两个不兼容的排序字符串或尝试选择不同排序规则的数据到组合列中)。
但是,如果我们指定" COLLATE"在查询中。例如:
WHERE 'A' COLLATE latin1_general_ci = 'A' COLLATE latin1_general_ci
但是,这会击败你可能拥有的任何指数。
防止"无效的排序组合"错误,我们可以使用varbinary。
如果varchar列使用多字节排序规则,则varbinary使用的空间比varchar少。 (二进制字符串没有字符集和排序规则。二进制字符串只是一个字节值序列。)***顺便说一句,字符集是一组符号和编码。排序规则是一组用于比较字符集https://dev.mysql.com/doc/refman/5.7/en/charset-general.html
中的字符的规则但是,如果选择单字节字符集(例如,latin1)而不是多字节字符集(例如,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使用" collation"来比较字符。和VARBINARY比较字节。大多数校对都是"不区分大小写",因此大写和小写被认为是相等的。因为varbinary不使用任何排序规则,所以在varbinary的情况下,搜索操作总是区分大小写。