主キー・外部キー・UNIQUE・NOT NULL:制約でデータを守る

入門 | 10分 で読める | 2026.06.17

公式ドキュメント

データベースでは、間違ったデータが入らないようにするための仕組みがあります。それが制約です。

一言でいうと

制約は、アプリ側の注意だけに頼らず、データベース自身にデータのルールを守らせる仕組みです。

代表的な制約

制約役割
PRIMARY KEY行を一意に識別する
FOREIGN KEY別テーブルとの関係を守る
UNIQUE重複を防ぐ
NOT NULL値なしを防ぐ
CHECK条件に合わない値を防ぐ

PRIMARY KEY

主キーは、テーブル内の1行を一意に識別します。

CREATE TABLE users (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL
);

id が主キーなら、同じ id のユーザーは2人作れません。

主キーには、検索しやすくするだけでなく、他のテーブルから参照される役割もあります。

NOT NULL

NOT NULL は、値が入っていない状態を禁止します。

CREATE TABLE users (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  email TEXT NOT NULL
);

名前やメールアドレスが必須なら、NOT NULL を付けます。

必ず必要な値には、アプリ側の入力チェックだけでなくNOT NULL制約を付けます。

UNIQUE

UNIQUE は、同じ値の重複を防ぎます。

CREATE TABLE users (
  id INTEGER PRIMARY KEY,
  email TEXT NOT NULL UNIQUE
);

この場合、同じメールアドレスのユーザーは登録できません。

ログインID、メールアドレス、スラッグなど、重複してはいけない値に使います。

FOREIGN KEY

外部キーは、別テーブルの主キーを参照します。

CREATE TABLE orders (
  id INTEGER PRIMARY KEY,
  user_id INTEGER NOT NULL REFERENCES users(id),
  total INTEGER NOT NULL
);

この制約があると、存在しない users.idorders.user_id に入れにくくなります。

外部キーは、JOINのためだけでなく、データの整合性を守るために重要です。

CHECK

CHECK は、値が条件を満たすことを確認します。

CREATE TABLE products (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL,
  price INTEGER NOT NULL CHECK (price >= 0)
);

価格がマイナスになることを防げます。

制約がないと何が起きるか

制約がない状態起きる問題
主キーがない1行を特定しにくい
NOT NULL がない必須値が空の行が入る
UNIQUE がない同じメールアドレスが重複する
外部キーがない存在しないユーザーの注文が入る
CHECK がないマイナス価格などが入る

よくある誤解

誤解実際
アプリでチェックするから制約はいらないバグや別経路の登録を防げません
外部キーはJOINに必須JOINはできますが、整合性は守られません
UNIQUE は後から考えればよい重複データが入った後の修正は大変です
NULL 許可で柔軟になる必須データが欠ける原因になります

まとめ

制約は、データベースにデータのルールを守らせる仕組みです。PRIMARY KEYNOT NULLUNIQUEFOREIGN KEYCHECK を適切に使うと、アプリのバグや運用ミスがあっても壊れにくいデータ構造になります。

参考リソース

← 一覧に戻る
PR
PR
PR
PR