CREATE SEQUENCE — 新しいシーケンスジェネレータを定義する
CREATE [ TEMPORARY | TEMP ] SEQUENCE [ IF NOT EXISTS ]name
[ ASdata_type
] [ INCREMENT [ BY ]increment
] [ MINVALUEminvalue
| NO MINVALUE ] [ MAXVALUEmaxvalue
| NO MAXVALUE ] [ START [ WITH ]start
] [ CACHEcache
] [ [ NO ] CYCLE ] [ OWNED BY {table_name
.column_name
| NONE } ]
CREATE SEQUENCE
は、新しいシーケンス番号ジェネレータを作成します。
これには、新しくname
という名前を持つ、1行だけの特殊なテーブルの作成と初期化が含まれます。
シーケンスジェネレータは、このコマンドを実行したユーザによって所有されます。
スキーマ名が与えられている場合、そのシーケンスは指定されたスキーマに作成されます。 スキーマ名がなければ、シーケンスは現在のスキーマに作成されます。 また、一時シーケンスは特別なスキーマに存在するため、一時シーケンスの作成時にスキーマ名を与えることはできません。 シーケンス名は、同じスキーマ内の他のシーケンス、テーブル、インデックス、ビュー、外部テーブルとは異なる名前にする必要があります。
シーケンスを作成した後、nextval
、currval
、setval
関数を使用してシーケンスを操作します。
これらの関数については9.16を参照してください。
シーケンスを直接更新することはできませんが、以下のような問い合わせは可能です。
SELECT * FROM name
;
これを使用すると、シーケンスのパラメータと現在の状態を確認することができます。
中でも、シーケンスのlast_value
フィールドは全てのセッションで割り当てられた最後の値を示します
(もちろんこの値は、他のセッションのnextval
の実行により、表示された時点で既に最新ではない可能性があります)。
TEMPORARY
もしくはTEMP
このパラメータが指定された場合、作成するシーケンスオブジェクトがそのセッション専用となり、セッション終了時に自動的に削除されます。 一時シーケンスが存在する場合、同じ名前を持つ既存の永続シーケンスは、スキーマ修飾された名前で参照されない限り、(そのセッションでは)不可視になります。
IF NOT EXISTS
同じ名前のリレーションが既に存在する場合にエラーとしません。 この場合、注意が発行されます。 既存のリレーションが、作成されようとしていたシーケンスと類似のものであることは全く保証されないことに注意してください。 それはシーケンスでさえ、ないかもしれません。
name
作成するシーケンスの名前です(スキーマ修飾名も可)。
data_type
オプション句AS
ではシーケンスのデータ型を指定します。
有効な型はdata_type
smallint
、integer
、bigint
です。
bigint
がデフォルトです。
データ型によりシーケンスのデフォルトの最小値と最大値が決定されます。
increment
INCREMENT BY
句は、現在のシーケンスの値から新しいシーケンス値を作成する際の値の増加量を設定します。この句は省略可能です。
正の値が指定された時は昇順のシーケンス、負の値が指定された時は降順のシーケンスを作成します。
指定がない場合のデフォルト値は1です。
increment
minvalue
NO MINVALUE
MINVALUE
句は、シーケンスとして作成する最小値を指定します。この句は省略可能です。
この句が指定されなかった場合、もしくは、minvalue
NO MINVALUE
が指定された場合、デフォルトが使用されます。
昇順のシーケンスでのデフォルト値は1です。
降順のシーケンスでのデフォルト値は、そのデータ型の最小値です。
maxvalue
NO MAXVALUE
MAXVALUE
句は、シーケンスの最大値を決定します。この句は省略可能です。
この句が指定されなかった場合、もしくはmaxvalue
NO MAXVALUE
が指定された場合、デフォルトが使用されます。
昇順のシーケンスでのデフォルト値は、そのデータ型の最大値です。
降順のシーケンスでのデフォルト値は-1です。
start
START WITH
句を使用すると、任意の数からシーケンス番号を開始することができます。この句は省略可能です。
デフォルトでは、シーケンス番号が始まる値は、昇順の場合start
minvalue
、降順の場合maxvalue
になります。
cache
CACHE
オプションは、あらかじめ番号を割り当て、メモリに格納しておくシーケンス番号の量を指定します。これによりアクセスを高速にすることができます。
最小値は1です(一度に生成する値が1つだけなので、キャッシュがない状態になります)。これがデフォルトになっています。
cache
CYCLE
NO CYCLE
CYCLE
オプションを使用すると、シーケンスが限界値(昇順の場合はmaxvalue
、降順の場合はminvalue
)に達した時、そのシーケンスを周回させることができます。
限界値まで達した時、次に生成される番号は、昇順の場合はminvalue
、降順の場合はmaxvalue
になります。
NO CYCLE
が指定された場合、シーケンスの限界値に達した後のnextval
呼び出しは全てエラーになります。
CYCLE
もNO CYCLE
も指定されていない場合は、NO CYCLE
がデフォルトとなります。
OWNED BY
table_name
.column_name
OWNED BY NONE
OWNED BY
オプションにより、シーケンスは指定されたテーブル列に関連付けられ、その列(やテーブル全体)が削除されると、自動的にシーケンスも一緒に削除されるようになります。
指定するテーブルは、シーケンスと同一所有者でなければならず、また、同一のスキーマ内に存在しなければなりません。
デフォルトはOWNED BY NONE
であり、こうした関連付けがないことを示します。
シーケンスを削除するにはDROP SEQUENCE
を使用してください。
シーケンスはbigint
演算に基づいています。
そのため、8バイト整数の範囲(-9223372036854775808から9223372036854775807まで)を越えることはできません。
nextval
とsetval
の呼び出しは決してロールバックされないので、シーケンスの番号について「欠番のない」割り当てが必要な場合には、シーケンスオブジェクトを使うことはできません。
カウンターを含むテーブルに対して排他ロックを使うことで、欠番のない割り当てを構築することは可能ですが、この解決策はシーケンスオブジェクトに比べてずっと高価で、特に多くのトランザクションが同時にシーケンスの番号を必要とする場合は高価になります。
シーケンスオブジェクトのcache
として1より大きな値を設定した場合、そのシーケンスを複数のセッションで同時に使用すると、予想外の結果になる可能性があります。
各セッションは、シーケンスオブジェクトへの1回のアクセスの間に、連続するシーケンス値を取得し、キャッシュします。
そして、キャッシュした数に応じて、シーケンスオブジェクトのlast_value
を増加させます。
この場合、そのセッションは、その後のcache
-1回に対しては、あらかじめ取得済みのシーケンス値を返し、シーケンスオブジェクトを変更しません。
セッションに割り当てられたが使用されなかったシーケンス番号は、セッションの終了時に全て失われるため、結果としてシーケンスに「穴」ができます。
さらに、複数のセッションには異なるシーケンス値が割り当てられることが保証されていますが、全てのセッションが尊重されると、シーケンス値が順番通りにならないことがあります。
例えば、cache
が10の場合を考えます。
セッションAでは1から10までを確保し、nextval
=1を返します。
セッションBでは、セッションAがnextval
=2を返す前に、11から20を確保し、nextval
=11を返します。
したがって、cache
を1に設定した場合はnextval
が順番に生成される値であると考えても問題ありませんが、cache
を1より大きな値に設定した場合は、nextval
の値が全て異なることのみが保証され、順番に生成される値であることは保証されません。
また、last_value
は、値がnextval
によって返されたかどうかに関係なく、いずれかのセッションによって確保された最後の値となります。
この他、このようなシーケンスに対してsetval
が実行されても、他のセッションは、それぞれがキャッシュした取得済みの値を全て使い果たすまで、それがわからないことも考慮すべき問題です。
101から始まるserial
という名前の昇順シーケンスを作成します。
CREATE SEQUENCE serial START 101;
このシーケンスから次の番号を選択します。
SELECT nextval('serial'); nextval --------- 101
このシーケンスから次の番号を選択します。
SELECT nextval('serial'); nextval --------- 102
このシーケンスをINSERT
コマンドで使用します。
INSERT INTO distributors VALUES (nextval('serial'), 'nothing');
COPY FROM
の後でシーケンス値を更新します。
BEGIN; COPY distributors FROM 'input_file'; SELECT setval('serial', max(id)) FROM distributors; END;
以下の例外を除き、CREATE SEQUENCE
は標準SQLに従います。
次の値を取り出すには、標準のNEXT VALUE FOR
式ではなくnextval()
関数を使用します。
OWNED BY
句はPostgreSQLの拡張です。