创建一个hashcode在数据库中使用(即不使用GetHashCode)

本文关键字:GetHashCode 一个 hashcode 创建 数据库 | 更新日期: 2023-09-27 18:12:56

我最近被告知GetHashCode()的方式,特别是"GetHashCode的消费者不能依赖它随时间或跨应用领域的稳定"(来自Eric Lippert博客文章)。

不幸的是,我一直在使用这个在数据库中,试图加快查找(通过插入GetHashCode的结果,而不是做搜索文本字符串)。我现在意识到这是一件非常糟糕的事情。

所以我想知道我能做些什么来代替。是否有任何给定字符串将保证返回一个合理的抗碰撞整数,我可以用于查找?

我可以自己写一些东西,但我希望有一些内置的东西,我可以使用,而不必去加密库中的东西,感觉有点重

创建一个hashcode在数据库中使用(即不使用GetHashCode)

我鼓励您考虑其他人所说的:让数据库做它擅长的事情。为了优化查找而创建哈希码,这表明表上的索引没有达到应有的水平。

也就是说,如果你真的需要一个哈希码:

你没有说你想要32位还是64位的哈希码。它将为字符串创建64位哈希码。这是合理的抗碰撞。

public static long ComputeHashCode(string url)
{
    const ulong p = 1099511628211;
    ulong hash = 14695981039346656037;
    for (int i = 0; i < url.Length; ++i)
    {
        hash = (hash ^ url[i]) * p;
    }
    // Wang64 bit mixer
    hash = (~hash) + (hash << 21);
    hash = hash ^ (hash >> 24);
    hash = (hash + (hash << 3)) + (hash << 8);
    hash = hash ^ (hash >> 14);
    hash = (hash + (hash << 2)) + (hash << 4);
    hash = hash ^ (hash >> 28);
    hash = hash + (hash << 31);
    if (hash == (ulong)UNKNOWN_RECORD_HASH)
    {
        ++hash;
    }
    return (long)hash;
}

注意,这是一个哈希码,如果你有几十亿条记录,碰撞的可能性是非常小的。经验法则:当项目数量超过哈希码范围的平方根时,你有50%的几率发生碰撞。这个哈希码的范围是2^64,所以如果你有2^32个项目,碰撞的几率大约是50%。

详情请参阅http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=792和http://en.wikipedia.org/wiki/Birthday_paradox#Probability_table

正如SLaks在评论中指出的那样,查找数据是数据库所擅长的。

如果您需要快速查找,请在列上创建索引。至少,您不必再处理碰撞了。

您是否使用MSSQL数据库?T-SQL Checksum函数就是这样做的。