使用SHA-256哈希作为主键时,是否可以忽略冲突的可能性?

时间:2014-05-13 19:29:39

标签: database-design hash sha

我遇到这种情况,我在HDD上有文件,我想在数据库中缓存有关它们的信息。鉴于其中一些文件可能会遇到GB,因此需要花费很长时间才能解析的信息。

我的第一个直觉是使用文件路径作为文件的唯一标识符,并将其用作密钥(TEXT / VARCHAR)并将信息作为值存储在数据库表中。

鉴于在某些文件系统下(特别是在* nix中),文件路径可以是无限长度的。将文件名用作数据库中的主键似乎是个坏主意。只需对字符串字段进行索引就会慢很多,更不用说内存/空间限制了。

我想,也许,我从完整文件路径(/usr/xxx/1/2/../abc.xyz)生成SHA-256哈希,并在我的数据库中将其用作主键(固定宽度)。另一个想法是从文件内容生成SHA-256哈希。然而,这也可能变得非常耗时。

我的问题是 - 在这种情况下,哈希冲突同样不太可能,就像这个优秀的thread提供的答案一样。

1 个答案:

答案 0 :(得分:0)

要回答您的问题,如果要接近表中的2 ^ 128个文件,您可能只会遇到哈希冲突问题。这假设所有输入的长度介于0 .. + INF之间,并且您使用的散列算法是完美(SHA-256在实践中被认为是完美但未经过验证理论上)并且输出大小恰好是256位。

如果你有几十亿个文件,你应该没问题。

现在我的建议。我想说您需要告诉我们有关您的预期用途的更多信息。你的第一个想法比你的哈希方法更接近正确。

我会使用这样的表(SQL Server的T-SQL语法):

CREATE TABLE [File]
(
    [Id] BIGINT IDENTITY NOT NULL,
    [Path] CHARACTER VARYING(MAX) NOT NULL

    PRIMARY KEY([Id])
);

CREATE NONCLUSTERED INDEX [File_Path_IX] ON [File]([Path]);

然后,您应该让数据库处理索引并快速进行搜索。 当且仅当您遇到重大性能问题后,通过性能分析证明,您是否应该考虑更改为哈希方法。散列会对预处理造成巨大的计算损失,并会引入复杂的场景,例如散列冲突,并在它们发生时尝试解决它们。