在这里使用varbinary相比于varchar的优势是什么?
在这里使用varbinary相比于varchar的优势是什么?
前段时间我在SQL Server中提出了一个有关层次结构/版本号排序的问题(链接:如何使用SQL Server查询对“版本号”列进行通用排序)。
在提交的答案中,有一个答案是这个链接,其中有一个类似的谜题的TSQL编码挑战。
在SQL2000的解决方案中,作者演示了两种变体,一种使用和返回varchar,另一种使用varbinary。作者解释了他这样做的原因,但没有解释为什么。
所以,我的问题实际上是,这种方法的主要差异/优势(如果有的话)是什么?即为什么要使用varbinary而不是varchar?
我没有发布代码,因为在上述文章中已经很好地总结了。
使用varbinary相对于varchar的优势是,varbinary数据通常会占用较少的字节数(大约5个字节),而每个原始字符串的部分varchar数据占用10或11个字节,因此对于非常大量的组件或比较操作,varbinary应该更高效。
作者建议如果您打算使用其中一种解决方案,最好同时实现两种方案(它们非常简短),并针对您的真实数据(和查询模式)进行一些性能分析,以查看是否存在实际差异(但他并不期望会有太大差异)。
正如Martin指出的,二进制比较会更高效,因为它不涉及处理字符集排序规则的所有代码。
以上是对于"使用varbinary相对于varchar的优势"这个问题的原因和解决方法的整理。
使用varbinary而不是varchar的优势是什么?
当我们在sql查询中使用不同的varchar列存储字符串,并且使用多个这样的列时,如果我们为不同的varchar列使用不同的排序规则,那么sql查询可能会抛出“无效的排序规则混合”的错误(例如,如果我们想要比较两个不兼容的排序规则的字符串,或者尝试将不同排序规则的数据选择到一个组合列中)。
但是,如果我们在查询中指定“COLLATE”,这个问题是可以解决的。例如:
WHERE 'A' COLLATE latin1_general_ci = 'A' COLLATE latin1_general_ci
但是,这会破坏任何可能存在的索引。
为了避免“无效的排序规则混合”错误,我们可以使用varbinary。
如果为varchar列使用多字节排序规则,那么varbinary使用的空间比varchar要少(二进制字符串没有字符集和排序规则。二进制字符串只是一系列字节值)。
顺便说一下,字符集是一组符号和编码。排序规则是一组比较字符的规则。
但是,如果选择单字节字符集(例如,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使用“排序规则”比较字符,而VARBINARY比较字节。大多数排序规则是“不区分大小写”的,所以大写和小写被视为相等。由于varbinary不使用任何排序规则,所以在varbinary的情况下,搜索操作始终区分大小写。