7

我有一张巨大的桌子,里面有 8 300 000 行(永远不会被编辑或删除)。

我的第一列看起来很相似P300-4312B_X16_S,并且该条目不是唯一的,因此我在此字段上使用了常规 INDEX。

但是,MySQL 使用二进制字段而不是 varchar 更快,因此我将我的 INDEX 编码为 MD5BINARY(16)用于存储数据。

今天早上,我第一次开始使用CRC32,我看到CRC32可以输出为8个字符的十六进制字符串。

我的问题:如果我使用 CRC32 而不是 MD5,它会更快。但是,当 CRC32 运行时,假设 2 000 000 个唯一值,结果将是唯一的,或者有时我会为两个不同的字符串提供两次相同的字符串?我这样问是因为结果只有 8 个字符 (32b) 长,而不是像 MD5 那样的 32(128b)。

谢谢。

4

1 回答 1

10

预期的冲突数量是可能的检查值数量上的对数。因此,对于 2,000,000 个值,有 (2000000 * 1999999) / 2 对,大约为 2x10 12。对于 32 位 CRC,预期的冲突次数超过 2 32,即 466。因此,在这种情况下,您基本上可以保证发生冲突。

对于 128 位 MD5 校验值,预期的冲突次数约为 6x10 -27。对于期望数的小值,这也是一次碰撞的概率。

如果碰撞概率非常低对您很重要,那么您需要选择除 CRC-32 之外的其他东西。

不过,您不需要 MD5 的开销,因为它的加密强度对您的应用程序并不重要。您并不真正关心是否有人恶意可以找到一种方法来伪造与另一个条目具有相同检查值的条目。因此,您可以使用为此目的而设计的 64 位非加密哈希,它运行得更快,并且在您的 2,000,000 个值的情况下会产生 10 -7的冲突概率。或者您可以使用 128 位非加密散列并获得与 MD5 相同的概率,但要快得多。看看CityHash 系列的哈希算法。

但是请注意,在所有情况下,碰撞的概率都不是零。您应该考虑代码冲突的后果。

于 2012-10-01T22:12:10.660 回答