我知道 HashCodes 不是唯一的。如果哈希码在两个不同的字符串上返回匹配项,我们会对结果进行后处理以找到精确匹配项。它不用作主键。
我相信架构师的意图是通过查询 long 而不是 NVarChar 来加快搜索速度
那就让数据库为你索引字符串吧!
听着,我不知道您的域有多大,但是如果它的大小足够大,那么您将很快发生冲突,而且很有可能发生冲突。相对于生日的数量,这是很多人的生日问题。您将发生碰撞,并且失去任何您可能认为不仅通过首先索引字符串而获得的速度增益。
无论如何,如果您距离发布还有几天的时间,您就不需要我们,而且您确实需要跨平台的不变哈希码。您可以使用非常愚蠢、非常快速的哈希码实现。见鬼,你可以在眨眼之间自己想出一个:
string s = "Hello, world!";
int hash = 17;
foreach(char c in s) {
unchecked { hash = hash * 23 + c.GetHashCode(); }
}
或者您可以使用旧的 Bernstein 哈希。不断地。他们会给你带来你正在寻找的性能提升吗?我不知道,它们不应该用于此目的。它们旨在用于平衡哈希表。您没有平衡哈希表。你使用了错误的概念。
编辑(以下是在使用新的显着信息编辑问题之前编写的):
理论上,如果不对输入空间进行某种限制,您根本无法做到这一点。您的问题比String.GetHashCode 严重得多,因平台而异。
string 的实例很多。事实上,比Int32 的实例多得多。所以,由于 piegonhole 原则,你会发生碰撞。您无法避免这一点:您的strings 是鸽子,而您的Int32 哈希码是鸽笼,鸽笼中有太多鸽子可以进入鸽笼,而某些鸽笼不会超过一只鸽子。由于冲突问题,您不能使用哈希码作为字符串的唯一键。它不起作用。期间。
使当前提议的设计工作(使用Int32 作为string 实例的标识符)的唯一方法是将字符串的输入空间限制为大小小于或等于Int32s 的数量。即使这样,您也很难想出一种算法,以一种独特的方式将您的输入空间 strings 映射到 Int32。
即使您尝试使用 SHA-512 或其他方式增加鸽巢的数量,您仍然有可能发生冲突。我怀疑您之前在设计中考虑过这种可能性;此设计路径是 DOA。无论如何,这不是 SHA-512 的用途,它不能用于消息的唯一标识。这只是为了减少消息伪造的可能性。
更复杂的是,我们离发布太近了,无法重构我们的应用程序以停止序列化哈希码并只查询字符串。
好吧,那么你有大量的工作要做。很抱歉你在游戏中这么晚才发现这一点。
我注意到String.GetHashCode 的文档:
GetHashCode 的行为取决于它的实现,它可能会从一个版本的公共语言运行时更改为另一个版本。发生这种情况的一个原因是为了提高GetHashCode 的性能。
来自Object.GetHashCode:
GetHashCode 方法适用于哈希算法和哈希表等数据结构。
哈希码用于平衡哈希表。它们不是用来识别物体的。如果您将这个概念用于它的用途,您可能会更早发现这一点。