ffx*_*sam 16 postgresql index primary-key postgresql-10
我正处于一个十字路口,我需要决定是否要坚持bigserial
作为我的主键,或者更改为uuid
(非自动生成\xe2\x80\x94)我的 API 服务器将使用 uuid v4 生成 ID并插入)。
我花了几个小时研究bigserial
主uuid
键,似乎没有人能就其缺点uuid
(如果有的话)达成一致。jsonb
我的数据库并没有那么复杂:它是一系列具有非常基本关系的表,我通常一次只插入一行,我到处使用一些字段。写入速度/频率只会在一张表上特别高。
我开始研究 UUID 的原因并不是因为我认为我会用完bigint
密钥(如果我没记错的话,有 9 千万亿),更多的是从混淆的角度来看。现在我必须在前端对 ID 进行哈希处理,以避免在 URL 中显示用户数据库 ID(例如/things/2732
)。使用Hashids,我可以使用类似 的 URL /things/To2jZP13dG
。但我认为我可以更进一步,只使用 UUID,它不会提供有关记录数的任何线索。我不喜欢的是,在将 ID 传递到后端并在那里解码之前必须对其进行编码,然后在查询 50-100 个项目的批次以返回给客户端时,必须对所有这些进行批量编码,这会增加额外的工作量在将 ID 返回给客户之前。
支持随机 UUID(uuid v4)的一个论据是:
\n\n\n如果您的主键是递增 ID,则它们在物理上彼此相邻存储。由于许多人正在写入该数据库页面,因此该数据库页面可能会发生争用。随机 ID 通过将写入分散到整个数据库来防止争用
\n
但后来我发现这里有一个矛盾的说法有一个矛盾的说法:
\n\n\n常规随机 UUID 在整个可能值范围内均匀分布。这会导致在将数据插入索引时局部性较差 - 所有索引叶页都同样可能被命中,从而迫使整个索引进入内存。对于小索引来说这没什么问题,但是一旦索引大小超过共享缓冲区(或 RAM),缓存命中率就会迅速下降。
\n
我知道 Heroku 的人们热衷于使用 UUID 作为主键。不管它的价值如何,我根本不打算让 Postgres 自动生成 ID。相反,我的 API 服务器会生成一个 v4 UUID 并将其传递到数据库(这将使我的 API 服务器和前端客户端更加高效,并且不必总是RETURNING id
在查询中使用语句)。
INSERT
有人对用uuid
作主键时语句的真实成本有规范的答案吗?
Lau*_*lbe 14
对此进行基准测试很容易,但INSERT
UUID 的性能会更差,因为它们更大且生成速度更慢。
但无论如何,听起来您并不是在构建高性能应用程序(那么您可能不会使用 JSON),因此它可能不会有太大区别。
最后,出于安全原因您希望使用 UUID(我不会在这里讨论)。安全性总是会损害性能和可用性,因此请将其视为您为安全性付出的代价。
Laurenz 所说的是真的,但实际上,当您尝试UUID
在谓词(例如JOIN
,在WHERE
、 和HAVING
子句中)中使用这些字段时,我实际上发现了性能上的更可衡量的差异。同样,这取决于谓词所针对的表之间的数据量,但 16 字节值和另一个 16 字节值之间的比较与 4 字节和 4 字节值之间的比较有些显着不同,例如,如果字段是INT
数据类型。但正如劳伦兹所提到的,这是为安全而付出的合理代价。
归档时间: |
|
查看次数: |
21124 次 |
最近记录: |