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               | 

2行挿入します

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)

私の質問は、2 行目の id の次の数字が 2 ではなく 3 である理由です。何かの下のどこかに最後の値がメモリに保存されていると思いますが、そのIDの行が削除されても問題ありません。必要に応じて、id の値を明示的に挿入できることはわかっています。しかし、この場合、なぜそれが起こるのかを明確にしたいと思います。また、その原因となっている機能や機能は何ですか? それはどのように機能しますか?

4

1 に答える 1

6

PostgreSQL は、削除されたシーケンス ID を追跡する努力をしません。カウンターを使用して、生成する次の ID を取得するだけです。

ギャップは、値を生成してからトランザクションを ROLLBACK した場合、コミット前にクライアント接続がクラッシュした場合、またはサーバーがクラッシュした場合にも発生します。

生成された ID から信頼できる唯一のプロパティは一意性です。コミット順序は ID 割り当て順序と必ずしも同じではないため、それらが生成されたのと同じ順序でテーブルに表示されることに依存することさえできません。

ギャップレス シーケンスが必要な場合は、それらを実装する方法がありますが、同時書き込みロードでパフォーマンスが低下します。そのため、PostgreSQL はそのように動作します。

詳細については、Google の「ギャップレス シーケンス pos​​tgresql」を参照し、シーケンスと「nextval」関数に関するドキュメントの章を参照してください。

于 2016-10-27T00:47:16.417 に答える