CodeGym /コース /SQL SELF /外部キー: FOREIGN KEY

外部キー: FOREIGN KEY

SQL SELF
レベル 19, レッスン 0
使用可能

例えば、学生のデータが入ったテーブルと、コースのデータが入ったテーブルがあるとするよ。どの学生がどのコースを受講してるかって、どうやって表現する?学生テーブルに受講してるコース全部を入れるカラムを追加するって手もあるけど、それだとすぐにカオスになるよね。そこで一番いい方法のひとつが、外部キーを使うこと!

外部キー(FOREIGN KEY)っていうのは、テーブル同士のつながりを作るためのカラム(またはカラムのセット)なんだ。他のテーブルのカラム(たいていはPRIMARY KEY)を指してて、データの参照整合性を保証してくれる。だから、もし誰かの学生がコースを受講してるってなったら、そのコースが本当に存在してるってことがちゃんと保証されるんだ。

外部キーのメリット:

  • データの整合性を保ってくれる。つまり、あるテーブルのレコードが他のテーブルのデータとちゃんと対応してることを保証してくれる。
  • データベースが分かりやすくて論理的に整理される。
  • データ処理が楽になるし、重複やミスも防げる。

リアルな例

図書館をイメージしてみて。booksテーブルには本のリスト、membersテーブルには読者のリストがある。誰がどの本を借りたかを管理するには、borrowed_booksテーブルを作って、そこからbooksとmembersに外部キーでつなげるんだ。こうすれば、誰がどの本を借りたか一発で分かる!

テーブル間のリレーションの種類

外部キーを使うと、いろんなテーブル同士の関係を表現できる。ここで代表的な3つのタイプを見てみよう:

1. 「1対1」リレーション(ONE-TO-ONE)

一番シンプルな関係で、あるテーブルの1レコードが、別のテーブルの1レコードとだけ対応してるパターン。例えば、usersテーブルにユーザー情報があって、profilesテーブルに追加情報(住所や写真とか)がある場合とか。

ONE-TO-ONEリレーションのSQL例:

CREATE TABLE users (
    user_id SERIAL PRIMARY KEY,
    username TEXT NOT NULL
);

CREATE TABLE profiles (
    profile_id SERIAL PRIMARY KEY,
    user_id INT UNIQUE REFERENCES users(user_id), -- users.user_idを参照
    address TEXT
);

ここではprofilesテーブルのuser_idカラムが外部キーになってて、usersテーブルのuser_idを参照してるよ。

usersテーブルの例:

user_id - PRIMARY KEY username
1 alice
2 bob
3 charlie

profilesテーブルの例:

profile_id - PRIMARY KEY user_id - FOREIGN KEY address
1 1 Berlin, Germany
2 2 Paris, France
3 3 Tokyo, Japan

2. 「1対多」リレーション(ONE-TO-MANY)

これが一番よく使われる関係。例えば、1人の顧客がたくさんの注文をする場合。customersテーブルとordersテーブルを外部キーでつなげる感じ。

ONE-TO-MANYリレーションのSQL例:

CREATE TABLE customers (
    customer_id SERIAL PRIMARY KEY,
    name TEXT NOT NULL
);

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    customer_id INT REFERENCES customers(customer_id),	-- customers.customer_idを参照
    order_date DATE NOT NULL
);

ordersテーブルには、同じcustomersテーブルの1レコードを指す複数のレコードが入ることができるよ。

customersテーブルの例:

customer_id - PRIMARY KEY name
1 Alice
2 Bob
3 Charlie

ordersテーブルの例:

order_id - PRIMARY KEY customer_id - FOREIGN KEY order_date
1 1 2024-12-01
2 1 2024-12-05
3 2 2024-12-03
4 3 2024-12-07

3. 「多対多」リレーション(MANY-TO-MANY)

たまに、あるテーブルの1レコードが別のテーブルの複数レコードとつながってて、逆もまた然りってパターンがある。例えば、学生がいろんなコースを受講できて、1つのコースにもたくさんの学生がいる場合。こういう時は中間テーブルを作るのが定番。

MANY-TO-MANYリレーションのSQL例:

-- 学生
CREATE TABLE students (
    student_id SERIAL PRIMARY KEY,
    name TEXT NOT NULL
);

-- コース
CREATE TABLE courses (
    course_id SERIAL PRIMARY KEY,
    title TEXT NOT NULL
);

-- "特定の学生が特定のコースを受講してる"
CREATE TABLE enrollments (
    student_id INT REFERENCES students(student_id), -- 学生IDへの参照
    course_id INT REFERENCES courses(course_id),	-- コースIDへの参照
    PRIMARY KEY (student_id, course_id)
);

ここではenrollmentsテーブルがstudentsとcoursesの「橋渡し」役になってるよ。

studentsテーブルの例:

student_id - PRIMARY KEY name
1 Alice
2 Bob
3 Charlie

coursesテーブルの例:

course_id - PRIMARY KEY title
1 SQL Basics
2 Data Structures
3 Algorithms

enrollmentsテーブルの例:

student_id - FOREIGN KEY course_id - FOREIGN KEY
1 1
1 2
2 1
3 3

外部キーを使うメリット

  1. データが一貫性を保てる。 外部キーが存在しないレコードを指してたら、PostgreSQLはINSERTやUPDATEを許してくれない。
  2. テーブル操作が楽になる。 外部キーがあると、テーブル間のデータを簡単につなげて、JOINみたいな複雑なクエリも書きやすい。
  3. 自動的な動作。 関連レコードを削除・更新した時の動作(カスケード削除、NULLセットなど)も設定できる。

PostgreSQLでの外部キーの書き方は?

テーブル作成時に外部キーを追加する基本の書き方:

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    customer_id INT REFERENCES customers(customer_id)   -- 外部キー参照
);

ここで:

  • customer_id — これが外部キー。
  • これはcustomersテーブルのcustomer_idを参照してる。

FOREIGN KEYを明示的に書くこともできるよ:

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    customer_id INT,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

豆知識

「外部キー(FOREIGN KEY)」って言葉は、1970年代にエドガー・コッドが考えたリレーショナルデータベース理論から来てるんだ。びっくりだけど、このアイデアは今でも現役で、モダンなデータベースの超重要な要素なんだよ。クラシックってやっぱりすごい!

これで外部キーが何か、なんで大事なのか分かったよね。テーブル作成時の外部キーの作り方や、カスケード操作の使い方はまた次のレクチャーで!

2
タスク
SQL SELF, レベル 19, レッスン 0
ロック未解除
外部キー付きテーブルの作成
外部キー付きテーブルの作成
2
タスク
SQL SELF, レベル 19, レッスン 0
ロック未解除
注文と顧客の「1対多」リレーション
注文と顧客の「1対多」リレーション
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION