概要
SQLite3 でカラムに主キーを設定するにはいくつか方法があるので この記事ではその方法について記載する。
環境
- Windows 11
- SQLite3 (3.53.1) Command-Line Shell
テーブル作成時にカラムに続けて主キーを指定する
サンプルのテーブルとしてuserテーブルを作成、
id を主キーとする。
| カラム名 | 型 | 制約 |
|---|---|---|
| id | text |
主キー not null制約 |
| name | text |
このテーブルを作成するためには以下のSQLを実行する。
カラム名の後にPRIMARY KEYと記述することで、そのカラムに主キーを設定出来る。
create table user (
id text primary key not null
, name text
);
上記のSQLを実行すると、idカラムに主キーが設定される。
そのため、idカラムには重複する値を登録することは出来ない。
以下は、上記のテーブルにデータを登録する例。
idカラムに重複する値を登録しようするとエラーになる。
sqlite> insert into user (id, name) values ('001', 'sample_name_1');
sqlite> insert into user (id, name) values ('002', 'sample_name_2');
sqlite> insert into user (id, name) values ('001', 'sample_name_3');
Runtime error: UNIQUE constraint failed: user.id (19)
補足
上記の方法で複数カラムを主キーとする、いわゆる「複合キー」を設定しようとするとエラーになる。 複合キーを設定するには次項で説明する「テーブル作成時にPRIMARY KEY句を使用する」を参照のこと。
以下は、複合キーを設定しようとしてエラーになる例。
sqlite> create table user (
(x1...> id text primary key not null
(x1...> , name text primary key
(x1...> );
Parse error: table "user" has more than one primary key
テーブル作成時にPRIMARY KEY句を使用する
カラム名に続けて主キーを指定するのではなく、テーブル作成時にPRIMARY KEY句を使用して主キーを設定することも出来る。
この方法を使用することで、複数カラムを主キーとする「複合キー」を設定することが出来る。
以下は、PRIMARY KEY句を使用して主キーを設定する例。
idカラムを主キーとする場合idカラムとnameカラムを複合キーとして主キーに設定する場合
-- 1.
create table user (
id text not null
, name text
, primary key (id)
);
-- 2.
create table user (
id text not null
, name text not null
, primary key ( id, name )
);
複合キーは複数のカラムの値の組み合わせでユニークになることを保証するため、 複合キーに設定したカラムのいずれかに重複する値があっても、他のカラムの値が異なれば登録することが出来る。
以下は、複合キーを設定したテーブルにデータを登録する例。
sqlite> create table user (
(x1...> id text not null
(x1...> , name text not null
(x1...> , primary key ( id, name )
(x1...> );
sqlite> insert into user (id, name) values ('001', 'sample_name_1');
sqlite> insert into user (id, name) values ('001', 'sample_name_2');
sqlite> insert into user (id, name) values ('001', 'sample_name_1');
Runtime error: UNIQUE constraint failed: user.id, user.name (19)
テーブル作成後に主キーを設定する
SQLite3 では、既存のテーブルに対して主キーを ALTER TABLE等で追加設定することは出来ない。
そのため、既存のテーブルに主キーを設定するには、以下の手順で行う必要がある。
- 新しいテーブルを作成する
- 既存のテーブルから新しいテーブルにデータをコピーする
- 既存のテーブルを削除する
詳しい作業手順は下記の過去記事と同じ手順になる。
結構手間がかかるので、最初のテーブル設計はきっちりやるべし。
主キーを設定するカラムには必ず NOT NULL 制約を設定する
SQLite3 では
PRIMARY KEYを指定しただけでは
NULLを入力することができてしまう。
以下はidカラムに主キーを設定したテーブルにNULLを登録する例。
| カラム名 | 型 | 制約 |
|---|---|---|
| id | text |
主キー |
| name | text |
sqlite> .mode box
sqlite> .nullvalue [null]
sqlite> create table user (
(x1...> id text primary key
(x1...> , name text
(x1...> );
sqlite> insert into user (id, name) values (NULL, 'sample_name_1');
sqlite> insert into user (id, name) values (null, 'sample_name_2');
sqlite> select * from user;
┌────────┬───────────────┐
│ id │ name │
├────────┼───────────────┤
│ [null] │ sample_name_1 │
│ [null] │ sample_name_2 │
└────────┴───────────────┘
上記の例では、idカラムに主キーを設定しているにも関わらず、
NULLを登録することが出来てしまっている。
さらに、NULLであれば複数登録することも出来てしまっている。
そのため、主キーを設定するカラムにはNOT NULL制約を設定したほうがよい。
これは過去バージョンで主キーにNULLが登録出来てしまっていたことに起因しているらしい。
SQLite は後方互換性を重視しているため、NULLが登録できるように維持し、
修正はしない方針らしい。
また、上記の例では主キーのデータ型がtextのためこのような挙動になっているが、
integer型の主キーの場合、もうちょっと厄介な挙動をするので、
やはり、主キーを設定するカラムにはNOT NULL制約は必須という考えでいたほうが安全。
参考URL
-
PRIMARY KEY(英語)
公式のPRIMARY KEYに関するドキュメント
https://www.sqlite.org/lang_createtable.html#the_primary_key -
NOT NULL constraints(英語)
公式のNOT NULL制約に関するドキュメント
https://www.sqlite.org/lang_createtable.html#not_null_constraints -
column-constraint(英語)
公式のカラムに設定する各種制約に関するドキュメント
https://www.sqlite.org/syntax/column-constraint.html
-
SQLite3 備忘録:SQLite3 nullを登録できないようにカラムを設定する(NOT NULL制約)
https://sfnovicenotes.blogspot.com/2022/04/sqlite3-nullnot-null.html -
SQLite3 備忘録:SQLite3 カラムの型を変更する
https://sfnovicenotes.blogspot.com/2021/01/sqlite3.html