2026年6月29日月曜日

SQLite3 テーブルに主キーを設定する(PRIMARY KEY)

概要

SQLite3 でカラムに主キーを設定するにはいくつか方法があるので この記事ではその方法について記載する。

環境
  • Windows 11
  • SQLite3 (3.53.1) Command-Line Shell

テーブル作成時にカラムに続けて主キーを指定する

サンプルのテーブルとしてuserテーブルを作成、 id を主キーとする。

「user」テーブル
カラム名 制約
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句を使用して主キーを設定する例。

  1. idカラムを主キーとする場合
  2. 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等で追加設定することは出来ない。 そのため、既存のテーブルに主キーを設定するには、以下の手順で行う必要がある。

  1. 新しいテーブルを作成する
  2. 既存のテーブルから新しいテーブルにデータをコピーする
  3. 既存のテーブルを削除する

詳しい作業手順は下記の過去記事と同じ手順になる。
結構手間がかかるので、最初のテーブル設計はきっちりやるべし。

主キーを設定するカラムには必ず NOT NULL 制約を設定する

SQLite3 では PRIMARY KEYを指定しただけでは NULLを入力することができてしまう。

以下はidカラムに主キーを設定したテーブルにNULLを登録する例。

「user」テーブル
カラム名 制約
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