Postgresql 在执行频繁插入时防止标识id列溢出
我有一个表,它有一个id列,指定如下:Postgresql 在执行频繁插入时防止标识id列溢出,postgresql,Postgresql,我有一个表,它有一个id列,指定如下: CREATE TABLE foo ( id integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ), name text, description text, CONSTRAINT foo_pkey PRIMARY KEY (id) ) 我非常频繁地更新此表(每5
CREATE TABLE foo
(
id integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
name text,
description text,
CONSTRAINT foo_pkey PRIMARY KEY (id)
)
我非常频繁地更新此表(每5分钟一次),但我使用的是“在冲突中什么都不做”
如本文所述,预期使用此设置时id会增加
然而,基于这篇文章,我确实需要担心柜台超限
如何防止在这种情况下发生错误?要明确的是,我不需要值是无间隔的,也不需要值按顺序排列,我只需要唯一性,我希望能够使用尽可能小的数据类型(我希望在某个时候切换到smallint) 我可以看到可能的解决方案:
- id为的表大约有20k行
- 每5分钟进行一次包含几乎所有20k重复项目的批量插入
- 引用id为的表包含超过100亿行,并在timescaledb上运行
- 如果我们使用bigint(8byte)而不是int(4byte),我们将使用(10bn*(8-4)字节)约40GB的未压缩额外空间
- 我想,使用timescaledb,这可能会被压缩到用于id的10GB额外空间
在这种情况下,考虑到表的更新不频繁,而且存储id的空间使用率较高,选择选项4比选择1更好吗?我认为正确的解决方案是另一种:将identity列的数据类型更改为
bigint
。这样就不会用完序列值
用一个简单的
ALTER TABLE
执行该更改将重写它并在语句期间锁定它。有更复杂的方法可以用更少的停机时间完成,请参见示例。谢谢您的回答。我不想使用此方法的原因是,我需要在非常大的第二个表中引用此id。由于它有很多行,使用smallint
vsbigint
节省的空间开始变得重要起来。使用循环
选项有什么问题?循环选项重复数值。保证重复ID或在数据循环之前删除数据。与其他选择相比,存储空间是廉价的。提供一些快速参考。我插入的表大约有20k行,引用它的表大约有100亿行。因此,未压缩的Bigint将使用大约80GB,而较小的是20GB——相差60GB。由于该表使用了timescaledb,我想60GB的压缩容量可能会减少到10GB。10GB值是否比每5分钟向20k行表批量插入10k值时检查唯一性的计算成本低?(obv.只是寻找一个大概的答案,而不是数学)也许你应该用这个信息更新这个问题。