Citus 上的主键(UUID、序列)策略

Primary Keys (UUID, Sequence) strategy on Citus

Citus 上主键的最佳方法是什么?

UUID: 不需要锁定,与 Identity/Serial 相反。但存储成本高,最终在查询时会导致碎片化。

序列 - 身份 在创建实体时造成瓶颈。存储成本更低,查询速度更快 + 无碎片。

如果我们想成为可扩展的项目,使用 UUID 会更好吗?

根据这个post: https://www.cybertec-postgresql.com/en/uuid-serial-or-identity-columns-for-postgresql-auto-generated-primary-keys/

对于分片,建议最终使用 UUID。

它在 Citus 上的表现如何?

我将给出一个模式示例:

User
UserId uuid/bigint?

Device
Device Id uuid/bigint?
UserId (here for the distribution key)

在上面的例子中,我们想根据UserId来分配用户数据,比如他的Devices。 主键 ID 类型应该是什么? 如果 UUID 是答案,我们是否应该担心节点中的碎片?

免责声明:我是从事 Citus 引擎工作的软件工程师,打开了一个 PR 以支持列默认中的 UDF。

在您在问题 gen_random_uuid() 中共享的 post 中,UDF 用作列默认值。 Citus 尚不支持此功能。

我建议你使用bigserial。

我还想指出,博客中的某些陈述对 Citus 来说是不正确的。例如:

So if you use sharding, where you distribute your data across several databases, you cannot use a sequence.

在 Citus 中,您可以创建分布式序列对象,其中每个工作节点将使用序列允许值的不相交子集。应用程序在协调器节点上看到单个序列,而分片有自己的具有不同起始值的序列。

(You could use sequences defined with an INCREMENT greater than 1 and different START values, but that might lead to problems when you add additional shards.)

Citus 将 bigserial 的开始位置移动 node_group_id * 2^48,这意味着您最多只能使用 2^18 个分片,这实际上是无限的。当您在单个 table 或四分之一百万分片中拥有数 PB 的数据时,您将 运行 陷入更大的问题,而这里的这种限制不会真正影响您的集群。

PS:我在 UDF 列默认值方面的工作现在暂停,因为最近的一些代码更改将使解决方案更清晰,更易于维护。我们尚未发布已发布版本中的更改。 https://github.com/citusdata/citus/pull/5149