文系出身がゼロからSQLを学んでみた 〜制約編〜
はじめに
現在、業務に向けた基礎スキルとしてSQLの学習を進めています。
その中で「キー制約」は、データベース設計の土台になる重要な考え方だと感じました。
この記事では、Primary Keyや外部キーなどのキー関連の制約を中心に、NOT NULLやCHECK、DEFAULTなどの代表的な制約もあわせて整理します。
制約とは?
制約(Constraint) とは、テーブルやカラムに対して設定するルールです。
不正なデータの登録を防ぎ、データの整合性を保つために使われます。
今回は代表的な以下の制約について学習しました。
- Primary Key
- UNIQUE
- 外部キー
- NOT NULL
- CHECK
- DEFAULT
キー関連の制約
Primary Key
Primary Keyとは、各行を一意に識別するための列で、重複せず、NULLにもできません。
マイナンバーや、学生証に書かれる学生番号のような全員に配られるものと考えると理解しやすいです。
例えば、以下のテーブルではidがPrimary Keyになります。
id name age
1 Satoshi 20
2 Momoko 30
3 Kazuya 20
同じidは絶対に存在せず、idを指定すれば、対象の行を一意に特定できます。
Primary Keyがないと以下のように情報が重複した際に区別ができません。
Primary Keyがあることでどちらのデータかを正確に区別することができます。
name age
Kazuya 20
Momoko 30
Kazuya 20 #どちらのKazuyaか区別できない
UNIQUE
重複した値を入れられないようにする制約です。
同じ値を2回入れたくない列に使用します。
例えば、メールアドレス、電話番号、ユーザー名などがあたります。
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100) UNIQUE
);
上記の場合、emailがUNIQUEに指定されているので、同じemailを入れることはできません。
Primary KeyとUNIQUEの違い
どちらも重複できない制約のため、最初は違いがよくわからなかったのですが、以下のように考えるとわかりやすかったです。
PRIMARY KEY
→ 重複NG
→ NULL NG
→ テーブルに1つだけ
→ 「この列で行を識別する」という宣言
UNIQUE
→ 重複NG
→ NULL OK
→ テーブルに複数設定できる
→ 「この列は重複しない」という宣言
CREATE TABLE users (
id INTEGER PRIMARY KEY, # 1つだけ
email VARCHAR(100) UNIQUE, # 複数設定できる
phone VARCHAR(20) UNIQUE, # これもUNIQUE
name VARCHAR(50)
);
上記のように、Primary Keyはひとつだけですが、UNIQUEは複数指定することができます。
外部キー
FOREIGN KEY(外部キー)は、別のテーブルのidを参照するカラムのことです。
外部キーの目的は、存在しない値を入れられないようにし、テーブル間のデータの整合性を保つことです。
参照先に存在しない値は登録できません。
ただし、NOT NULL制約がなければNULLを許可できる場合もあります。
# usersテーブル
id name
1 Hana
2 Kana
# postsテーブル
id user_id content
1 1 おはよう
2 2 こんにちは
3 1 おやすみ
上記のような2つのテーブルがあった場合、user_idが外部キーになります。
この例だと「誰の投稿か」をusersテーブルと紐づけるのが外部キーの役割です。
SQLには以下のように書きます。
CREATE TABLE posts (
id INTEGER PRIMARY KEY,
user_id INTEGER NOT NULL,
content VARCHAR(100),
FOREIGN KEY (user_id) REFERENCES users(id)
);
単一キーと複合キー
単一キーはひとつのカラムだけで識別できるものに用います。
一方、複合主キーは、単一カラムのPRIMARY KEYのように各カラムの後ろには書けず、PRIMARY KEY (カラム1, カラム2,...) の形でまとめて指定します。
日常生活に例えると、
単一キー = マイナンバー(1つの番号で識別)
複合キー = 座席番号
映画館の座席
「A列」だけでは識別できない
「3番」だけでは識別できない
「A列3番」で初めて識別できる
複合キーの指定方法は2つあります。
# テーブル作成時に指定
CREATE TABLE attendance (
student_id INTEGER,
class_id INTEGER,
date DATE,
PRIMARY KEY (student_id, class_id, date)
);
# 後から追加
ALTER TABLE attendance
ADD PRIMARY KEY (student_id, class_id, date);
複合キーの指定は必ず最後にまとめて指定する必要があり、カラムの後ろに書くことはできません。
# 最後にまとめて書く
CREATE TABLE attendance (
student_id INTEGER,
class_id INTEGER,
date DATE,
PRIMARY KEY (student_id, class_id)
);
上記のように複合キーは必ず、
PRIMARY KEY (カラム1, カラム2, カラム3)
というように()内にまとめて指定する必要があります。
値に関する制約
NOT NULL
NOT NULLの目的は、必須項目に空欄が入らないようにすることです。
これにより、データの抜け漏れを防ぐことができるため、絶対に入力が必要な列に使います。
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name VARCHAR(50) NOT NULL #名前必須・空欄NG
);
上記の場合、値があれば通常通り値が入りますが、NOT NULLでNULLを入れられないようにしているので、空欄はエラーになります。
CHECK
CHECKとは、入れられる値に条件をつける制約です。
例えば年齢にマイナスはありえないので以下のように条件をつけます。
age INTEGER CHECK(age >= 0)
age = 20 # 0以上なのでOK
age = -1 # 0未満なのでエラー
上記のようにすることで、入れられない値が入らないようにガードすることができます。
省略時の規定値設定
DEFAULT
DEFAULTは、INSERT時に値を省略したときに自動で入る既定値、いわゆる何も入れなかったときの初期値です。
age INTEGER DEFAULT 0
SQLは上記のように書き、このときageを入力すると、その値が入力されます。
しかし、ageを入力しなかった場合はDEFAULTで0を指定しているため、自動的に0が入力されます。
# ageを入力した場合
INSERT INTO users (name, age) VALUES ('Kazuya', 30)
→ age = 30
# ageを入力しなかった場合
INSERT INTO users (name) VALUES ('Takuya')
→ age = 0 # DEFAULTの値が自動で入る
会員登録など初期設定の場面で使われることが多く、
数値 → DEFAULT 0
文字 → DEFAULT '初期値'
フラグ → DEFAULT 0 or 1
上記のように、最初の状態として自然な値を設定することがポイントです。
まとめ
キー制約は単なる文法ではなく、不正なデータを防ぎ、データの整合性を保つための重要な仕組みです。
学習を通して、何を防ぐための制約なのかを意識して考えると、理解しやすいと感じました。
クラスメソッドオペレーションズ株式会社について
クラスメソッドグループのオペレーション企業です。
運用・保守開発・サポート・情シス・バックオフィスの専門チームが、IT・AIをフル活用した「しくみ」を通じて、お客様の業務代行から課題解決や高付加価値サービスまでを提供するエキスパート集団です。
当社は様々な職種でメンバーを募集しています。
「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、クラスメソッドオペレーションズ株式会社 コーポレートサイトをぜひご覧ください。
※2026年1月 アノテーション㈱から社名変更しました。










