SQL構文(DDL):シーケンス(SEQUENCE)とは
数値を自動的に生成するためのオブジェクトです。主にテーブルの主キーやユニークな値を自動で割り当てる目的で使用します。
シーケンスの特徴
- 連続した数値の生成
1ずつ増加する数値や、任意の増分で数値を生成する事ができます。 - ユニーク性
同じ値を重複して作成しない為、主キーやユニーク列で使用されます。 - 他のテーブルと独立して動作
テーブルの外部で独立したオブジェクトとして存在する為、異なるテーブルやカラムでの再利用が可能です。
シーケンス(SEQUENCE)の作成
作成構文
CREATE SEQUENCE sequence_name
[ INCREMENT BY increment_value ] -- 増分を指定(デフォルト: 1)
[ MINVALUE min_value ] -- 最小値を指定(デフォルト: 型の最小値)
[ MAXVALUE max_value ] -- 最大値を指定(デフォルト: 型の最大値)
[ START WITH start_value ] -- 開始値(デフォルト: MINVALUE)
[ CACHE cache_value ] -- キャッシュする値の個数(デフォルト: 1)
[ CYCLE | NO CYCLE ]; -- 最大値を超えた場合に再びMINVALUEに戻るかどうか(デフォルト: NO CYCLE)
各オプションの説明
- INCREMENT BY increment_value
シーケンスが生成する値の増分を指定します。デフォルトは1で、負の値を指定すると値が減少する方向にカウントされます。
- TEMP | TEMPORARY
一時ビューを作成します。セッションが終了するとビューは削除されます。
- MINVALUE min_value
シーケンスが生成する値の最小値を指定します。負のシーケンス(値が減少)の場合、最小値は負の値になります。 - MAXVALUE max_value
シーケンスが生成する値の最大値を指定します。シーケンスがこの値に達すると、オプションに応じて停止するか、最小値に戻ります(CYCLEが有効な場合)。デフォルトでは整数の最大値(BIGINT型:9223372036854775807)が設定されます。 - START WITH start_value
シーケンスが最初に生成する値を指定します。デフォルトでは増加するシーケンスの場合は1、減少するシーケンスの場合は、最小値(BIGINT型:-9223372036854775808)を使用します。 - CACHE cache_value
パフォーマンスを向上させるために、シーケンスの次の値をあらかじめ生成しておく個数を指定します。但し、キャッシュが大きいほどシーケンスの取得が高速になりますが、障害が発生した場合、一部の値が失われる可能性があります。 - CYCLE | NO CYCLE
シーケンスが最大値に達したときに、最小値に戻って再びカウントを続けるかどうかを指定します。CYCLE
を指定すると、最大値に達した後、シーケンスは最小値に戻りますが、NO CYCLE
を指定すると、最大値に達した時点でエラーが発生します。
シーケンス(SEQUENCE)の作成例
- シーケンスの作成例
このシーケンスは、1000から開始して1ずつ増加し、9999まで達したら再び1000に戻ります。キャッシュは10個分を保持します。
CREATE SEQUENCE order_seq
INCREMENT BY 1 -- 1ずつ増加
MINVALUE 1000 -- 最小値は1000
MAXVALUE 9999 -- 最大値は9999
START WITH 1000 -- 1000から開始
CACHE 10 -- 次の10個の値をキャッシュ
CYCLE; -- 9999に達したら1000に戻る
シーケンスの使用例
- シーケンスから次の値を取得するには、nextval()関数を使用します。
SELECT nextval('order_seq');
- 現在のシーケンスの値を取得するには、currval()を使用します。ただし、currval()はそのセッションでnextval()が呼び出された後にのみ有効です。
SELECT currval('order_seq');
- シーケンスの現在の値を手動で設定するには、
setval()
を使用します。
SELECT setval('order_seq', 5000); -- 現在の値を5000に設定
- 作成後でもシーケンスの設定を変更することが可能です。
ALTER SEQUENCE order_seq INCREMENT BY 5;
シーケンスの実践的使用例
- テーブルの主キーにシーケンスを利用する
シーケンスはテーブルの主キー(ID)を自動生成するために頻繁に使われます。SERIAL
型を使うと、PostgreSQLは内部的にシーケンスを生成し、自動でIDを増加させます。
下記の場合user_idは自動的にシーケンスから生成されたユニークな値が割り当てられます。レコードを挿入するとき、user_idを指定する必要はありません。
CREATE TABLE users (
user_id SERIAL PRIMARY KEY, -- user_idはシーケンスで自動生成
username VARCHAR(100)
);
INSERT INTO users (username) VALUES ('John Doe');
-- 自動的に user_id が 1 となり挿入される
- SERIAL型を使わずに、シーケンスを自分で作成して主キーを管理する
下記の例では、user_idがuser_seqシーケンスから生成され、ユーザーが挿入されるたびにuser_idが増加します。
CREATE SEQUENCE user_seq START 1000;
CREATE TABLE users (
user_id INTEGER DEFAULT nextval('user_seq'), -- シーケンスから値を取得
username VARCHAR(100),
PRIMARY KEY (user_id)
);
- シーケンスを使ったユニークな注文番号の生成
シーケンスを使ってユニークな注文番号を生成することができます。この場合、注文が挿入されるたびに、order_id
はorder_seq
シーケンスから生成され、ユニークな注文番号が割り当てられます。
CREATE SEQUENCE order_seq START 1000;
CREATE TABLE orders (
order_id INTEGER DEFAULT nextval('order_seq'), -- 注文番号はシーケンスから生成
customer_id INTEGER,
product_id INTEGER,
order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO orders (customer_id, product_id)
VALUES (1, 101); -- シーケンスにより自動的に注文番号が割り当てられる
- 複数テーブルでシーケンスを共有
一つのシーケンスを複数のテーブルで共有し、同じシーケンスからユニークIDを生成することも可能です。
この場合、customers
とsuppliers
テーブルで共通のシーケンスを使ってIDを生成しているので、両テーブルで重複しないユニークIDを共有できます。
CREATE SEQUENCE global_seq START 1000; -- グローバルなシーケンス
CREATE TABLE customers (
customer_id INTEGER DEFAULT nextval('global_seq'), -- global_seq から生成
name VARCHAR(100),
PRIMARY KEY (customer_id)
);
CREATE TABLE suppliers (
supplier_id INTEGER DEFAULT nextval('global_seq'), -- 同じ global_seq から生成
company_name VARCHAR(100),
PRIMARY KEY (supplier_id)
);
INSERT INTO customers (name) VALUES ('Alice');
-- customer_id は global_seq から 1000 が割り当てられる
INSERT INTO suppliers (company_name) VALUES ('ACME Corp');
-- supplier_id は global_seq から 1001 が割り当てられる
- シーケンスを使って特定の範囲で番号を生成
シーケンスを利用して、指定した範囲内で番号を生成することができます。このシーケンスは、100
から始まり、10
ずつ増加し、1000
に達すると再び100
に戻ります。
CREATE SEQUENCE limited_seq
START WITH 100
INCREMENT BY 10
MINVALUE 100
MAXVALUE 1000
CYCLE; -- 最大値を超えると最小値に戻る
SELECT nextval('limited_seq'); -- 100
SELECT nextval('limited_seq'); -- 110
...
SELECT nextval('limited_seq'); -- 1000
SELECT nextval('limited_seq'); -- 100 (CYCLEにより戻る)
UPDATE
やINSERT
文でシーケンスを活用
シーケンスを使ってテーブルの特定の列を自動的に更新したり、新しいデータを挿入するときに利用できます。この例では、user_id
がNULL
のレコードに対して、シーケンスuser_seq
から値を取得して一括でIDを設定します。
- 既存のレコードに対してシーケンスを使って番号を付与
UPDATE users
SET user_id = nextval('user_seq')
WHERE user_id IS NULL;
RETURNING
句を使ったシーケンスの利用RETURNING
句を使って、シーケンスで生成されたIDを挿入時に取得することができます。このようにすると、挿入されたレコードのorder_id
(シーケンスによって自動生成された値)が返され、プログラムや他のクエリでその値を利用できます。
INSERT INTO orders (customer_id, product_id)
VALUES (1, 101)
RETURNING order_id; -- 挿入されたレコードの order_id を返す