2

我创建下表

CREATE TABLE dogs (
  id serial,
  name VARCHAR(15),
  age integer;

我的桌子看起来像这样

                                  Table "public.birds"
 Column  |         Type          |                     Modifiers                      
---------+-----------------------+-------------------------------------    
 id      | integer               | not null default nextval('birds_id_seq'::regclass)
 name    | character varying(25) | 
 age     | integer               | 

我插入两行

INSERT INTO dogs (name, age) 
VALUES ('puffy', 13),
 ('fluffy', 15);

表格现在看起来像这样

  id |  name  | age 
 ----+--------+-----
   1 | puffy  |  13
   2 | fluffy |  15
 (2 rows)

然后我删除 id = 2 的行

DELETE FROM dogs WHERE id = 2;

并添加另一行

INSERT INTO dogs (name, age) VALUES('mimi', 20);

该表是

  id | name  | age 
 ----+-------+-----
   1 | puffy |  13
   3 | mimi  |  20
 (2 rows)

我的问题是为什么第二行中 id 的下一个数字不是 2 而是 3?我猜想某处下方某处存储了内存中的最后一个值,并且删除了具有该 id 的行并不重要。我知道如果需要,我可以显式地为 id 插入值。但我想清楚为什么会发生这种情况。什么功能或特性对此负责?它是如何工作的?

4

1 回答 1

6

PostgreSQL 不努力跟踪已删除的序列 ID。它只是使用一个计数器来获取下一个要生成的 ID。

如果您生成值然后 ROLLBACK 事务、客户端连接在提交之前崩溃或服务器崩溃,也会出现间隙。

您可以从生成的 ID 中依赖的唯一属性是唯一性。您甚至不能依赖它们以它们生成的相同顺序出现在表中,因为提交顺序不一定与 ID 分配顺序相同。

如果您需要无间隙序列,则有一些方法可以实现它们,但是它们在并发写入负载中的性能很差。这就是 PostgreSQL 以它的方式做事的原因。

更多信息,谷歌“gapless sequence postgresql”并阅读关于序列和“nextval”函数的文档章节。

于 2016-10-27T00:47:16.417 回答