【问题标题】:Are there any downsides to using nanoid for primary key?使用 nanoid 作为主键有什么缺点吗?
【发布时间】:2022-06-14 00:02:27
【问题描述】:

我知道 UUID 和递增整数通常用于主键。 我正在考虑 nanoids,因为它们是 URL 友好的,不会被猜测/蛮力刮掉(比如递增整数)。

在 Postgres 这样的数据库中,是否有任何理由不使用 nanoids 作为主键? (例如:也许它们会大大增加查询时间,因为它们没有……对齐或其他什么?)

https://github.com/ai/nanoid

【问题讨论】:

    标签: sql postgresql indexing


    【解决方案1】:

    大多数数据库使用递增的 id,因为将新值插入基于 B 树的索引的末尾会更有效。

    如果你在 B-tree 中间的随机位置插入一个新值,它可能不得不拆分 B-tree 非终结节点,这可能导致下一个更高级别的节点拆分,所以直到 B 树的顶部。

    这也有更大的导致碎片的风险,这意味着索引为相同数量的值占用更多空间。

    阅读https://www.percona.com/blog/2015/04/03/illustrating-primary-key-models-in-innodb-and-their-impact-on-disk-usage/,了解在主键中使用自动增量与 UUID 之间的权衡。

    该博客是关于 MySQL 的,但同样的问题适用于任何基于 B-tree 的数据结构。

    【讨论】:

    • 从(略读)链接的文章中,似乎主要的性能差异是使用 UUID 或递增 id。 nanoid 与 UUID 差别不大。
    • IMO,我不会使用任何 nanoid。我会使用数字主键作为标识符。如果你想掩盖你还没有很多记录的事实,你可以从 1000000 开始整数。
    • 如果您已经决定必须使用 nanoid 作为面向人类的标识符,则将其作为非主键属性存储在表中。
    • 有些人修改了标准的 UUID 以确保它是按时间戳排序的。此博客描述了该技术:percona.com/blog/2014/12/19/store-uuid-optimized-way 但您必须调查该技术是否可以应用于 nanoid。我不知道 nanoid 如何对其值进行编码,并且可能无法使用这种优化技术。
    • 在这一点上,我想你明白了权衡。我无法为您回答哪种解决方案最适合您的应用。现在你可以选择了。这就是成为专业软件开发人员的工作。
    【解决方案2】:

    我不确定使用 nanoids 是否有缺点,但它们通常是不必要的。虽然 UUID 很长,但可以将它们转换为更短的格式而不会丢失熵。

    查看 NPM 包 (https://www.npmjs.com/package/short-uuid)。

    【讨论】:

      【解决方案3】:

      UUID 由开放软件基金会 (OSF) 标准化并由 RFC 4122 进行描述。这意味着其他工具将有更多机会为您提供一些好处。

      一些例子:

      • MongoDB 有一种特殊的类型来优化 UUID 的存储。不仅 NanoID 字符串会占用更多空间,甚至二进制也会占用更多位(Nano ID 为 126,UUID 为 122)

      • 曾经看到一个记录工具从 uid 中提取时间戳,不记得是哪个,但它是可用的

      此外,UUID 的长、非简化版本也很容易在视觉上识别。当最终用户是开发人员时,了解 ID 的性质/来源可能会有所帮助(显然不是数据库自动增量键)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-27
        • 2023-03-16
        • 1970-01-01
        • 2011-04-26
        相关资源
        最近更新 更多