SHA1总和作为主键?

时间:2012-08-19 20:03:19

标签: mysql sha1

我要将文件名和其他详细信息存储在一个表中,我打算使用文件名的sha1哈希作为PK。

  • Q1。 SHA1 PK不是顺序增加/减少的数字。 那么,数据库的资源消耗会更多吗? 维护/ search_into和该键的索引?如果我决定将它作为40个char值保存在数据库中。

  • Q2。我在这里读到: https://stackoverflow.com/a/614483/986818将数据存储为 二进制(20)字段。有人可以就此提出建议:

  • a)我是否必须创建此列:TYPE = integer,LENGTH = 20,
    COLLATION = binary,ATTRIBUTES = binary?
  • b)如何将MySQL或Perl中的sha1值转换为存储 表?
  • c)这个20 char值是否存在重复的危险?

**

  

--------- UPDATE -------------

**

要求是在文件名上搜索表格。用户提供文件名,我去搜索表格,如果文件名不是,那就添加它。因此,要么在varchar(100)文件名字段上索引,要么生成一个文件名为sha1的列 - 希望与索引varchar字段相比,为MySql编制索引更容易。此外,我可以使用我的程序中的sha1值对sha1列进行搜索。说啥?主键或只是索引键:我选择PK coz DBIx喜欢使用PK。和PK或INDEX + UNIQ将是相同的系统开销(所以我认为)

5 个答案:

答案 0 :(得分:0)

这里没有理由使用加密安全哈希。相反,如果您这样做,请使用普通哈希。见这里:https://softwareengineering.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed

哈希值不是40个char值!它是一个160位的数字,你应该以那种方式存储它(作为一个20字符的二进制字段)。编辑:我看到你在评论中提到了2.是的,你一定要这样做。但我无法告诉你,因为我不知道你使用的是什么编程语言。 Edit2:我看到它是perl - 抱歉我不知道如何在perl中转换它,但是寻找“pack”函数。

不,不要将其创建为类型整数。最大整数是128位,不能容纳整个事物。虽然你真的可以把它截断到128位而没有真正的伤害。

最好还是使用更简单的哈希。你可以冒险并忽略碰撞,但如果你做得恰当,你就必须处理它们。

答案 1 :(得分:0)

  

如果我决定将其作为40个char值保存在数据库中。

使用字符序列作为键会因性能明显而降低性能。

PK也应该是唯一的。虽然它可能可能不太可能你最终发生碰撞(理论上使用它来创建PK似乎是不合适的。) 此外,任何知道您使用的文件名和哈希值的人都会知道您的所有数据库ID。我不确定这是否值得考虑。

答案 2 :(得分:0)

Q1:是的,它需要建立一个B-Tree节点,它不仅包含1个整数(4个字节),还包含一个CHAR(40)。只要INDEX保留在记忆中,速度​​就会大致相同。由于条目大约大10倍,因此需要10倍的内存才能将其保留在内存中。但是:你可能想要通过哈希查找。因此,您需要将其作为主键或索引。

Q2:只需创建一个像CREATE TABLE test一样的表字段(ID BINARY(40),...);以后你可以使用INSERT INTO test(ID,..)VALUES(UNHEX('4D7953514C'),...);

- 关于:这个20 char值是否存在重复的危险?

机会是1 ^ 2 ^(8 * 20)。 1在1,46 * 10 ^ 48 ...或1的14615016373309029182036848327163 * 10 ^ 18。所以这个机会非常非常不可能。

答案 3 :(得分:0)

我会坚持主键的标准自动递增整数。如果文件名的唯一性很重要(它听起来像是这样),那么您可以在文件名本身或文件名的某些派生规范版本上添加UNIQUE约束。大多数语言/框架都有某种方法来获取路径的规范版本(相对于绝对的,标准化的案例等)。

如果您实施我的建议或追求原始计划,那么您应该知道多个字符串可以映射到相同的文件名/路径。两个版本都会有不同的哈希值/传递唯一性约束,但实际上它们都会引用同一个文件。这取决于操作系统,可能或可能不是您的问题。请记住一些事情。

答案 4 :(得分:0)

好的,然后对文件名使用非常短的哈希并接受冲突。使用整数类型(更快!!!)。例如。你可以使用md5(filename),然后使用前8个字符并将它们转换为整数。 SQL可能如下所示:

CREATE TABLES files (
  id INT auto_increment,
  hash INT unsigned,
  filename VARCHAR(100),

  PRIMARY KEY(id),
  INDEX(hash)
);

然后你可以使用:

SELECT id FROM files WHERE hash=<hash> AND filename='<filename>';

然后使用散列来排序大多数其他文件(通常是所有其他文件),然后文件名用于从少数散列冲突中选择正确的条目。

为了在perl中生成整数哈希键,我建议使用md5()和pack()。