PostgreSQLリレーション入門
テーブル間の関係を定義する
テーブル間のリレーション(1対1、1対多、多対多)の設計と外部キー制約を解説します。
こんな人向けの記事です
- テーブル間の関連付けを理解したい人
- 外部キー制約の設定方法を知りたい人
- 多対多の関係を中間テーブルで実装したい人
Step 1リレーションの種類
| 種類 | 説明 | 例 |
|---|---|---|
| 一対一(1:1) | 1行が他テーブルの最大1行に関連 | ユーザーとプロフィール |
| 一対多(1:N) | 1行が他テーブルの複数行に関連 | 部門と従業員 |
| 多対多(M:N) | 複数行が互いに複数行に関連 | 学生と授業 |
Step 2一対多(1:N)リレーション
最も一般的なリレーションです。「多」側のテーブルに外部キーを配置します。
SQL
CREATE TABLE departments (
dept_id SERIAL PRIMARY KEY,
dept_name VARCHAR(100) NOT NULL
);
CREATE TABLE employees (
emp_id SERIAL PRIMARY KEY,
emp_name VARCHAR(100) NOT NULL,
dept_id INTEGER REFERENCES departments(dept_id),
hire_date DATE NOT NULL
);
Step 3多対多(M:N)リレーション
中間テーブル(結合テーブル)を使って実装します。
SQL
CREATE TABLE students (
student_id SERIAL PRIMARY KEY,
student_name VARCHAR(100) NOT NULL
);
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY,
course_name VARCHAR(100) NOT NULL
);
-- 中間テーブル
CREATE TABLE enrollments (
student_id INTEGER REFERENCES students(student_id) ON DELETE CASCADE,
course_id INTEGER REFERENCES courses(course_id) ON DELETE CASCADE,
enrollment_date DATE NOT NULL DEFAULT CURRENT_DATE,
PRIMARY KEY (student_id, course_id)
);
Step 4外部キーの参照アクション
親レコードが削除・更新された時の子レコードの動作を定義します。
| アクション | 説明 |
|---|---|
| CASCADE | 親と一緒に子も削除/更新 |
| RESTRICT | 子があれば親の削除を禁止(デフォルト) |
| SET NULL | 子のFK列をNULLに設定 |
| SET DEFAULT | 子のFK列をデフォルト値に設定 |
SQL
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(user_id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
Step 5自己参照リレーション
テーブルが自分自身を参照する特殊なリレーションです。階層構造の表現に使います。
SQL
-- 従業員の上司-部下関係
CREATE TABLE employees (
employee_id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
manager_id INTEGER REFERENCES employees(employee_id)
);
-- カテゴリの階層構造
CREATE TABLE categories (
category_id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
parent_id INTEGER REFERENCES categories(category_id)
);
ポイント: 自己参照の階層データを検索する場合は、再帰的共通テーブル式(WITH RECURSIVE)を使用します。