顧客情報や商品データを管理するとき、「この行が誰の情報か」「どの商品のデータか」を確実に特定できる必要があります。そのための仕組みがPRIMARY KEY制約(主キー制約)です。
この記事では、データベース設計において最も基本的で重要な概念である主キー制約について、初心者にも分かりやすく解説していきます。
PRIMARY KEY制約とは?基本を理解しよう

主キーの定義
PRIMARY KEY(主キー)とは、テーブル内の各行を一意に識別するための列(または列の組み合わせ)のことです。
分かりやすく言えば、「データの身分証明書」のようなものです。
具体例で理解する
学校のクラス名簿を考えてみましょう:
| 出席番号 | 名前 | 年齢 |
|---|---|---|
| 1 | 田中太郎 | 15 |
| 2 | 佐藤花子 | 15 |
| 3 | 鈴木一郎 | 16 |
この場合、「出席番号」が主キーです。出席番号さえ分かれば、誰の情報か確実に特定できますよね。
同じ名前の生徒がいるかもしれませんし、同じ年齢の生徒も複数いるでしょう。しかし、出席番号は必ず重複しません。これが主キーの役割です。
なぜPRIMARY KEYが必要なのか
主キーがないと、どんな問題が起きるのでしょうか。
問題1:データの特定ができない
主キーがない顧客テーブルを想像してください:
| 名前 | 住所 |
|---|---|
| 山田太郎 | 東京都 |
| 山田太郎 | 大阪府 |
この場合、「山田太郎さんの住所を変更する」という操作をしたとき、どちらの山田太郎さんなのか判断できません。
問題2:データの更新・削除が危険
特定のデータを更新したいとき、主キーがなければ:
- 意図しないデータまで変更してしまう
- 複数のデータを誤って削除してしまう
といったリスクが高まります。
問題3:他のテーブルとの関連付けができない
注文テーブルで「誰が注文したか」を記録する場合、顧客を確実に特定する方法が必要です。主キーがなければ、テーブル間の関連付け(リレーション)ができません。
PRIMARY KEYの特徴と制約
主キーには、厳格なルールがあります。
特徴1:一意性(ユニーク性)
主キーの値は、テーブル内で絶対に重複してはいけません。
OK:
顧客ID: 1, 2, 3, 4, 5...
NG:
顧客ID: 1, 2, 2, 3, 4... ← 2が重複!
特徴2:NOT NULL(必須)
主キーの値は絶対にNULLであってはいけません。
NULLとは「値が存在しない」という状態です。身分証明書が空欄では困りますよね。
OK:
顧客ID: 1, 2, 3, 4
NG:
顧客ID: 1, NULL, 3, 4 ← NULLは不可!
特徴3:テーブルに1つだけ
1つのテーブルに定義できる主キーは1つだけです。
ただし、複数の列を組み合わせて1つの主キーとすることはできます(後述する複合主キー)。
特徴4:自動的にインデックスが作成される
主キーを設定すると、データベースは自動的にその列にインデックス(索引)を作成します。これにより、データの検索が高速になります。
PRIMARY KEYの種類
主キーには、大きく分けて2つのタイプがあります。
単一列の主キー(シングルキー)
最も一般的なパターンです。1つの列だけで主キーを構成します。
例:顧客テーブル
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100)
);
この場合、customer_idだけで各顧客を識別できます。
複合主キー(コンポジットキー)
複数の列を組み合わせて、1つの主キーを構成します。
例:受講記録テーブル
CREATE TABLE enrollments (
student_id INT,
course_id INT,
enrollment_date DATE,
PRIMARY KEY (student_id, course_id)
);
この場合、「学生ID」と「コースID」の組み合わせで一意になります。同じ学生が同じコースに2回登録することはできません。
使い分けのポイント:
- 単一列:シンプルで管理しやすい(推奨)
- 複合主キー:多対多の関連テーブルなどで使用
PRIMARY KEYの設定方法(SQL文の書き方)

データベースごとに、主キーの設定方法を見ていきましょう。
方法1:列定義時に指定
最もシンプルな方法です。
CREATE TABLE users (
user_id INT PRIMARY KEY,
username VARCHAR(50),
email VARCHAR(100)
);
方法2:テーブル制約として指定
複数列を使う場合や、後から追加する場合に使います。
CREATE TABLE users (
user_id INT,
username VARCHAR(50),
email VARCHAR(100),
PRIMARY KEY (user_id)
);
方法3:複合主キーの指定
CREATE TABLE order_items (
order_id INT,
product_id INT,
quantity INT,
PRIMARY KEY (order_id, product_id)
);
方法4:既存のテーブルに主キーを追加
すでに作成済みのテーブルに、後から主キーを追加する場合:
ALTER TABLE users
ADD PRIMARY KEY (user_id);
方法5:主キーに名前を付ける
主キー制約に名前を付けると、後から管理しやすくなります:
CREATE TABLE products (
product_id INT,
product_name VARCHAR(100),
CONSTRAINT pk_products PRIMARY KEY (product_id)
);
pk_productsが主キー制約の名前です。
データベース別の書き方
主要なデータベースでの主キー設定方法を紹介します。
MySQL / MariaDB
CREATE TABLE customers (
customer_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100)
);
AUTO_INCREMENTを使うと、自動で番号が割り振られます。
PostgreSQL
CREATE TABLE customers (
customer_id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(100)
);
SERIALが、MySQLのAUTO_INCREMENTに相当します。
SQL Server
CREATE TABLE customers (
customer_id INT IDENTITY(1,1) PRIMARY KEY,
name NVARCHAR(100) NOT NULL,
email NVARCHAR(100)
);
IDENTITY(1,1)は「1から始まり、1ずつ増える」という意味です。
SQLite
CREATE TABLE customers (
customer_id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT
);
Oracle
CREATE TABLE customers (
customer_id NUMBER PRIMARY KEY,
name VARCHAR2(100) NOT NULL,
email VARCHAR2(100)
);
-- シーケンスを使った自動採番
CREATE SEQUENCE customer_id_seq START WITH 1;
自動採番(AUTO_INCREMENT)の仕組み
主キーには、通常「自動採番」の機能を使います。
自動採番とは
データを新規登録するたびに、自動的に次の番号を割り振る機能です。
例:顧客を3人登録する
INSERT INTO customers (name, email) VALUES ('田中太郎', 'tanaka@example.com');
-- customer_id = 1 が自動で割り振られる
INSERT INTO customers (name, email) VALUES ('佐藤花子', 'sato@example.com');
-- customer_id = 2 が自動で割り振られる
INSERT INTO customers (name, email) VALUES ('鈴木一郎', 'suzuki@example.com');
-- customer_id = 3 が自動で割り振られる
自動採番のメリット
- 手動で番号を管理する必要がない
- 重複の心配がない
- 連番が保証される(欠番が生じる場合もあるが)
注意点
削除したIDは再利用されません:
DELETE FROM customers WHERE customer_id = 2;
-- customer_id = 2 は欠番になる
INSERT INTO customers (name, email) VALUES ('山田次郎', 'yamada@example.com');
-- customer_id = 4 が割り振られる(2ではない)
主キーと外部キーの関係
主キーは、他のテーブルとの関連付けに使われます。
外部キー(FOREIGN KEY)とは
別のテーブルの主キーを参照する列のことです。
例:注文テーブルと顧客テーブル
顧客テーブル:
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
name VARCHAR(100)
);
注文テーブル:
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
この構造により:
- 注文は必ず既存の顧客に紐付く
- 存在しない顧客IDでは注文を作成できない
- 顧客を削除するとき、その顧客の注文がある場合はエラーになる
主キーと外部キーの組み合わせで、データの整合性が保たれます。
良い主キーの選び方

どの列を主キーにすべきか、設計の指針を紹介します。
推奨:代理キー(サロゲートキー)
専用のID列を作成し、それを主キーにする方法です。
CREATE TABLE products (
product_id INT PRIMARY KEY, -- 代理キー
product_code VARCHAR(20),
product_name VARCHAR(100)
);
メリット:
- 値が変わらない
- シンプルで管理しやすい
- パフォーマンスが良い
非推奨:自然キー
実際のデータ(メールアドレスや商品コードなど)を主キーにする方法です。
CREATE TABLE users (
email VARCHAR(100) PRIMARY KEY, -- 自然キー
name VARCHAR(100)
);
デメリット:
- メールアドレスが変わったら主キーも変わる
- 長い文字列は処理が遅い
- 外部キーで参照している場合、変更が複雑
避けるべき主キー
1. 意味のある情報を主キーにしない
-- 悪い例
CREATE TABLE products (
product_name VARCHAR(100) PRIMARY KEY -- 商品名は変わる可能性がある
);
2. 複雑すぎる複合主キー
-- 悪い例:5つの列を組み合わせた主キー
PRIMARY KEY (col1, col2, col3, col4, col5)
管理が複雑になり、パフォーマンスも悪化します。
主キーの変更と削除
主キーを変更したり削除したりする方法です。
主キーの削除
ALTER TABLE users
DROP PRIMARY KEY;
注意:
他のテーブルから外部キーで参照されている場合、削除できません。
主キーの変更
直接変更はできないので、一度削除してから再作成します:
-- 1. 既存の主キーを削除
ALTER TABLE users
DROP PRIMARY KEY;
-- 2. 新しい主キーを設定
ALTER TABLE users
ADD PRIMARY KEY (new_column);
主キーの値を変更
主キーの値自体を変更することは、通常推奨されません。
どうしても必要な場合:
UPDATE users
SET user_id = 999
WHERE user_id = 1;
ただし、外部キーで参照されている場合は、それらも連動して変更する必要があります(CASCADE設定による)。
PRIMARY KEYのパフォーマンスへの影響
主キーは、データベースのパフォーマンスに大きく影響します。
検索が速くなる
主キーには自動的にインデックスが作成されるため、主キーでの検索は非常に高速です。
-- 非常に速い
SELECT * FROM users WHERE user_id = 123;
-- 主キーでない列での検索は遅い可能性
SELECT * FROM users WHERE email = 'example@example.com';
データ型の選択が重要
推奨:整数型(INT)
product_id INT PRIMARY KEY
非推奨:長い文字列
product_id VARCHAR(200) PRIMARY KEY -- 遅い
整数型の方が:
- 比較が速い
- メモリ使用量が少ない
- インデックスのサイズが小さい
テーブルのサイズへの影響
主キーが大きいと、外部キーでも同じサイズが必要になり、データベース全体が肥大化します。
よくある間違いと注意点
初心者がやりがちなミスを紹介します。
間違い1:主キーを設定しない
-- 悪い例
CREATE TABLE products (
name VARCHAR(100),
price DECIMAL(10,2)
);
主キーがないと、データの特定ができず、後から問題が発生します。
間違い2:主キーに意味のあるデータを使う
-- 悪い例
CREATE TABLE employees (
employee_name VARCHAR(100) PRIMARY KEY
);
同姓同名がいたら破綻します。
間違い3:複合主キーの乱用
-- 悪い例:不必要に複雑
CREATE TABLE logs (
year INT,
month INT,
day INT,
hour INT,
user_id INT,
PRIMARY KEY (year, month, day, hour, user_id)
);
シンプルにlog_idを作る方が良いです。
間違い4:UUIDを安易に使う
-- 場合によっては問題
CREATE TABLE users (
user_id CHAR(36) PRIMARY KEY -- UUID
);
UUIDは一意性が高いですが、文字列なので整数より遅く、サイズも大きくなります。
実践例:ECサイトのテーブル設計
実際のシステムでの主キーの使い方を見てみましょう。
顧客テーブル
CREATE TABLE customers (
customer_id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(100) UNIQUE NOT NULL,
name VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
商品テーブル
CREATE TABLE products (
product_id INT AUTO_INCREMENT PRIMARY KEY,
product_name VARCHAR(200) NOT NULL,
price DECIMAL(10,2) NOT NULL,
stock_quantity INT DEFAULT 0
);
注文テーブル
CREATE TABLE orders (
order_id INT AUTO_INCREMENT PRIMARY KEY,
customer_id INT NOT NULL,
order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
total_amount DECIMAL(10,2),
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
注文明細テーブル(複合主キー)
CREATE TABLE order_details (
order_id INT,
product_id INT,
quantity INT NOT NULL,
unit_price DECIMAL(10,2) NOT NULL,
PRIMARY KEY (order_id, product_id),
FOREIGN KEY (order_id) REFERENCES orders(order_id),
FOREIGN KEY (product_id) REFERENCES products(product_id)
);
この設計により:
- 各テーブルで行を一意に識別できる
- テーブル間の関連が明確
- データの整合性が保たれる
まとめ:PRIMARY KEYはデータベース設計の土台
PRIMARY KEY制約は、データベース設計において最も基本的で重要な概念です。
この記事の重要ポイント:
- 主キーは各行を一意に識別する「身分証明書」
- 一意性とNOT NULL制約が必須
- テーブルに1つだけ設定できる
- 自動的にインデックスが作成され、検索が高速化
- 代理キー(専用のID列)の使用を推奨
- 外部キーとの組み合わせでデータの整合性を保つ
設計のベストプラクティス:
- 常に主キーを設定する
- 整数型の代理キーを使う(INT AUTO_INCREMENTなど)
- 意味のあるデータを主キーにしない
- 複合主キーは必要最小限に
- 名前付き制約で管理しやすく
よく使うSQL文:
-- 主キー付きテーブル作成
CREATE TABLE users (
user_id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL
);
-- 既存テーブルに主キー追加
ALTER TABLE users ADD PRIMARY KEY (user_id);
-- 主キーの削除
ALTER TABLE users DROP PRIMARY KEY;
主キーは、データベースの信頼性とパフォーマンスの基盤となります。テーブルを設計する際は、必ず適切な主キーを設定することを心がけましょう。
この記事で学んだ知識を活用すれば、堅牢なデータベース設計ができるようになります。実際のプロジェクトで、ぜひ実践してみてください。

コメント