在HashBytes函数中选择正确的算法


20

我们需要创建nvarchar数据的哈希值以进行比较。T-SQL中有多种可用的哈希算法,但是在这种情况下,哪一种是最好的选择?

我们要确保两个不同的nvarchar值具有重复哈希值的风险最小。根据我对互联网的研究,MD5似乎是最好的。那正确吗?MSDN向我们(下面的链接)介绍了可用的算法,但是没有说明在哪种条件下使用哪种算法?

哈希(Transact-SQL)

我们需要在两个nvarchar(max)列上联接两个表。可以想象,查询需要一段时间才能执行。我们认为最好保留每个nvarchar(max)数据的哈希值,然后对哈希值进行联接,而不是blob的nvarchar(max)值。问题是哪种哈希算法提供了唯一性,因此我们不会遇到为多个nvarchar(max)拥有一个哈希值的风险。

Answers:


18

HASHBYTES功能最多占用8000个字节作为输入。由于您的输入可能大于输入,因此,无论选择哪种算法,在散列字段范围内的重复项都会导致冲突。仔细考虑您计划散列的数据范围-使用前4000个字符是显而易见的选择,但可能不是最佳选择。

无论如何,由于哈希函数是什么,即使输入为8000字节或更小,确保结果100%正确的唯一方法是在某个点比较基值(阅读:不一定是first)。期。

企业将决定是否需要100%的准确性。这会告诉你,要么(一)比较的基础值是必需的,或(b)您应考虑 比较的基础值-多少精度应为性能进行权衡。

尽管在唯一的输入集中可能发生哈希冲突,但无论选择哪种算法,它们都是极其罕见的。在这种情况下,使用哈希值的整个想法是有效地将联接结果缩小为更易于管理的集合,而不必立即得出最终结果集。同样,对于100%的准确性,这不是过程的最后一步。这种情况不是出于加密目的而使用散列,因此MD5之类的算法可以正常工作。

对于我来说,为“准确性”目的而升级为SHA-x算法是非常困难的,因为如果企业对MD5的微小碰撞可能性感到恐惧,那么他们也有可能感到恐惧。 SHA-x算法也不是完美的。他们要么不得不稍有不准确,要么要求查询必须100%准确并具有相关的技术含义。我想,如果CEO知道您使用SHA-x而不是MD5,则晚上睡得更好,那很好。在这种情况下,从技术角度来看,这仍然没有多大意义。

说到性能,如果表是只读的并且频繁需要连接结果,请考虑实现索引视图,以消除每次请求时都计算整个连接的需要。当然,您需要为此权衡存储,但是对于提高性能可能是值得的,尤其是在要求100%精度的情况下。

为了进一步阅读如何为长字符串值建立索引,我发表了一篇文章,其中提供了一个如何针对单个表执行此操作的示例,并介绍了尝试使用此问题的完整方案时要考虑的事项。


8

MD5应该很好,输出可以存储在二进制文件(16)中。即使有较大的物理样本量,发生碰撞的可能性(参见生日悖论)仍然非常低。SHA-1的输出占用20个字节,SHA-256的输出占用32个字节。除非您有如此多的记录,以至于您的生日碰撞概率变得很大(实际上是不可能的,或者至少对于当前的硬件技术而言是不切实际的),否则它可能是可以的。



0

我没有看到答案中提到的这个 MSDN

从SQL Server 2016(13.x)开始,不推荐使用SHA2_256和SHA2_512以外的所有算法。较旧的算法(不建议使用)将继续工作,但是会引发弃用事件。

我问了一个类似的问题,所以要使用不推荐使用的功能(例如MD5)(如果您使用的是2016年以上版本),则取决于您。您可以进行测试,以查看MD5和SHA2在存储和性能上有多少差异。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.