OpenText Analytics Database 旧Vertica

技術情報サイト

Analytics Database

シーケンスによる採番を連番にする方法

公開日:
更新日:
基本操作
#データロード

はじめに

本記事では、シーケンスによって採番される番号を連番にする方法(NO CACHEパラメータ)を紹介します。
NO CACHEパラメータを使用しない場合、シーケンスはセッション毎に予め一定数の番号をメモリにキャッシュしてから採番するため、一部の番号が抜ける可能性があります。
一方で、NO CACHEパラメータを使用する場合は、ディスク上で番号を管理するため、連番を保つことができます。
※NO CACHEパラメータを使用する場合、採番時に毎回ディスクアクセスが発生する動作のため、データロードの性能が落ちる可能性があります。十分なテストを行った上でのご利用をご検討ください。

構文

連番にする場合の構文

CREATE SEQUENCE シーケンス名 MINVALUE 1 START WITH 1 INCREMENT BY 1 NO CACHE;

実行例

連番にする場合

/*** テーブル定義を確認 ***/
dbadmin=> \d table1
                                    List of Fields by Tables
 Schema | Table  | Column |    Type     | Size | Default | Not Null | Primary Key | Foreign Key 
--------+--------+--------+-------------+------+---------+----------+-------------+-------------
 public | table1 | col1   | int         |    8 |         | f        | f           | 
 public | table1 | col2   | varchar(15) |   15 |         | f        | f           | 
(2 rows)

/*** キャッシュなしのシーケンスオブジェクトを作成 ***/
dbadmin=> CREATE SEQUENCE seq1
dbadmin-> MINVALUE 1
dbadmin-> START WITH 1
dbadmin-> INCREMENT BY 1
dbadmin-> NO CACHE;
CREATE SEQUENCE

/*** ノード1のセッションで採番(1件目) ***/
dbadmin=> INSERT INTO table1 values(seq1.NEXTVAL, 'table1 node1');
 OUTPUT 
--------
      1
(1 row)

/*** ノード1のセッションで採番(2件目) ***/
dbadmin=> INSERT INTO table1 values(seq1.NEXTVAL, 'table1 node1');
 OUTPUT 
--------
      1
(1 row)

dbadmin=> COMMIT;
COMMIT

/*** データを確認 ***/
dbadmin=> SELECT * FROM table1 ORDER BY col1;
 col1 |     col2     
------+--------------
    1 | table1 node1
    2 | table1 node1
(2 rows)

/*** ノード2のセッションで採番(1件目) ***/
dbadmin=> INSERT INTO table1 values(seq1.NEXTVAL, 'table1 node2');
 OUTPUT 
--------
      1
(1 row)

/*** ノード2のセッションで採番(2件目) ***/
dbadmin=> INSERT INTO table1 values(seq1.NEXTVAL, 'table1 node2');
 OUTPUT 
--------
      1
(1 row)

dbadmin=> COMMIT;
COMMIT

/*** データを確認 ***/
/*** ノード2のセッションから採番したデータは、ノード1のデータと連続する ***/
dbadmin=> SELECT * FROM table1 ORDER BY col1;
 col1 |     col2     
------+--------------
    1 | table1 node1
    2 | table1 node1
    3 | table1 node2
    4 | table1 node2
(4 rows)

/*** ノード3のセッションで採番(1件目) ***/
dbadmin=> INSERT INTO table1 values(seq1.NEXTVAL, 'table1 node3');
 OUTPUT 
--------
      1
(1 row)

/*** ノード3のセッションで採番(2件目) ***/
dbadmin=> INSERT INTO table1 values(seq1.NEXTVAL, 'table1 node3');
 OUTPUT 
--------
      1
(1 row)

dbadmin=> COMMIT;
COMMIT

/*** データを確認 ***/
/*** ノード3のセッションから採番したデータは、ノード1やノード2のデータと連続する ***/
dbadmin=> SELECT * FROM table1 ORDER BY col1;
 col1 |     col2     
------+--------------
    1 | table1 node1
    2 | table1 node1
    3 | table1 node2
    4 | table1 node2
    5 | table1 node3
    6 | table1 node3
(6 rows)

連番でなくても良い場合

/*** テーブル定義を確認 ***/
dbadmin=> \d table2
                                    List of Fields by Tables
 Schema | Table  | Column |    Type     | Size | Default | Not Null | Primary Key | Foreign Key 
--------+--------+--------+-------------+------+---------+----------+-------------+-------------
 public | table2 | col1   | int         |    8 |         | f        | f           | 
 public | table2 | col2   | varchar(15) |   15 |         | f        | f           | 
(2 rows)

/*** キャッシュありのシーケンスオブジェクトを作成 ***/
dbadmin=> CREATE SEQUENCE seq2
dbadmin-> MINVALUE 1
dbadmin-> START WITH 1
dbadmin-> INCREMENT BY 1;
CREATE SEQUENCE

/*** ノード1のセッションで採番(1件目) ***/
dbadmin=> INSERT INTO table2 values(seq2.NEXTVAL, 'table2 node1');
 OUTPUT 
--------
      1
(1 row)

/*** ノード1のセッションで採番(2件目) ***/
dbadmin=> INSERT INTO table2 values(seq2.NEXTVAL, 'table2 node1');
 OUTPUT 
--------
      1
(1 row)

dbadmin=> COMMIT;
COMMIT

/*** データを確認 ***/
dbadmin=> SELECT * FROM table2 ORDER BY col1;
 col1 |     col2     
------+--------------
    1 | table2 node1
    2 | table2 node1
(2 rows)

/*** ノード2のセッションで採番(1件目) ***/
dbadmin=> INSERT INTO table2 values(seq2.NEXTVAL, 'table2 node2');
 OUTPUT 
--------
      1
(1 row)

/*** ノード2のセッションで採番(2件目) ***/
dbadmin=> INSERT INTO table2 values(seq2.NEXTVAL, 'table2 node2');
 OUTPUT 
--------
      1
(1 row)

dbadmin=> COMMIT;
COMMIT

/*** データを確認 ***/
/*** ノード2のセッションから採番したデータは、ノード1のデータと連続しない ***/
dbadmin=> SELECT * FROM table2 ORDER BY col1;
  col1   |     col2     
---------+--------------
       1 | table2 node1
       2 | table2 node1
 1000001 | table2 node2
 1000002 | table2 node2
(4 rows)

/*** ノード3のセッションで採番(1件目) ***/
dbadmin=> INSERT INTO table2 values(seq2.NEXTVAL, 'table2 node3');
 OUTPUT 
--------
      1
(1 row)

/*** ノード3のセッションで採番(2件目) ***/
dbadmin=> INSERT INTO table2 values(seq2.NEXTVAL, 'table2 node3');
 OUTPUT 
--------
      1
(1 row)

dbadmin=> COMMIT;
COMMIT

/*** データを確認 ***/
/*** ノード3のセッションから採番したデータは、ノード1やノード2のデータと連続しない ***/
dbadmin=> SELECT * FROM table2 ORDER BY col1;
  col1   |     col2     
---------+--------------
       1 | table2 node1
       2 | table2 node1
 1000001 | table2 node2
 1000002 | table2 node2
 2000001 | table2 node3
 2000002 | table2 node3
(6 rows)

参考情報

CREATE SEQUENCEのSQLリファレンス

CREATE SEQUENCEの構文や各パラメータの詳細は、以下のマニュアルをご参照ください。
https://www.vertica.com/docs/10.1.x/HTML/Content/Authoring/SQLReferenceManual/Statements/CREATESEQUENCE.htm

複数ノード構成でキャッシュする番号の仕様

上述「3.2 連番でなくても良い場合」の実行例のように、一定数の番号をキャッシュする場合は、セッション毎に採番の開始番号が異なります。
また、複数ノード構成の場合にはノード毎にキャッシュする番号が異なります。
詳細は以下のマニュアルをご参照ください。https://www.vertica.com/docs/10.1.x/HTML/Content/Authoring/AdministratorsGuide/Sequences/HowVerticaAllotsCacheforSequencing.htm

検証バージョンについて

この記事の内容はVertica 10.1で確認しています。

更新履歴

2021/07/01 本記事を公開