SQLite 3 でオートインクリメントなカラムを作りたかったら、
CREATE TABLE my_diary ( diary_id INTEGER PRIMARY KEY, subject TEXT, body TEXT, create_dt TEXT );
と主キーを INTEGER にしてテーブルを作れば、そのカラムは自動的にオートインクリメントになる、というのは今や常識的。
主キーにしたくない場合は INSERT INTO my_diary VALUES((SELECT max(diary_id) FROM my_diary) + 1, 'タイトル', '本文', '2009-01-29'); などと更新時の SQL 文を工夫するとか。
ただ AUTOINCREMENT というキーワードもあって、"PRIMARY KEY" の後ろにこれを付けるか付けないかで振る舞いが違ってくる。
具体的には、AUTOINCREMENT キーワードを付けて宣言した場合、ID の再利用がされない。
SQLite のオートインクリメントは「その時点で最大の数に 1 足したもの」を自動的に割り振る仕組みっぽいんだけど、AUTOINCREMENT を付けると「これまでに使われたものの最大値に 1 足したもの」という意味になる。
たとえば次のようなデータを持つテーブルで、
diary_id | subject | body | create_dt |
---|---|---|---|
1 | タイトル 1 | 本文 1 | 2009-01-28 |
2 | タイトル 2 | 本文 2 | 2009-01-29 |
3 | タイトル 3 | 本文 3 | 2009-01-20 |
なんとなく 3 行目の dairy_id = 3 の行を消したとして、そのあと INSERT で新しい行を追加すると、
- AUTOINCRENEMT なし
- 新しい行の diary_id = 3
- AUTOINCRENEMT あり
- 新しい行の diary_id = 4
という結果になる。
こうなるのはその時点で最大値の主キーを削除したためで、AUTOINCREMENT を付けないと消した値は忘れられているので再利用されることになる。
あくまで最大値がポイントだから、上の例で diary_id = 2 の行を消しても diary_id は 3 が最大値のままだから、新規行が diary_id = 4 になるだけで全く関係ない。
というようなことが、公式ドキュメントの FAQ トップにしっかり書かれてあった。
SQLite Frequently Asked Questions
http://www.sqlite.org/faq.html#q1
個別のページでも詳しく解説されてた。
SQLite Autoincrement
http://www.sqlite.org/autoinc.html
ちょろっと探しただけじゃ見つからなかったので忘れないようにメモっておく。
コメント