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_typesmallint、integer、bigintです。
bigintがデフォルトです。
データ型によりシーケンスのデフォルトの最小値と最大値が決定されます。
increment
INCREMENT BY 句は、現在のシーケンスの値から新しいシーケンス値を作成する際の値の増加量を設定します。この句は省略可能です。
正の値が指定された時は昇順のシーケンス、負の値が指定された時は降順のシーケンスを作成します。
指定がない場合のデフォルト値は1です。
increment
minvalueNO MINVALUE
MINVALUE 句は、シーケンスとして作成する最小値を指定します。この句は省略可能です。
この句が指定されなかった場合、もしくは、minvalueNO MINVALUEが指定された場合、デフォルトが使用されます。
昇順のシーケンスでのデフォルト値は1です。
降順のシーケンスでのデフォルト値は、そのデータ型の最小値です。
maxvalueNO MAXVALUE
MAXVALUE 句は、シーケンスの最大値を決定します。この句は省略可能です。
この句が指定されなかった場合、もしくはmaxvalueNO MAXVALUEが指定された場合、デフォルトが使用されます。
昇順のシーケンスでのデフォルト値は、そのデータ型の最大値です。
降順のシーケンスでのデフォルト値は-1です。
start
START WITH 句を使用すると、任意の数からシーケンス番号を開始することができます。この句は省略可能です。
デフォルトでは、シーケンス番号が始まる値は、昇順の場合startminvalue、降順の場合maxvalueになります。
cache
CACHE オプションは、あらかじめ番号を割り当て、メモリに格納しておくシーケンス番号の量を指定します。これによりアクセスを高速にすることができます。
最小値は1です(一度に生成する値が1つだけなので、キャッシュがない状態になります)。これがデフォルトになっています。
cache
CYCLENO CYCLE
CYCLEオプションを使用すると、シーケンスが限界値(昇順の場合はmaxvalue、降順の場合はminvalue)に達した時、そのシーケンスを周回させることができます。
限界値まで達した時、次に生成される番号は、昇順の場合はminvalue、降順の場合はmaxvalueになります。
NO CYCLEが指定された場合、シーケンスの限界値に達した後のnextval呼び出しは全てエラーになります。
CYCLEもNO CYCLEも指定されていない場合は、NO CYCLEがデフォルトとなります。
OWNED BY table_name.column_nameOWNED 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の拡張です。