【PostgreSQL】 SQL構文(DDL):シーケンス(SEQUENCE)

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_idorder_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を生成することも可能です。
    この場合、customerssuppliersテーブルで共通のシーケンスを使って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により戻る)


  • UPDATEINSERT文でシーケンスを活用
    シーケンスを使ってテーブルの特定の列を自動的に更新したり、新しいデータを挿入するときに利用できます。この例では、user_idNULLのレコードに対して、シーケンス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 を返す

タイトルとURLをコピーしました