PostgreSQL

PostgreSQLリレーション入門|テーブル間の関係を定義する

PostgreSQL リレーション 外部キー

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)を使用します。