すべてのプロダクト
Search
ドキュメントセンター

PolarDB:シーケンスと自動生成列の使用ガイド

最終更新日:Oct 28, 2025

データベーステーブルを設計する際、ユーザー ID や注文番号などの一意の識別子がプライマリキーとして必要になることがよくあります。これらの ID を手動で管理するのは面倒で、エラーが発生しやすくなります。この問題を解決するために、PolarDB for PostgreSQL (Oracle 互換)シーケンス自動生成列 という 2 つの機能を提供します。どちらの機能も、一意の番号シーケンスを自動的かつ安全に生成できます。このプロセスにより、プライマリキーの管理が簡素化され、データ整合性が確保されます。

特徴

PolarDB for PostgreSQL (Oracle 互換) は、一意のシーケンス値を生成するためのいくつかの方法を提供します。これらのメソッドは、さまざまなシナリオのニーズを満たし、Oracle Database との高い互換性があります。

  • 従来のシーケンス
    従来のシーケンスは、CREATE SEQUENCE コマンドを使用して作成される独立したデータベースオブジェクトです。データを挿入する際には、my_seq.NEXTVAL のように NEXTVAL 疑似列を呼び出して、シーケンスから次の値を明示的に取得する必要があります。その後、その値をテーブルに挿入します。このメソッドは、シーケンスとテーブルが分離されているため、最も柔軟性があります。

  • 自動生成列
    この機能は Oracle 12c で導入されました。シーケンスをテーブル列に暗黙的にバインドします。テーブルを作成する際に、列定義に GENERATED ... AS IDENTITY 句を追加します。これにより、新しい行が挿入されると、データベースが自動的に列の値を生成します。INSERT 文でこれを処理する必要はありません。このメソッドはより便利で、最新のデータベース設計のトレンドに沿っています。

自動生成列には、その動作ポリシーに基づいて 3 つのタイプがあります。

  • GENERATED ALWAYS AS IDENTITY: 強制的な自動生成。システムは常に列の値を生成します。INSERT 文で列に明示的な値を指定することはできません。値を指定しようとすると、エラーが発生します。このポリシーは最も厳格で、データベースが ID を完全にコントロールすることを保証します。

  • GENERATED BY DEFAULT AS IDENTITY: デフォルトの自動生成。システムは INSERT 文で値が指定されていない場合にのみ、列の値を生成します。特定の値を指定すると、システムは指定された値を使用します。ただし、明示的に NULL を指定すると、エラーが発生します。

  • GENERATED BY DEFAULT ON NULL AS IDENTITY: デフォルトまたは NULL での自動生成。これは最も柔軟なポリシーです。システムは、INSERT 文で列が指定されていない場合、または列に明示的に NULL 値を指定した場合に、自動的に値を生成します。このメソッドは、データ移行や、カスタム ID と自動生成 ID の混在が必要なシナリオで役立ちます。

前提条件

お使いの PolarDB for PostgreSQL (Oracle 互換) クラスターは、マイナーエンジンバージョンが 2.0.14.17.36.0 以降である必要があります。

説明

コンソールで マイナーエンジンバージョン番号を表示する か、SHOW polardb_version; 文を使用して確認できます。マイナーエンジンバージョンの要件が満たされていない場合は、マイナーエンジンバージョンをアップグレードする 必要があります。

利点

  • 開発の簡素化: 自動生成列は、ID 生成ロジックをテーブル定義にカプセル化します。これにより、シーケンスを呼び出す必要がないため、INSERT 文がよりシンプルになります。

  • 一意性の保証: データベースは、生成されたシーケンス値が一意であることを保証します。このプロセスにより、アプリケーション層で ID を生成する際に発生する可能性のある競合を回避できます。

  • 高い柔軟性: GENERATED BY DEFAULT ON NULL ポリシーは、自動生成と手動指定の両方をサポートします。これにより、データインポートや既存データの移行など、複雑なシナリオに最適です。

推奨事項

次の表は、さまざまなシーケンス生成メソッドの特徴を比較したものです。

生成メソッド

手動での値指定

明示的な NULL 挿入

柔軟性

データ移行のしやすさ

推奨されるユースケース

従来のシーケンス (SEQUENCE)

サポート

サポート (列が NULL を許可する必要がある)

最高

複数のテーブル間でシーケンスを共有する。

強制生成 (GENERATED ALWAYS)

非サポート

適用外

最低

厳密な自動増分。介入は許可されない。

デフォルト生成 (GENERATED BY DEFAULT)

サポート

非サポート (エラーを返す)

ID の上書きは許可するが、NULL は許可しない。

デフォルトまたは on-NULL 生成 (GENERATED BY DEFAULT ON NULL)

サポート

サポート (自動生成をトリガーする)

最高

新しいアプリケーション、データ移行、および混合 ID シナリオ。

ベストプラクティス

  • 新しいアプリケーションには、GENERATED BY DEFAULT ON NULL AS IDENTITY を使用してください。最も柔軟性があります。

  • GENERATED BY DEFAULT ON NULL は、データ移行や既存の ID を含むデータをインポートする場合に最適な選択肢です。

  • ビジネス要件で、手動介入なしでデータベースが ID を厳密に制御する必要がある場合は、GENERATED ALWAYS AS IDENTITY を使用してください。

  • 高同時実行の挿入シナリオでは、IDENTITY 列または従来のシーケンスに対して、CACHE 20 以上の適切な CACHE 値を設定してください。これにより、パフォーマンスが大幅に向上します。

従来のシーケンスの使用

このメソッドでは、シーケンスとテーブルは 2 つの別々のオブジェクトです。

  1. シーケンスの作成

    まず、CREATE SEQUENCE コマンドを使用してシーケンスオブジェクトを作成します。開始値、ステップサイズ、最大値/最小値などのプロパティをカスタマイズできます。

    CREATE SEQUENCE emp_seq
        START WITH 1000       -- 開始値は 1000
        INCREMENT BY 1        -- 1 ずつ増加
        MAXVALUE 9999         -- 最大値は 9999
        NOCYCLE               -- サイクルしない
        CACHE 20;             -- パフォーマンス向上のために 20 個の値をキャッシュ

    パラメーターの説明

    • START WITH: 開始値。

    • INCREMENT BY: 増分ステップサイズ。

    • MAXVALUE/NOMAXVALUE: 最大値。

    • MINVALUE/NOMINVALUE: 最小値。

    • CYCLE/NOCYCLE: シーケンスがサイクルするかどうかを指定します。

    • CACHE/NOCACHE: キャッシュする値の数。

    • ORDER/NOORDER: 順序を保証するかどうかを指定します。

  2. INSERT 文でのシーケンスの使用

    テーブルにデータを挿入する際、シーケンスの NEXTVAL 疑似列を呼び出して新しい ID を取得します。

    -- シーケンスを使用するテーブルを作成
    CREATE TABLE employees (
        emp_id NUMBER(10) PRIMARY KEY,
        emp_name VARCHAR2(50) NOT NULL
    );
    
    -- データ挿入時に emp_seq.NEXTVAL を呼び出す
    INSERT INTO employees (emp_id, emp_name) VALUES (emp_seq.NEXTVAL, 'John Smith');
    INSERT INTO employees (emp_id, emp_name) VALUES (emp_seq.NEXTVAL, 'Jane Doe');
    
    -- 結果をクエリ
    SELECT * FROM employees;
    -- emp_id  |  emp_name
    -- --------+------------
    -- 1000    | John Smith
    -- 1001    | Jane Doe
    
  3. 結果のクエリ

    SELECT * FROM employees;

    次の結果が返されます。

     emp_id |  emp_name  
    --------+------------
       1000 | John Smith
       1001 | Jane Doe
    (2 rows)
  4. シーケンスの管理

    user_sequences ビューをクエリして、シーケンスの現在のステータスを確認します。ALTER SEQUENCE コマンドを使用してプロパティを変更することもできます。

    -- シーケンスの現在値の表示 (最初に NEXTVAL を一度呼び出す必要があります)
    SELECT emp_seq.CURRVAL FROM dual;
    
    -- シーケンスのステップサイズとキャッシュを変更
    ALTER SEQUENCE emp_seq INCREMENT BY 2 CACHE 50;

自動生成列 (ID 列) の使用

このメソッドは、シーケンスをテーブル列に直接バインドします。よりモダンで便利です。

強制生成 (GENERATED ALWAYS)

これは、すべての ID をデータベースによって厳密に制御する必要がある場合に適しています。

  1. テーブルの作成: 強制自動生成列を持つテーブルを作成し、データを挿入します。

    -- 強制自動生成列を持つテーブルを作成
    CREATE TABLE products (
        product_id NUMBER GENERATED ALWAYS AS IDENTITY (
          START WITH 100 
          INCREMENT BY 10
        ),
        product_name VARCHAR2(100) NOT NULL
    );
    
    -- データ挿入時、product_id 列を指定する必要はなく、また指定できません
    INSERT INTO products (product_name) VALUES ('Laptop');
    INSERT INTO products (product_name) VALUES ('Mouse');
  2. ID を明示的に挿入してみる

    INSERT INTO products (product_id, product_name) VALUES (999, 'Keyboard');

    コマンドは失敗し、エラーが返されます。

    ERROR:  cannot insert a non-DEFAULT value into column "product_id"
    DETAIL:  Column "product_id" is an identity column defined as GENERATED ALWAYS.
  3. 結果のクエリ

    SELECT * FROM products ORDER BY product_id;

    次の結果が返されます。

     product_id | product_name 
    ------------+--------------
            100 | Laptop
            110 | Mouse
    (2 rows)

デフォルト生成 (GENERATED BY DEFAULT)

このメソッドでは、必要に応じて自動生成された ID を上書きできます。ON NULL 句とは異なり、このメソッドでは明示的に NULL を挿入することはできません。

  1. テーブルの作成

    CREATE TABLE transactions (
        trans_id NUMBER GENERATED BY DEFAULT AS IDENTITY,
        amount NUMBER(10,2)
    );
  2. 挿入メソッド 1: ID を指定せず、自動的に生成させます。

    INSERT INTO transactions (amount) VALUES (500.00);
  3. 挿入メソッド 2: カスタム ID を明示的に挿入します。

    INSERT INTO transactions (trans_id, amount) VALUES (9999, 200.00);
  4. 挿入メソッド 3: 明示的に NULL を挿入すると失敗します。

    INSERT INTO transactions (trans_id, amount) VALUES (NULL, 150.00);

    コマンドは失敗し、エラーが返されます。

    ERROR:  null value in column "trans_id" of relation "transactions" violates not-null constraint
    DETAIL:  Failing row contains (null, 150).
  5. 結果のクエリ

    SELECT * FROM transactions ORDER BY trans_id;

    次の結果が返されます。

     trans_id | amount 
    ----------+--------
            1 |    500
         9999 |    200
    (2 rows)

デフォルトまたは on-NULL 生成 (GENERATED BY DEFAULT ON NULL)

これは最も柔軟なメソッドです。新しいアプリケーションやデータ移行シナリオに推奨されます。

  1. テーブルの作成: 柔軟な自動生成列を持つテーブルを作成します。

    -- 柔軟な自動生成列を持つテーブルを作成
    CREATE TABLE customers (
        customer_id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY,
        customer_name VARCHAR2(100) NOT NULL
    );
  2. 挿入メソッド 1: ID を指定しません。データベースが自動的に生成します。

    INSERT INTO customers (customer_name) VALUES ('John Doe');
  3. 挿入メソッド 2: カスタム ID を明示的に挿入します。たとえば、既存データを移行する場合などです。

    INSERT INTO customers (customer_id, customer_name) VALUES (5000, 'Jane Smith');
  4. 挿入メソッド 3: 明示的に NULL を挿入します。データベースが自動的に ID を生成します。

    INSERT INTO customers (customer_id, customer_name) VALUES (NULL, 'Bob Wilson');
  5. 結果のクエリ

    SELECT * FROM customers ORDER BY customer_id;

    次の結果が返されます。

     customer_id | customer_name 
    -------------+---------------
               1 | John Doe
               2 | Bob Wilson
            5000 | Jane Smith
    (3 rows)

シーケンスの管理

従来のシーケンスと、自動生成列に関連付けられた内部シーケンスの両方を管理および保守できます。

シーケンス情報の表示

user_sequences ビューをクエリして、すべてのユーザー定義シーケンスのステータスを監視します。

SELECT sequence_name, min_value, max_value, increment_by,
       last_number, cache_size, cycle_flag
FROM user_sequences;

シーケンスプロパティの変更

ALTER SEQUENCE コマンドを使用して、ステップサイズ、最大値、キャッシュサイズなどのシーケンスプロパティを変更します。

-- emp_seq シーケンスのステップサイズを 2、最大値を 99999、キャッシュを 50 に変更
ALTER SEQUENCE emp_seq
    START WITH 1005
    INCREMENT BY 2
    MAXVALUE 99999
    CACHE 50;

シーケンスのリセット

PolarDB for PostgreSQL (Oracle 互換) は、シーケンスをリセットするコマンドをサポートしていません。標準的な方法は、シーケンスを削除してから再作成することです。

-- 既存のシーケンスを削除
DROP SEQUENCE emp_seq;

-- シーケンスを再作成し、新しい開始値を設定
CREATE SEQUENCE emp_seq START WITH 5000 INCREMENT BY 1;

ユースケース

GENERATED BY DEFAULT ON NULL 機能は、新規ユーザーの ID を自動生成することでユーザー登録を簡素化する一方、データ移行やバッチインポートのために指定された既存の ID もサポートします。

  1. ユーザーアカウントテーブルを作成します。

    CREATE TABLE user_accounts (
        user_id NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY (
            START WITH 100000
            CACHE 100
        ),
        username VARCHAR2(50) UNIQUE NOT NULL,
        email VARCHAR2(100) UNIQUE NOT NULL,
        created_date DATE DEFAULT SYSDATE
    );
  2. ケース 1: 新規ユーザーが登録します。ID は自動的に生成されます。

    INSERT INTO user_accounts (username, email) VALUES ('john_doe', 'john@example.com');
  3. ケース 2: 古いシステムからデータを移行します。既存の ID が指定されます。

    INSERT INTO user_accounts (user_id, username, email, created_date) VALUES (99999, 'legacy_user', 'leg***@system.com', DATE '2020-01-01');
  4. ケース 3: バッチインポート。自動生成された ID と指定された ID を混在させます。

    INSERT ALL
        INTO user_accounts (username, email) VALUES ('alice', 'ali**@test.com')
        INTO user_accounts (user_id, username, email) VALUES (88888, 'system_acct', 'sys***@app.com')
    SELECT * FROM dual;
  5. 最終結果をクエリします。

    SELECT * FROM user_accounts ORDER BY user_id;

    次の結果が返されます。

     user_id |  username   |       email       |    created_date     
    ---------+-------------+-------------------+---------------------
       88888 | system_acct | sys***@app.com    | 2025-09-17 10:21:38
       99999 | legacy_user | leg***@system.com | 2020-01-01 00:00:00
      100000 | john_doe    | john@example.com  | 2025-09-17 10:21:38
      100001 | alice       | ali**@test.com    | 2025-09-17 10:21:38
    (4 rows)