CHECKSUM()和BINARY_CHECKSUM()之间有什么区别?什么时候/什么是适当的使用场景?

时间:2009-08-06 17:51:30

标签: sql-server sql-server-2005

MSDN并没有真正用简单的英语解释确切的差异,或者何时选择其中一种的信息。

CHECKSUM

  

返回在表的一行或表达式列表上计算的校验和值。 CHECKSUM旨在用于构建哈希索引。

BINARY_CHECKSUM

  

返回通过表的行或表达式列表计算的二进制校验和值。 BINARY_CHECKSUM可用于检测表格行的更改。

它确实暗示应该使用二进制校验和来检测行更改,但不是为什么。

5 个答案:

答案 0 :(得分:17)

查看以下博文,重点介绍差异。

http://decipherinfosys.wordpress.com/2007/05/18/checksum-functions-in-sql-server-2005/

从此链接添加信息:

CHECKSUM函数的关键意图是基于表达式或列列表构建哈希索引。如果您使用它来计算和存储表级别的列以表示在表中使记录唯一的列上的校验和,那么这可以帮助确定行是否已更改。然后可以使用此机制而不是与使记录唯一的所有列连接以查看记录是否已更新。 SQL Server联机丛书有很多关于这个功能的例子。

使用这些功能时需要注意以下几点:

您需要确保正在比较的两个校验和之间的列或表达式顺序相同,否则值将会不同并将导致问题。

我们不建议使用校验和(*),因为以这种方式生成的值将基于运行时表定义的列顺序,这可以在一段时间内轻松更改。因此,明确定义列列表。

当您包含日期时间数据类型列时要小心,因为粒度是1/300秒,即使很小的变化也会导致不同的校验和值。因此,如果必须使用日期时间数据类型列,请确保获得确切的日期+小时/分钟。即你想要的粒度级别。

您可以使用三种校验和功能:

CHECKSUM:如上所述。

CHECKSUM_AGG:这将返回组中值的校验和,在这种情况下将忽略Null值。这也适用于SQL Server 2005中新的分析函数的OVER子句。

BINARY_CHECKSUM:如名称所示,它返回通过行或表达式列表计算的二进制校验和值。 CHECKSUM和BINARY_CHECKSUM之间的区别在于为字符串数据类型生成的值。这种差异的一个例子是为“DECIPHER”和“decipher”生成的值在BINARY_CHECKSUM的情况下会有所不同,但对于CHECKSUM函数将是相同的(假设我们对实例进行了不区分大小写的安装)。 另一个区别在于表达式的比较。如果两个表达式的元素具有相同的类型和字节表示,则BINARY_CHECKSUM()返回相同的值。因此,“2Volvo Director 20”和“3Volvo Director 30”将产生相同的值,但CHECKSUM()函数会评估类型以及比较两个字符串,如果它们相等,则只返回相同的值。

Example:
STRING              BINARY_CHECKSUM_USAGE    CHECKSUM_USAGE
------------------- ----------------------    -----------
2Volvo Director 20  -1356512636                -341465450
3Volvo Director 30  -1356512636                -341453853
4Volvo Director 40  -1356512636                -341455363

答案 1 :(得分:8)

带有MD5的HASHBYTES比CHECKSUM慢5倍,我在一个超过100万行的表上进行了测试,并且每次测试运行5次以获得平均值。

有趣的是CHECKSUM与BINARY_CHECKSUM完全相同。

以下是发布完整结果的帖子: http://networkprogramming.wordpress.com/2011/01/14/binary_checksum-vs-hashbytes-in-sql/

答案 2 :(得分:4)

我发现校验和冲突(即两个不同的值返回相同的校验和)比大多数人想象的更常见。我们有一个货币表,使用ISO货币代码作为PK。在一个少于200行的表中,有三对货币代码返回相同的Binary_Checksum():

  • “ETB”和“EUR”(埃塞俄比亚比尔和欧元)均返回16386.
  • “LTL”和“MDL”(立陶宛立特和摩尔多瓦列伊)均返回18700。
  • “TJS”和“UZS”(Somoni和Uzbekistan Som)均返回20723。

ISO文化代码也是如此:“de”和“eu”(德语和巴斯克语)都返回1573。

将Binary_Checksum()更改为Checksum()会修复这些情况下的问题......但在其他情况下,它可能无济于事。所以我的建议是在过分依赖这些功能的独特性之前进行彻底的测试。

答案 3 :(得分:3)

使用CHECKSUM时要小心,可能会得到意想不到的结果。以下语句产生相同的校验和值;

SELECT CHECKSUM (N'这么便宜怎么办?廉价iPhone售价再曝光', 5, 4102)
SELECT CHECKSUM (N'PlayStation Now – Sony startet Spiele-Streaming im Sommer 2014', 238, 13096)

答案 4 :(得分:2)

很容易从CHECKSUM()中获得冲突。在SQL 2005中添加了HASHBYTES()以增强SQL Server的系统哈希功能,因此我建议您也将此作为替代方案。