创建一个hashcode在数据库中使用(即不使用GetHashCode)
本文关键字:GetHashCode 一个 hashcode 创建 数据库 | 更新日期: 2023-09-27 18:12:56
我最近被告知GetHashCode()的方式,特别是"GetHashCode的消费者不能依赖它随时间或跨应用领域的稳定"(来自Eric Lippert博客文章)。
不幸的是,我一直在使用这个在数据库中,试图加快查找(通过插入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
函数就是这样做的。