制約_3(SQLiteを学ぶ_14)

SQLiteを学んでいこうという連載の14回目です。前回の記事はこちらになります。

hirocom777.hatenadiary.org

前回は、SQLiteのPRIMARY KEY制約についてご紹介しました。今回も引き続きPRIMARY KEY制約についてご紹介します。

主キーを設定する

前回お話しましたが、PRIMARY KEY制約は主キーを設定するためのものです。これまで確認したPRIMARY KEY制約のテーブルへの登録を見てみましょう。今までの事例ではテーブル内の入力して管理される列にPRIMARY KEY制約を設定していました。

sqlite> CREATE TABLE sample(id INTEGER,name TEXT PRIMARY KEY,age INTEGER);

大体こんな感じです。しかしながら実際の運用では主キー用の列を設けて運用することの方が多いと思います。先頭にIDなどという名前で設定されているテーブルを見かけますが、それです。上の例でいくと、id列がそれにあたります。id列を主キーに設定してテーブルを作ってみましょう。

sqlite> CREATE TABLE sample(id INTEGER PRIMARY KEY,name TEXT,age INTEGER);

id列にPRIMARY KEY制約を設定することによって、name列、age列にが同じレコードがあったとしても区別がつくようになります。というよりも、先頭列に「ID」等とあって通し番号が振ってあるテーブルをよく見かけますが、主キーとして扱う列なんです。

INTEGER型のPRIMARY KEY制約

データ型がINTEGERに設定されている列にPRIMARY KEY制約を設定すると、以下の機能が付与されます。

  • PRIMARY KEY制約を設定した列のデータを省略すると自動的に整数の値が設定される

データ入力の際にRIMARY KEY制約を設定した列のデータを省略すると、自動的に整数の値が設定されます。値は入力済みデータの最大値+1です。以下を実行してみました。

sqlite> CREATE TABLE sample(id INTEGER PRIMARY KEY,name TEXT,age INTEGER);
sqlite> INSERT INTO sample VALUES(null,"MURAYAMA",22);
sqlite> INSERT INTO sample VALUES(null,"TANAKA",29);
sqlite> INSERT INTO sample VALUES(null,"YAMADA",26);
sqlite> SELECT * FROM sample;
┌────┬────────────┬─────┐
│ id │    name    │ age │
├────┼────────────┼─────┤
│ 1  │ 'MURAYAMA' │ 22  │
│ 2  │ 'TANAKA'   │ 29  │
│ 3  │ 'YAMADA'   │ 26  │
└────┴────────────┴─────┘

id列を省略(null)して入力したデータは、1~3が設定されました。

  • PRIMARY KEY制約を設定した列には整数(INTEGER)以外のデータが設定できなくなる

SQLiteでは列に指定したデータ型も入力できたりします。これは以下でご説明しました。

hirocom777.hatenadiary.org

上のテーブルで以下を実行してみました。

sqlite> INSERT INTO sample VALUES('A',"TANAKA",25);
Runtime error: datatype mismatch (20)
sqlite> INSERT INTO sample VALUES(10,"TANAKA",25);
sqlite> SELECT * FROM sample;
┌────┬────────────┬─────┐
│ id │    name    │ age │
├────┼────────────┼─────┤
│ 1  │ 'MURAYAMA' │ 22  │
│ 2  │ 'TANAKA'   │ 29  │
│ 3  │ 'YAMADA'   │ 26  │
│ 10 │ 'TANAKA'   │ 25  │
└────┴────────────┴─────┘

id列に文字「'A'」を入力しようとするとエラーになりました。一方整数「10」とした場合は正常に入力されました。

CREATE TABLE sample(id INTEGER AUTOINCREMENT,name TEXT,age INTEGER);

AUTOINCREMENT

INTEGER型でPRIMARY KEY制約を設けた列には、さらにAUTOINCREMENTを指定できます。指定方法は以下になります。

CREATE TABLE テーブル名(列名 データ型 PRIMARY KEY AUTOINCREMENT);

AUTOINCREMENTを指定すると主キー列の番号の振り方が少し変わります。指定していない場合前述した通り「入力済みデータの最大値+1」の値が設定されますが、指定した場合には「今まで使用したデータの最大値+1」となるのです。

違いは値が再利用されるかどうかです。AUTOINCREMENTを指定していない場合はレコードを削除した場合、削除したレコードの主キーの値が新しく追加したレコードの主キーの値として使用される可能性があります。指定した場合は削除したレコードの主キーの値は再利用されません。

でも、このAUTOINCREMENTは余り推奨されていないようです。メモリ、CPUなど余計なリソースを消費するようですね。それにSQLiteにはROWIDという仕組みがあってそちらを使用したほうが便利なんです。

次回はROWID

いかがでしょうか。PRIMARY KEY制約の動きについて大体わかったと思います。次回はROWIDです。実はPRIMARY KEY制約を指定しなくてもSQLiteは追加したレコードにそれぞれ個別の番号を振っているんです。この仕組みについてご紹介しようと思います。お楽しみに!!

hirocom777.hatenadiary.org

SQLite学習記事のまとめですはこちらから