主キーとNULL制約
主キーとNULL制約 とは
主キーとNULL制約について、SQLでの設定方法を実践的に学びます。本レッスンでは、主キーとNULL制約 の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
なぜ重要か
テーブル設計の二大柱は 主キー (Primary Key) と NULL の扱い です。主キーは「行を一意に識別するための約束」、NULL は「値がまだ無い・該当しない」を表す特別な状態。どちらもデータ品質の根幹に関わり、ここを軽く扱うとあとから集計や結合がぐちゃぐちゃになります。
初心者がよく踏むのは「name を主キーにしたら、同姓同名で詰んだ」「電話番号に NULL を許したら、検索結果がいつも 1 件足りない」といった失敗です。本レッスンでは主キーと NULL の役割を整理し、PRIMARY KEY と NOT NULL をどう使い分けるかを掴みます。
主キーとは何か
主キーは テーブル内で行を一意に識別する列 (または列の組み合わせ) です。要件は次の 2 つを同時に満たすことです。
- NOT NULL, つまり値が必ず入っている
- UNIQUE, つまり全行を通じて重複していない
SQL クエリ
CREATE TABLE users (
id INT PRIMARY KEY,
email VARCHAR(100) NOT NULL UNIQUE,
name VARCHAR(50) NOT NULL
);この例では id が主キー、email は補助キー (代替キー) として UNIQUE で守っています。主キーがあれば「あの行を更新したい」「あの行を消したい」が確実に指定できます。
自然キーとサロゲートキー
主キーには 2 つの流派があります。
自然キー(Natural Key) は、業務的な意味を持つ値 (メールアドレス、商品コードなど) をそのまま主キーにする方式サロゲートキー(Surrogate Key) は、業務とは無関係な連番やUUIDを発行してそれを主キーにする方式
現代の業務システムでは、サロゲートキー (例: id BIGINT GENERATED BY DEFAULT AS IDENTITY や UUID) を主キーに据え、業務的な一意性は UNIQUE 制約で別途守る、というスタイルが定石です。理由はシンプルで、業務ルールは変わるからです。電話番号もメールアドレスも、いつか変わるかもしれない値を主キーにすると、関連テーブル全部に波及してしまいます。
迷ったら サロゲートキーを主キーにする のが安全です。
idを不変の識別子として固定し、業務的な一意性 (email, code 等) は別の UNIQUE 制約で守ると、変更コストを最小化できます。
NULL は「値がない」状態
NULL は数字の 0 でも空文字 '' でもなく、「値が存在しない / 不明 / 該当しない」 を表す特殊な状態です。たとえば phone 列が NULL なら「電話番号は登録されていない」、shipped_at が NULL なら「まだ発送していない」を意味します。
SQL クエリ
-- NG パターン NULL に対する = は常に NULL を返すため、結果が空になる
SELECT * FROM users WHERE phone = NULL;
-- OK パターン IS NULL / IS NOT NULL を使う
SELECT * FROM users WHERE phone IS NULL;
SELECT * FROM users WHERE phone IS NOT NULL;NULL は通常の値とは比較ロジックが違うため、= NULL や <> NULL は思った通りに動きません。SQL では 3 値論理 (TRUE / FALSE / UNKNOWN) を採用しており、NULL を含む比較はすべて UNKNOWN になります。
NULL を許す列は、設計の段階で「本当に NULL を許す業務的な意味があるか」を必ず問い直してください。安易に NULL を許すと、後の集計クエリで毎回 IS NULL 分岐が必要になります。
NOT NULL 制約
NULL を入れさせたくない列には NOT NULL を付けます。これは「この列には必ず値を入れること」というアプリ全体への契約になります。
SQL クエリ
CREATE TABLE orders (
id INT PRIMARY KEY,
customer_id INT NOT NULL, -- 顧客は必ず必要
amount INT NOT NULL, -- 金額は必ず必要
shipped_at TIMESTAMP -- 発送日は NULL を許す
);customer_id や amount のように業務上必ず必要な列は NOT NULL、shipped_at のように「まだ発送していない」状態を表したい列は NULL 許容、というのが基本方針です。
演習でやること
演習エディタには users テーブルが入っています。phone 列に NULL を含むレコードがあるので、IS NULL / IS NOT NULL の挙動を試してみましょう。
まとめ
- 主キーは NOT NULL かつ UNIQUE な列 (または列の組合せ)
- 業務的な意味のないサロゲートキーを使うのが現代の定石
- NULL は 0 でも空文字でもなく「値がない」を表す特殊状態
- NULL の比較は = ではなく IS NULL / IS NOT NULL を使う
- 必須項目には NOT NULL を付けて契約を強制する
次のレッスン
次は 基礎確認クイズ です。SQLの基礎知識をクイズ形式で確認し、理解度を深めましょう。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- 主キー・NULL の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. 主キー・NULL とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
テーブル構造
schema.sql
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
phone VARCHAR(20)
);
INSERT INTO users (id, name, email, phone) VALUES
(1, '田中', 'tanaka@example.com', '090-1111-2222'),
(2, '鈴木', 'suzuki@example.com', NULL),
(3, '佐藤', 'sato@example.com', '080-3333-4444'),
(4, '高橋', 'takahashi@example.com', NULL),
(5, '山本', 'yamamoto@example.com', '070-5555-6666');期待される出力
| id | name | phone | |
|---|---|---|---|
| 2 | 鈴木 | suzuki@example.com | NULL |
| 4 | 高橋 | takahashi@example.com | NULL |