【发布时间】:2022-06-14 00:02:27
【问题描述】:
我知道 UUID 和递增整数通常用于主键。 我正在考虑 nanoids,因为它们是 URL 友好的,不会被猜测/蛮力刮掉(比如递增整数)。
在 Postgres 这样的数据库中,是否有任何理由不使用 nanoids 作为主键? (例如:也许它们会大大增加查询时间,因为它们没有……对齐或其他什么?)
【问题讨论】:
标签: sql postgresql indexing
我知道 UUID 和递增整数通常用于主键。 我正在考虑 nanoids,因为它们是 URL 友好的,不会被猜测/蛮力刮掉(比如递增整数)。
在 Postgres 这样的数据库中,是否有任何理由不使用 nanoids 作为主键? (例如:也许它们会大大增加查询时间,因为它们没有……对齐或其他什么?)
【问题讨论】:
标签: sql postgresql indexing
大多数数据库使用递增的 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 的数据结构。
【讨论】:
我不确定使用 nanoids 是否有缺点,但它们通常是不必要的。虽然 UUID 很长,但可以将它们转换为更短的格式而不会丢失熵。
查看 NPM 包 (https://www.npmjs.com/package/short-uuid)。
【讨论】:
UUID 由开放软件基金会 (OSF) 标准化并由 RFC 4122 进行描述。这意味着其他工具将有更多机会为您提供一些好处。
一些例子:
MongoDB 有一种特殊的类型来优化 UUID 的存储。不仅 NanoID 字符串会占用更多空间,甚至二进制也会占用更多位(Nano ID 为 126,UUID 为 122)
曾经看到一个记录工具从 uid 中提取时间戳,不记得是哪个,但它是可用的
此外,UUID 的长、非简化版本也很容易在视觉上识别。当最终用户是开发人员时,了解 ID 的性质/来源可能会有所帮助(显然不是数据库自动增量键)
【讨论】: