RDBを選ぶ機会があったので調べてみた。
[シーケンス]
シーケンスは連番を利用したいときに利用するDBオブジェクトである。
利用するDBによって多少差はあるが、使い方は以下のような感じ。
- 作成時(DBによって利用可能なオプションに差がある)
CREATE SEQUENCE my_sequece_name INCREMENT BY 1 START WITH 1;
- 取得時
SELECT my_sequence_name.nextval FROM DUAL; // Oracle, h2, MariaDB
SELECT NEXTVAL(my_sequence_name); // PostgreSQL, MariaDB
SELECT NEXT VALUE FOR my_sequence_name; // h2, MariaDB, SQL Server
取得方法も様々だが、後発のMariaDBが色々対応していて、シーケンスについてだけ見れば乗換えやすそうではある。
MySQLではシーケンスの代わりにAUTO_INCREMENT属性を利用できる。
また、ひとくちにシーケンスといっても、DBによって挙動が異なる。
[シーケンスのキャッシュ]
シーケンス作成時にCACHE + 数値
またはNO CACHE
というオプションを指定できる。
パフォーマンス向上のためにメモリ上に事前に採番したシーケンスをキャッシュとして保持する仕組みだ。
しかし、キャッシュがメモリ上に保持されるためDBを再起動すると、シーケンスに欠番が発生することがある。
[キャッシュのデフォルト値比較]
シーケンスに最大どれくらいの欠番が発生するか、はシーケンス作成時に指定されるキャッシュのサイズに依存している。
シーケンス作成時にキャッシュサイズが指定されない場合、欠番はDBのデフォルト値に依存するが、これはDBによって値が異なる。
Oracleのシーケンスキャッシュのデフォルト値は20となっている。
PostgreSQLのシーケンスキャッシュのデフォルト値は1となっている。
MariaDBのシーケンスキャッシュのデフォルト値は1000となっている。
H2のシーケンスキャッシュのデフォルト値は32となっている。
SQL Serverもキャッシュするのがデフォルトの動作だが、デフォルト値がいくつなのかはっきりと書かれてはいない。
以下の記述があるから、デフォルト値が1ということはなさそうだ。
CACHE オプションを使用して作成するときに予期しないシャットダウン (電源障害など)が発生すると、キャッシュ内のシーケンス番号が失われる可能性があります。
以下のサイトの記述が正しければ、SQL Server 2012ではデフォルト値が50だったようだ。最新版だと変わっているのだろうか...。
[まとめ]
- シーケンスの取得方法はDBによって異なる
- シーメンスの値は欠番が発生することがある
- シーケンスの欠番のでき方の一因となるキャッシュサイズもDBによってデフォルト値が異なる