Mysql SHA1 sum作为主键?

Mysql SHA1 sum作为主键?,mysql,sha1,Mysql,Sha1,我将在一个表中存储文件名和其他详细信息,我计划使用文件名的sha1散列作为PK 问题1。SHA1 PK不是一个顺序递增/递减的数字。 那么,数据库是否会消耗更多的资源 在该键上维护/搜索并索引?如果我决定将其作为40个字符的值保存在数据库中 问题2。我在这里读到: 将数据存储为 二进制(20)字段。在这方面,有人能给我一些建议吗 a) 我是否必须将此列创建为:TYPE=integer,LENGTH=20, 排序规则=二进制,属性=二进制 b) 如何将MySQL或Perl中的sha1值转换为存储

我将在一个表中存储文件名和其他详细信息,我计划使用文件名的sha1散列作为PK

  • 问题1。SHA1 PK不是一个顺序递增/递减的数字。 那么,数据库是否会消耗更多的资源 在该键上维护/搜索并索引?如果我决定将其作为40个字符的值保存在数据库中

  • 问题2。我在这里读到: 将数据存储为 二进制(20)字段。在这方面,有人能给我一些建议吗

  • a) 我是否必须将此列创建为:TYPE=integer,LENGTH=20,
    排序规则=二进制,属性=二进制
  • b) 如何将MySQL或Perl中的sha1值转换为存储 桌子
  • c) 这个20个字符的值是否有重复的危险
**

---------更新-------------

**


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

这里没有理由使用加密安全的散列。相反,如果这样做,请使用普通散列。请看这里:

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

否,不要将其创建为integer类型。最大整数是128位,它不能容纳全部内容。虽然你真的可以把它截短到128位而不会造成真正的伤害

无论如何,最好使用更简单的散列。你可以冒险忽略碰撞,但如果你做得好,你就必须处理它们

如果我决定将其作为40个字符的值保存在数据库中

由于明显的原因,使用字符序列作为键会降低性能

而且PK应该是唯一的。虽然可能不会出现冲突(理论上,将其用于函数来创建PK似乎不合适)。

另外,任何知道你使用的文件名和散列的人都会知道你所有的数据库ID。我不确定这是不是要考虑的事情。

< P> Q1:是的,它需要建立一个包含1个整数(4字节)但一个字符(40)的节点的B-树。。只要索引保留在内存中,速度大致相同。由于条目大约大10倍,您需要多10倍的内存才能将其保留在内存中。但是:您可能还是希望通过哈希进行查找。因此,您需要将其作为主键或索引

问题2:只需创建一个表字段,如createtablettest(ID BINARY(40),…);稍后可以使用INSERT-INTO-test(ID,…)值(UNHEX('4D7953514C'),…)

--关于:这个20个字符的值是否有重复的危险


可能性是1/2^(8*20)。1/1,46*10^48…或14615016373309029182036848327163*10^18中的1。因此,这是非常不可能的。我会坚持主键的标准自动递增整数。如果文件名的唯一性很重要(听起来很重要),然后您可以在文件名本身或文件名的派生规范版本上添加唯一约束。大多数语言/框架都有某种方法来获取路径的规范版本(相对于绝对、标准化大小写等)


如果您执行我的建议或执行您的原始计划,那么您应该知道,多个字符串可以映射到同一文件名/路径。两个版本都有不同的哈希值/传递唯一性约束,但实际上都引用同一个文件。这取决于操作系统,可能对您来说是个问题,也可能不是。仅此而已方法要记住。

好的,然后在文件名上使用非常短的散列并接受冲突。使用整数类型(这要快得多!!!)。例如,您可以使用md5(文件名),然后使用前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>';
从hash=和filename=''的文件中选择id;
散列然后用于排序大多数其他文件(通常是所有其他文件),然后文件名用于从少数散列冲突中选择正确的条目


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

为什么要将散列用作PK,而不仅仅是具有常规PK(Guid/int)的唯一列?此外,请记住散列不是唯一的。无限多的数据输入映射到相同的散列值(虽然我不知道,对于特定的哈希算法,是否每个可能的哈希值都是如此。对于某些哈希值,可能有一些只有有限数量的数据输入)。我是否遗漏了什么?我假设您的文件名附加了一个位置?因为名称/位置应该是唯一的,只需在文件名和位置上使用一个已经自动递增的pk和一个单独的唯一键。根本没有理由使用散列。散列有冲突。您不想在主键中发生冲突。即使Lision是“非常罕见的”。Ty.Hi,我想知道构建列所提供的值的完整详细信息(我正在使用phpMyAdmin处理我的数据库)。您需要创建一个类型为BINARY(40)的列;您可以选择此列作为列类型(可能不可用)…或者