SQL Server CHECKSUM函数问题

时间:2018-10-05 16:53:44

标签: sql-server checksum

任何人都可以向我解释,也许可以提出更好的方法。

为什么校验和(0.0280)=校验和(-0.0280)? 强制浮动可以解决该问题,但我不愿意这样做,我宁愿找到解决方法。

LE:我一直想让事情保持简单,因为这里的大多数问题都是在生产中出现的,因此将整个数据库结构放的有些过头了。 我会尽力解释一下。我有一些动态结构表(在最终用户通过Web应用程序控制结构的意义上来说是动态的),它们具有以下大致结构:Id(int),StartDate,FKey1(nvarchar),Value1(十进制或nvarchar或int),值2 ...值N。

可以用冗余数据(数百万行)填充(再次由最终用户使用)此表,在进行某些计算时,我希望整理一下该表,仅保留相关信息。整理它的方法是删除连续的相同行(日期除外)。为了提高性能,我想避免单独检查每个列,因此CHECKSUM派上了用场,因为它还支持多列作为输入。

2 个答案:

答案 0 :(得分:2)

如果您认为每种可能的CHECKSUM都只有一个可能值,那您就错了。

来自documentation

  

如果表达式列表中的至少一个值发生更改,则列表   校验和可能会更改。但是,这不能保证。   因此,要检测值是否已更改,我们建议使用   仅当您的应用程序可以容忍偶尔丢失时才使用CHECKSUM   更改。否则,请考虑改用HashBytes。使用指定的MD5哈希算法,与CHECKSUM相比,对于两个不同的输入,HashBytes返回相同结果的可能性要低得多。

如果您想进一步研究,可以使用Google CHECKSUM collisions

答案 1 :(得分:0)

使用散列函数(例如CHECKSUM),总是会有冲突的风险。

您可以尝试另一个(较慢的)哈希函数(例如@TabAlleman提到的HashBytes),也可以尝试做一些自制尝试,这些尝试可能比HashBytes更好(但是应该对此进行测试),并且更适合您的预期您期望进入的数量。所以这是一个权衡:性能与碰撞风险。这是2种这样的自制尝试,对于除数字之外的相等数字,它们将给出不同的结果。请注意,这些变体也会产生碰撞,但很可能是其他差异,而不仅仅是其符号。

select checksum(.028, floor(.28))
select checksum(-.028, floor(-.28))

select checksum(.028) + sign(.28)
select checksum(-.028) + sign(-.28)

当您说可以通过强制转换为浮点数来解决它,但仍然不想这样做时,我想知道这是否出于性能考虑。如果是这样,我不确定我的变体是否会比强制转换为浮点型更好。可以自己测量一下:-)