AUTOINCREMENT
カラムのデータ型をINTEGER型にしてPRIMARY KEY制約を設定すると、そのカラムには自動で連番の値が格納されることは既に説明しました。簡単にユニークな連番が割り当てられるのは便利なのですが、一度割り当てられた値であってもその値が格納されたデータが削除され使用されなくなると、再度同じ値が他のデータに割り当てられる可能性があり、それが問題となる場合があります。
そこでカラムに対してINTEGER PRIMARY KEYを設定する時にAUTOINCREMENTも合わせて記述すると、一度割り当てられた値は二度と使われないようにすることができます。
AUTOINCREMENTはINTEGER PRIMARY KEYと同時に指定する必要があり書式は次の通りです。
CREATE TABLE テーブル名(カラム名 INTEGER PRIMARY KEY AUTOINCREMENT, ...);
※MySQLではAUTO_INCREMENTですが、SQLiteではAUTOINCREMENTなので注意して下さい。
サンプル
では実際に試してみます。
テーブルを作成し3つのデータを追加しました。
では「ID」カラムの値が3のデータを削除します。
ここでデータを追加した場合、AUTOINCREMENTを指定していないと追加されたデータの「ID」カラムの値は3となります。それに対してAUTOINCREMENTが指定されていると、追加されたデータの「ID」カラムの値は現在の最大の値に1を加えた値以上で一度も使われたことのない値である4となります。
このようにAUTOINCREMENTが指定されていれば、そのカラムの値は削除されたデータまで含めて重複しない値が常に割り当てられることになります。
なおAUTOINCREMENTを指定した場合は、ROWIDの値も一度使われた値は使われなくなります。つまりAUTOINCREMENTを指定してもINTEGER PRIMARY KEYが設定されたカラムの値とROWIDの値は常に同じです。
※ROWIDについては「ROWID」を参照して下さい。
カラムに格納されたことのある最大の値
INTEGER PRIMARY KEY AUTOINCREMENTが設定されたカラムがあるテーブルについては、対象のカラムに過去に割り当てられたことのある最大の値が保存されています。仮に最大の値が一度削除されたとしても、最大の値はそのまま残っていますので次に値を連番で割り当てる時は保存してある最大の値に1を加えた値を割り当てるだけで済みます。
過去に割り当てられたことのある最大の値は特別なテーブルである「sqlite_sequence」テーブルに格納されています。
このテーブルには「name」と「seq」の2つのカラムがあり、「name」にはテーブル名、「seq」にはINTEGER PRIMARY KEY AUTOINCREMENTが設定されたカラムに過去に割り当てられたことのある最大の値が格納されています。
では最大の値が割り当てられているデータを削除してみます。
最大の値が使われているデータは削除されましたが、「sqlite_sequence」テーブルの「seq」カラムの値は変化しません。ではデータを一つ追加してみます。
追加されたデータの自動で割り当てられるカラムの値は、「sqlite_sequence」テーブルの「seq」カラムの値に1を加えた値となります。では「sqlite_sequence」テーブルのデータを再度取得してみます。
「seq」カラムの値が5に更新されていることが確認できます。