目次
はじめに
本記事では、シーケンスによって採番される番号を連番にする方法(NO CACHEパラメータ)を紹介します。NO CACHEパラメータを使用しない場合、シーケンスはセッション毎に予め一定数の番号をメモリにキャッシュしてから採番するため、一部の番号が抜ける可能性があります。
一方で、NO CACHEパラメータを使用する場合は、ディスク上で番号を管理するため、連番を保つことができます。
※NO CACHEパラメータを使用する場合、採番時に毎回ディスクアクセスが発生する動作のため、データロードの性能が落ちる可能性があります。十分なテストを行った上でのご利用をご検討ください。
構文
連番にする場合の構文
CREATE SEQUENCE シーケンス名 MINVALUE 1 START WITH 1 INCREMENT BY 1 NO CACHE;
実行例
連番にする場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
/*** テーブル定義を確認 ***/ 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) |
連番でなくても良い場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
/*** テーブル定義を確認 ***/ 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