【问题标题】:Storing SHA1 Signature as Primary Key in Postgres SQL在 Postgresql 中存储 SHA1 签名作为主键
【发布时间】:2009-10-29 02:29:56
【问题描述】:

我正在编写一个简单的内容管理系统。 我需要存储外部计算的 SHA1 哈希值作为我最大表的主键。

我显然可以使用序列作为主键并索引 SHA1 十六进制字符串以进行查找... 但是,我正在寻找一个更优雅的解决方案,我将简单地使用 20 字节的 SHA1 计算值作为我将要在数据库表中插入/删除/更新的行的给定键。 是否有一种高效的存储类型可用于存储并稍后将 SHA1 键用作主键?

我显然需要 postgres 支持使用 20 字节的值作为键来完成这项工作。

有人有什么想法吗?

【问题讨论】:

标签: postgresql primary-key sha1


【解决方案1】:

特别是如果您要将二进制参数放入数据库(例如通过 libpq),请使用 bytea。如果您想通过简单的文本查询进行大量操作,请将其转换为 hext 并存储在 text 或 varchar 列中。

一般而言,PostgreSQL 使用 20 字节键当然不会有任何问题,除了性能开销当然比使用序列更大。

【讨论】:

    【解决方案2】:

    您可以转换为十六进制或 base64 并使用 varchar 列,或者尝试将其存储在 bytea 类型的列中。我会尝试用两种格式的一堆随机值制作表格,看看它们的表现如何。

    有关该类型的信息,请参阅 the PostgreSQL docs on bytea

    【讨论】:

      【解决方案3】:

      小心这会对您的索引 btree 造成什么影响。由于 SHA1 不是连续的,由于 btree 中的所有跳跃,您的写入将非常缓慢。

      如果序列不起作用,我通常会推荐某种顺序的 GUID/UUID(例如,参见 SQL Server 的 NEWSEQUENTIALID())。

      如果您想在知道这一点后将 SHA1 设为您的主键,您可以将其转换为 SHA1 通常显示的标准十六进制格式(便于键入)。我不推荐二进制格式,因为您将无法键入它进行调试等。

      【讨论】:

      • B-Tree 的写入无论如何都是连续的,搜索要链接的页面会跳转。然而,值的均匀分布将使树更加平衡,搜索速度更快,而不是更慢。
      • 我想我是指一些数据库服务器根据聚集索引排序页面的方式,但那是SQL Server,我不知道它是否适用于pgsql。唔!但你是对的,树会很好地平衡(几乎完美)
      • @wojo:即使使用聚簇表,SQL Server 也保持B-Tree 顺序,而不是物理顺序。这些行不一定是物理上的,只是逻辑上的。 msdn.microsoft.com/en-us/library/ms177443(SQL.90).aspx
      • @Quassnoi 嗯,我的理解是,使用聚集索引,磁盘上的页面根据索引进行排序,并且使用随机值(如 GUID 或 SHA1),你最终会得到两个逻辑以及插入时页面拆分的物理碎片。这不是真的吗? GUID 的类似问题(适用于任何哈希):stackoverflow.com/search?q=clustered+index+guid
      • @wojo:插入顺序值不会导致页面拆分,但会导致不平衡的B-Tree(实际上是B+Tree)。 B+Tree 索引中没有“逻辑碎片”之类的东西(它被设计为页面碎片,因此您应该始终遍历链接列表以到达下一页)。当值是连续的时,这个链表将指向下一页(按物理顺序),如果不是,则指向某个随机页面(可能很远)。
      猜你喜欢
      • 1970-01-01
      • 2012-08-15
      • 1970-01-01
      • 2016-03-05
      • 2014-11-02
      • 1970-01-01
      • 2018-11-01
      • 2011-08-28
      • 2018-12-24
      相关资源
      最近更新 更多