AUTOINCREMENTを設定する場合としない場合の違い
INTEGER PRIMARY KEYにAUTOINCREMENTを合わせて設定した場合にどのように自動的に値が割り当てられるようになるのかについて解説します。また今までに割り当てられたことのある最大の値を確認する方法を合わせてご紹介します。
1.AUTOINCREMENTを設定した場合の値の割り当てルール
2.カラムに格納されたことのある最大の値
カラムに対してINTEGER PRIMARY KEYを設定した場合、データを追加した時にカラムの値を指定しないと自動的に値が格納されます。自動的に格納される値は、対象のカラムに格納されている最大の値に1を加えた値となります。この値は以前に割り当てられたことがあるかどうか関係がないため、データの追加と削除を繰り返していると以前に格納されたことがある値が再度カラムに格納される場合があります。
INTEGER PRIMARY KEYにAUTOINCREMENTを合わせて指定すると自動的に設定される値のルールが変わります。対象のカラムに現在格納されている最大の値に1が加えられるのではなく、対象のカラムに今までに格納されたことのある最大の値に1が加えられた値が格納されるようになります。
CREATE TABLE テーブル名(カラム名 INTEGER PRIMARY KEY AUTOINCREMENT, ...);
データが残っているかどうかは関係がないため、自動的に設定される値は常に今までで最大の値となります。その結果、今までに格納されたことがある値が自動的に格納されることはありません。
では実際に試してみます。まずはAUTOINCREMENTを指定しない場合にどうなるのかを確認してみます。次のようなテーブルを作成しました。
create table user(id integer primary key, name text);
3つのデータを追加します。INTEGER PRIMARY KEYを設定してあるカラムには値を指定していませんので自動的に値が格納されます。
「ID」カラムに一番大きい値が入っているデータ(「ID」カラムの値が3のデータ)を削除します。
ここで再びデータを追加します。この時INTEGER PRIMARY KEYを設定してあるカラムに値を指定しない場合、対象のカラムに格納されている最大の値(現在は2)に1を加えた値が自動的に設定されるため、カラムに自動的に設定される値は3となります。
このように以前に一度別のデータに割り当てられた値であっても関係無く最大の値に1を加えた値がカラムに設定されます。
----
では次にAUTOINCREMENTを合わせて指定してみます。次のようなテーブルを作成しました。
create table user(id integer primary key autoincrement, name text);
先ほどと同じように3つのデータを追加します。INTEGER PRIMARY KEY AUTOINCREMENTを設定してあるカラムには値を指定していませんので自動的に値が格納されます。データ追加後に「ID」カラムに一番大きい値が入っているデータ(「ID」カラムの値が3のデータ)を削除します。
ここで再びデータを追加します。この時INTEGER PRIMARY KEY AUTOINCREMENTを設定してあるカラムに値を指定しない場合、対象のカラムに今までに格納されたことのある最大の値(現在は3)に1を加えた値が自動的に設定されるため4が格納されます。
このようにAUTOINCREMENTを設定すれば以前に設定されたことのある値が再び使用されることを防ぐことが可能です。
AUTOINCREMENTがカラムに設定されている場合、削除されたデータも含めて過去に対象のカラムに格納されたことのある最大の値を参照することになりますが、この値はSQLiteが自動で作成する特別なテーブルである「sqlite_sequence」テーブルに格納されています。
「sqlite_sequence」テーブルのスキーマを確認してみると、「name」と「seq」の2つのカラムが含まれていることが分かります。
「name」にはテーブル名、「seq」にはINTEGER PRIMARY KEY AUTOINCREMENTが設定されたカラムに過去に割り当てられたことのある最大の値が格納されます。では先ほど使用していた「user」テーブルの最大の値を確認してみます。
現在「user」テーブルではINTEGER PRIMARY KEY AUTOINCREMENTが設定されたカラムに今までに格納された最大の値が4であることが確認できます。
( Written by Tatsuo Ikura )