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

Sky*_*Sky 22 sql-server t-sql sql-server-2008-r2 hashing

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

我们希望确保两个不同的 nvarchar 值具有重复哈希值的风险最小。根据我对互联网的研究,MD5 似乎是最好的。那正确吗?MSDN 告诉我们(下面的链接)有关可用算法的信息,但没有说明哪一种适用于什么条件?

哈希字节 (Transact-SQL)

我们需要在两个 nvarchar(max) 列上连接两个表。可以想象,执行查询需要很长时间。我们认为最好保留每个 nvarchar(max) 数据的散列值并对散列值进行连接,而不是 nvarchar(max) 值是 blob。问题是哪种哈希算法提供了唯一性,这样我们就不会遇到一个哈希值对应多个 nvarchar(max) 的风险。

Jon*_*gel 19

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

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

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

虽然哈希冲突在唯一的输入集中是可能的,但无论选择何种算法,它们都是非常罕见的。在这种情况下使用散列值的整个想法是有效地将连接结果缩小到一个更易于管理的集合,而不必立即到达最终的结果集合。同样,对于 100% 的准确度,这不能是过程的最后一步。这个场景不是为了加密目的使用散列,所以像 MD5 这样的算法会很好地工作。

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

说到性能,如果表主要是读取并且经常需要连接结果,请考虑实现索引视图以消除每次请求时都计算整个连接的需要。当然,您会为此牺牲存储,但对于性能改进而言,这样做可能是值得的,尤其是在需要 100% 准确度的情况下。

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


Con*_*lls 8

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