在这里使用varbinary over varchar有什么好处?

Jam*_*man 19 sql sql-server varchar varbinary

前一段时间我问了一个关于SQL Server中层次结构/版本号排序的问题.( 如何使用SQL Server查询对"版本号"列进行排序).

提交的答案中包含了与TSQL编码挑战相关的链接.

在SQL2000解决方案中,作者演示了两个变体,一个使用并返回varchar,另一个使用varbinary.作者解释说他没有解释为什么这样做.

那么,我的问题是,方法上的差异有哪些主要差异/优势(如果有的话)?即为什么使用varbinary而不是varchar?

我省略了发布代码,因为它在上面的文章中总结得最为优雅.

Dam*_*ver 14

我相信期望的是varbinary数据通常比原始字符串的每个部分的varchar one(10或11,我认为)消耗更少的字节(5),因此,对于非常大量的组件,或者比较到发生,应该更有效率.

但我建议,如果你正在寻找为使用的解决方案,你同时实现(他们是很短),并尝试对你的真实数据(和查询模式),一些分析,看看是否有实际的差别(我我不希望如此).

(Crafty Steal):正如Martin指出的那样,二进制比较将更有效率,因为它不会涉及处理排序规则的所有代码.:-)


sud*_*dip 5

如果我们对不同的 varchar 列使用不同的排序规则来存储字符串并在 sql 查询中使用多个这样的列,那么 sql 查询可能会抛出错误“排序规则混合无效”。(例如,如果我们要比较两个不兼容排序规则的字符串或尝试将不同排序规则的数据选择到组合列中)。

但是,如果我们在查询中指定“COLLATE”,这可以解决。例如:

 WHERE 'A' COLLATE latin1_general_ci = 'A' COLLATE latin1_general_ci 
Run Code Online (Sandbox Code Playgroud)

但是,这会打败您可能拥有的任何 INDEX。

为了防止“无效的排序规则混合”错误,我们可以使用 varbinary。

如果对 varchar 列使用多字节归类,则 varbinary 使用的空间比 varchar 少。(二进制字符串没有字符集和排序规则。二进制字符串只是字节值的序列)。

*** 顺便说一句,字符集是一组符号和编码。排序规则是一组用于比较字符集中字符的规则https://dev.mysql.com/doc/refman/5.7/en/charset-general.html

但是,如果您选择单字节字符集(例如 ex、latin1)而不是多字节字符集(例如 ex、utf8 或 ucs2),则 varbinary 和 varchar 的空间要求是相同的。

如果没有有效性检查,VARBINARY 比 VARCHAR 更好。例如,如果默认字符集是 UTF8,那么这是非法的:

CREATE TABLE t9 (s1 VARCHAR(5));
INSERT INTO t9 VALUES (0xF4808283);
Run Code Online (Sandbox Code Playgroud)

但是,这是合法的,因为字符集无关紧要:

CREATE TABLE t10 (s1 VARBINARY(5));
INSERT INTO t10 VALUES (0xF4808283);
Run Code Online (Sandbox Code Playgroud)

因此,VARCHAR 使用“排序规则”和 VARBINARY 比较字节来比较字符。大多数排序规则“不区分大小写”,因此大写和小写被认为是相等的。由于 varbinary 不使用任何排序规则,因此在 varbinary 的情况下,搜索操作始终区分大小写。