PostgreSQL の SEQUENCE には CACHE という設定があります。 (Oracle などにもあります)
この機能は高速化のためのもので、事前に SEQUENCE をまとめて 取得しておき、大量に SEQUENCE を発行するときに 何度も SEQUENCE を更新しないようします。
実際の動きを見てみます。
db=# CREATE SEQUENCE test_seq CACHE 3;
CACHE のみ設定して(他はデフォルトで)作成しました。
下のように設定されています。
db=# SELECT last_value, cache_value FROM test_seq; -[ RECORD 1 ]-- last_value | 1 cache_value | 3
nextval() で値を取得します。
db=# SELECT nextval('test_seq'); → 1 が返る
SEQUENCE は次のようになります。
db=# SELECT last_value, cache_value FROM test_seq; -[ RECORD 1 ]-- last_value | 3 cache_value | 3
1 回しか nextval() していませんが last_value は 3 になっています。 これは 1 を取得したときに 2, 3 をキャッシュとして取得しているためです。
もちろん nextval() を続ければ 2, 3 を取得できます。
db=# SELECT nextval('test_seq'); → 2 が返る db=# SELECT nextval('test_seq'); → 3 が返る
これでキャッシュした分を使い切ってしまったのですが さらに nextval() してみます。
db=# SELECT nextval('test_seq'); → 4 が返る
この状態で SEQUENCE は次のようになります。
db=# SELECT last_value, cache_value FROM test_seq; -[ RECORD 1 ]-- last_value | 6 cache_value | 3
このように、キャッシュを使い切ると新しくキャッシュを取得しなおします。 デフォルトでは CACHE が 1 なので取得するごとにキャッシュを使い切っているわけです。
キャッシュはセッション内でのみ有効です。 この状態は、このセッション以外からは 6 まで使用済みとして扱うため 別のセッションで nextval() すると次のように 7 が返ります。
[別セッション] db=# SELECT nextval('test_seq'); → 7 が返る [このセッション] db=# SELECT nextval('test_seq'); → 5 が返る
そのためキャッシュを使用すると SEQUENCE の値が時系列に 並ばないことがあるので注意が必要です。