※当サイトの記事には、広告・プロモーションが含まれます。

PostgreSQLのシーケンスオブジェクトがややこしい

gigazine.net

⇧ 広大過ぎて、検証の仕様がない気がしてならないのだが...

PostgreSQLのシーケンスオブジェクトとは?

PostgreSQLの公式のドキュメントによりますと、

www.postgresql.jp

9.17. シーケンス操作関数

本節ではシーケンスオブジェクトに対し演算を行う関数について説明します。 シーケンスオブジェクトは、シーケンスジェネレータ、あるいは単にシーケンスとも呼ばれます。 シーケンスオブジェクトは特殊な一行だけのテーブルで、CREATE SEQUENCEで作成されます。 シーケンスオブジェクトは一般的にテーブルの行に一意の識別子を生成するために使用されます。

https://www.postgresql.jp/docs/15/functions-sequence.html

⇧ とありますと。

呼び方を統一して欲しいところなんだけど...

PostgreSQLのシーケンスオブジェクトがややこしい

公式のドキュメントが取っ散らかっているのですが、

www.postgresql.jp

smallserialserialおよびbigserialデータ型は正確にはデータ型ではなく、テーブルの列に一意の識別子を作成する簡便な表記法です (他のデータベースでサポートされるAUTO_INCREMENTプロパティに似ています)。 現在の実装では、

CREATE TABLE tablename ( colname SERIAL );

は以下を指定することと同じです。

CREATE SEQUENCE tablename_colname_seq AS integer; CREATE TABLE tablename ( colname integer NOT NULL DEFAULT nextval('tablename_colname_seq') ); ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

このように整数列を作成し、その列のデフォルト値が連番ジェネレータから割り当てられるようにしました。 また、NOT NULL制約を適用することによって、NULL値が挿入されないようにします。 (たいていの場合は、重複する値を間違って挿入しないように、UNIQUE制約またはPRIMARY KEY制約も追加することになるでしょうが、これは自動的には行われません。) 最後に、シーケンスは列に「より所有」されるものと印が付きます。 したがって、テーブルの列が削除された場合にシーケンスは削除されます。

https://www.postgresql.jp/document/15/html/datatype-numeric.html#DATATYPE-SERIAL

www.postgresql.jp

CYCLE
NO CYCLE

CYCLEオプションを使用すると、シーケンスが限界値(昇順の場合はmaxvalue、降順の場合はminvalue)に達した時、そのシーケンスを周回させることができます。 限界値まで達した時、次に生成される番号は、昇順の場合はminvalue、降順の場合はmaxvalueになります。

NO CYCLEが指定された場合、シーケンスの限界値に達した後のnextval呼び出しは全てエラーになります。 CYCLENO CYCLEも指定されていない場合は、NO CYCLEがデフォルトとなります。

https://www.postgresql.jp/docs/15/sql-createsequence.html

⇧ 上記の情報を整理するに、

  1. smallserial、serialおよびbigserialデータ型のカラムを持つテーブルをCREATE TABLE文で作成する
  2. CREATE SEQUENCE文を実行する

のどちらかで、「シーケンスオブジェクト」が生成されるようなのだけど、「1. smallserial、serialおよびbigserialデータ型のカラムを持つテーブルをCREATE TABLE文で作成する」のケースは、オプションが効かないという罠があると。

なので、「1. smallserial、serialおよびbigserialデータ型のカラムを持つテーブルをCREATE TABLE文で作成する」のケースで「シーケンスオブジェクト」を作成した場合は、

www.postgresql.jp

⇧「シーケンスオブジェクト」の定義を変更することでオプションを有効にしたりする必要があるっぽいですな。

ネットの情報によると、

kawaken.dev

⇧ serial型だと、すぐに上限を超える可能性があるらしい。

ちなみに、シーケンスの定義を確認する方法は、

oha-yo.com

⇧ 上記サイト様がまとめてくださっています。

テーブルのレコードを定期的に削除していくような運用であれば、「CYCLE」オプションとかを有効にしておけば良いってことなんですかね?

デフォルトで「NO CYCLE」となっているのが気にはなりますな...

「CYCLE」を利用して欲しくないのか?と勘ぐってしまうのよな...

それにしても、PostgreSQL のシーケンスオブジェクトはややこし過ぎないかね...

毎度モヤモヤ感が半端ない…

今回はこのへんで。