重用已删除的主键序列 (BIGSERIAL) - 无 UUID 以节省存储空间

Re-use the deleted sequences of primary keys (BIGSERIAL) - No UUID to save storage

提问人:Zim 提问时间:1/13/2023 最后编辑:Zim 更新时间:1/13/2023 访问量:92

问:

我用作主键,我想使用已删除行的 ID。BIGSERIAL

我要从已删除的行中重用已删除的 ID 的表示例:

DELETE FROM my_table WHERE id=3;
INSERT INTO my_table(column_x) VALUES(xxxxx)

my_table

| id|column_x|        | id|column_x|               | id|column_x|
|---|--------|        |---|--------|               |---|--------|
| 1 | xxxxxx |        | 1 | xxxxxx |               | 1 | xxxxxx |
| 2 | xxxxxx |        | 2 | xxxxxx |               | 2 | xxxxxx |
| 3 | xxxxxx |   >>>  | 4 | xxxxxx |        >>>    | 4 | xxxxxx |
| 4 | xxxxxx |        | 5 | xxxxxx |               | 5 | xxxxxx |
| 5 | xxxxxx |                                     | 3 | xxxxxx |

右边的第三个表插入了一个 id=3 的新行,该行在中间的表中删除了该行,并且这样做了。我想利用那些跳过的序列。

我使用源代码进行了一些尝试ALTER SEQUENCE

我目前的解决方案:

 INSERT INTO my_table(id, column_x)
 VALUES(deleted_index, xxxx);

预期解决方案:

INSERT INTO my_table(column)
VALUES(xxxx);

换句话说,更改索引 my_table.id 的序列,以便它重用已删除的序列并继续nextval

SQL PostgreSQL 序列 主键 更改

评论

3赞 Adrian Klaver 1/13/2023
为什么?序列值应被视为没有任何意义,除非是唯一的和递增的(不是无间隙的)。
4赞 1/13/2023
生成的主键的唯一工作是唯一的。实际值完全无关紧要。值 1 与 36947648、-34234 或 93 一样好。您无需执行任何操作。继续前进。
0赞 Zim 1/13/2023
@AdrianKlaver UUID 将消耗额外的存储空间,而 BIGSERIAL 则不
1赞 Horaciux 1/13/2023
您将需要一个触发器来跟踪表中已删除的 ID,以及另一个从那里选取 ID 的触发器。你不想走那条路。
1赞 Adrian Klaver 1/13/2023
我没有说任何关于使用.列意味着一个唯一的数字生成器,除此之外没有任何意义。UUIDBIGSERIAL Primary key

答:

0赞 mwalter 1/13/2023 #1

dot 不明白这样做的目的,但有代码,令人惊讶的是它工作正常:

WITH selectvalues AS (
SELECT * FROM my_table 
),
deletevalue AS (
DELETE FROM my_table  del
    USING selectvalues sel
    WHERE del.id = sel.id
    RETURNING del.*
),
insertval AS(
INSERT INTO my_table 
SELECT * FROM deletevalue
RETURNING * )
SELECT * FROM insertval

评论

0赞 Zim 1/13/2023
其目的不是在性能方面增加太多,而是为每秒插入大量值的应用程序增加更多的存储空间。我会尝试你的解决方案。谢谢你的努力。
0赞 Laurenz Albe 1/13/2023 #2

你真的认为你会用尽所有9223372036854775807正数吗?任何“填补空白”的尝试都会使事情复杂化,不利于性能。bigint

评论

0赞 Zim 1/13/2023
这是一个具有挑战性的应用要求,并且为了节省使用 UUID.As 插入物的存储空间!每秒插入次数相当多。另一方面,“这是傻瓜的差事”,是完全没有必要和无益的评论!请尝试更礼貌的评论。谢谢!
0赞 Laurenz Albe 1/13/2023
“傻瓜差事”是一个转折,并不意味着你是个傻瓜。我已经删除了它。当然,你不想要 UUID,这对我来说非常有意义。但是你的 s 序列中的间隙有什么问题?毕竟,这些都是自动生成的人工主键,在数据库之外没有任何意义。id