PRIMARY KEY制約(主キー制約)とは?データベース設計の基本を徹底解説

プログラミング・IT

顧客情報や商品データを管理するとき、「この行が誰の情報か」「どの商品のデータか」を確実に特定できる必要があります。そのための仕組みがPRIMARY KEY制約(主キー制約)です。

この記事では、データベース設計において最も基本的で重要な概念である主キー制約について、初心者にも分かりやすく解説していきます。

スポンサーリンク
  1. PRIMARY KEY制約とは?基本を理解しよう
    1. 主キーの定義
    2. 具体例で理解する
  2. なぜPRIMARY KEYが必要なのか
    1. 問題1:データの特定ができない
    2. 問題2:データの更新・削除が危険
    3. 問題3:他のテーブルとの関連付けができない
  3. PRIMARY KEYの特徴と制約
    1. 特徴1:一意性(ユニーク性)
    2. 特徴2:NOT NULL(必須)
    3. 特徴3:テーブルに1つだけ
    4. 特徴4:自動的にインデックスが作成される
  4. PRIMARY KEYの種類
    1. 単一列の主キー(シングルキー)
    2. 複合主キー(コンポジットキー)
  5. PRIMARY KEYの設定方法(SQL文の書き方)
    1. 方法1:列定義時に指定
    2. 方法2:テーブル制約として指定
    3. 方法3:複合主キーの指定
    4. 方法4:既存のテーブルに主キーを追加
    5. 方法5:主キーに名前を付ける
  6. データベース別の書き方
    1. MySQL / MariaDB
    2. PostgreSQL
    3. SQL Server
    4. SQLite
    5. Oracle
  7. 自動採番(AUTO_INCREMENT)の仕組み
    1. 自動採番とは
    2. 自動採番のメリット
    3. 注意点
  8. 主キーと外部キーの関係
    1. 外部キー(FOREIGN KEY)とは
  9. 良い主キーの選び方
    1. 推奨:代理キー(サロゲートキー)
    2. 非推奨:自然キー
    3. 避けるべき主キー
  10. 主キーの変更と削除
    1. 主キーの削除
    2. 主キーの変更
    3. 主キーの値を変更
  11. PRIMARY KEYのパフォーマンスへの影響
    1. 検索が速くなる
    2. データ型の選択が重要
    3. テーブルのサイズへの影響
  12. よくある間違いと注意点
    1. 間違い1:主キーを設定しない
    2. 間違い2:主キーに意味のあるデータを使う
    3. 間違い3:複合主キーの乱用
    4. 間違い4:UUIDを安易に使う
  13. 実践例:ECサイトのテーブル設計
    1. 顧客テーブル
    2. 商品テーブル
    3. 注文テーブル
    4. 注文明細テーブル(複合主キー)
  14. まとめ: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列)の使用を推奨
  • 外部キーとの組み合わせでデータの整合性を保つ

設計のベストプラクティス:

  1. 常に主キーを設定する
  2. 整数型の代理キーを使う(INT AUTO_INCREMENTなど)
  3. 意味のあるデータを主キーにしない
  4. 複合主キーは必要最小限に
  5. 名前付き制約で管理しやすく

よく使う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;

主キーは、データベースの信頼性とパフォーマンスの基盤となります。テーブルを設計する際は、必ず適切な主キーを設定することを心がけましょう。

この記事で学んだ知識を活用すれば、堅牢なデータベース設計ができるようになります。実際のプロジェクトで、ぜひ実践してみてください。

コメント

タイトルとURLをコピーしました