2010-10-28 77 views
2

我们目前正在广泛使用GetHashCode方法将散列码存储在数据库中以跟踪唯一项目。 MSDN在这里有一个可怕的条目使用ToHashCode将散列存储在数据库中?

“GetHashCode方法的默认实现不保证不同对象的唯一返回值。此外,.NET Framework不保证GetHashCode方法的默认实现,并且值它返回的结果在不同版本的.NET Framework之间是相同的,因此,此方法的默认实现不能用作用于散列目的的唯一对象标识符。“

我们一直在使用这种方法几年没有问题。我们是否应该担心,如果是的话,那么更好的方法是什么?

详细说明,数据来自外部来源。我们需要两到三个字符串字段,将它们一起添加到一个新字符串中,然后使用GetHashCode关闭该字符串。

回答

2

使用哈希码作为唯一标识符是一个非常糟糕的主意,因为如果集合足够大,最终可以确保发生冲突 - 而且它不必非常大统计上可能会发生碰撞。哈希代码是评估两个对象是否相同(假设哈希函数相同)的好方法 - 如果它们哈希到不同的值,它们肯定是不同的。但是,如果它们散列到相同的值,则需要进行相等比较以确保它们是相同的对象。此时,您需要比较使其具有唯一性的对象的属性,即如果这些属性相同,则对象是相同的。

我建议在自然键属性的数据库中使用一个唯一索引,并将人工自动增量ID作为主键。然后你可以确定你没有在数据库中获得重复插入(索引的唯一性约束),但是你可以通过简单地比较它们是否具有相同的ID来快速比较数据库外部的对象 - 也保证是唯一的由主键约束。

2

是的。害怕。 GetHashCode不可能在大于32位的任何类型上提供无冲突保证。鉴于在某些情况下,GetHashCode的实现可能不够完美(即某些类实现了自己的不合理版本),在某些情况下,风险可能会更高。无论如何,这是一种糟糕的做法,需要重新思考。

我建议阅读一下哈希表如何工作,以便更好地理解哈希码的用途。这实际上只是快速存储的启发性措施。

0

GetHashCode不可靠。

您在这方面有两种选择:

  1. 覆盖GetHashCode方法 ,并使其返回,而不是 整数的GUID。
  2. 让您的数据库为您创建唯一的ID值 。
+1

挪用GetHashCode在调用之间返回不同的值是一个可怕的想法,并且会打破比修复更多的问题。选项2将您从-1保存。 – spender 2010-10-28 02:09:39

+0

嗯...似乎很奇怪,因为MSDN建议覆盖GetHashCode以确保它返回唯一值。 – 2010-10-28 02:16:04

+0

但每次都必须为对象返回相同的唯一值。每次生成一个新的Guid都会违反该规则。弄清楚如何每次检索相同的Guid比使用确定性算法为复杂对象构建唯一值的工作要多得多。 – tvanfosson 2010-10-28 02:22:18

相关问题