主キーとNULL制約

主キーとNULL制約 とは

主キーとNULL制約について、SQLでの設定方法を実践的に学びます。本レッスンでは、主キーとNULL制約 の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

なぜ重要か

テーブル設計の二大柱は 主キー (Primary Key)NULL の扱い です。主キーは「行を一意に識別するための約束」、NULL は「値がまだ無い・該当しない」を表す特別な状態。どちらもデータ品質の根幹に関わり、ここを軽く扱うとあとから集計や結合がぐちゃぐちゃになります。

初心者がよく踏むのは「name を主キーにしたら、同姓同名で詰んだ」「電話番号に NULL を許したら、検索結果がいつも 1 件足りない」といった失敗です。本レッスンでは主キーと NULL の役割を整理し、PRIMARY KEYNOT 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 を発行してそれを主キーにする方式
diagram (will load when visible)

現代の業務システムでは、サロゲートキー (例: id BIGINT GENERATED BY DEFAULT AS IDENTITYUUID) を主キーに据え、業務的な一意性は 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_idamount のように業務上必ず必要な列は 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 つができることを確認しましょう。

  1. 主キー・NULL の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (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');

期待される出力

idnameemailphone
2鈴木suzuki@example.comNULL
4高橋takahashi@example.comNULL

ヒント

query.sql
query.sql
学習モード
コードの実行結果
データベースを初期化中...