CodeGym /課程 /SQL SELF /外鍵: FOREIGN KEY

外鍵: FOREIGN KEY

SQL SELF
等級 19, 課堂 0
開放

想像一下你有兩個資料表:一個放學生資料,一個放課程資料。你覺得要怎麼表示哪些學生選了哪些課程?你可以在學生表裡加一個欄位來存他們選的所有課程,但這很快就會變成一團亂。最好的解法之一,就是用 外鍵 啦!

外鍵(FOREIGN KEY) 就是一個欄位或一組欄位,用來建立資料表之間的關聯。它會指向另一個表的欄位(通常是 PRIMARY KEY),確保兩邊的資料有參照完整性。所以如果某個學生選了一門課,我們就能確定那門課真的存在。

外鍵的好處:

  • 幫你維護資料完整性,保證一個表的資料真的有對應到另一個表。
  • 讓資料庫結構更清楚、更有邏輯。
  • 讓資料處理更簡單,避免重複跟出錯。

生活中的例子

想像一下圖書館。books 表放書的清單,members 表放會員清單。要追蹤誰借了哪本書,我們可以建立一個 borrowed_books 表,透過外鍵連到 books 跟 members。這樣每次有人借書,我們就能精確知道是誰借的、借了哪本。

資料表之間的關聯型態

外鍵可以描述不同的資料表關聯。我們來看三種最常見的:

1. 一對一關聯(ONE-TO-ONE)

這是最簡單的關聯,一個表的一筆資料只對應另一個表的一筆資料。比如 users 表放使用者資料,profiles 表放額外資訊(像地址或照片)。

一對一關聯的 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. 一對多關聯(ONE-TO-MANY)

這是最常見的關聯。比如一個客戶可以有很多訂單。這時 customers 表會用外鍵連到 orders 表。

一對多關聯的 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 表的資料。

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)

有時候一個表的資料可以對應到另一個表的多筆資料,反過來也一樣。比如學生選課,一門課可以有很多學生,一個學生也可以選很多課。這時通常會用一個中介表來處理。

多對多關聯的 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 會不讓你插入或更新。
  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 年代資料庫理論大神 Edgar Codd 發明的。很神奇吧,這個概念超強大,到現在還是現代資料庫的核心。誰說經典不流行?

現在你已經懂什麼是外鍵、為什麼它很重要。接下來你還會學到怎麼在建表時加外鍵,還有怎麼正確用連帶操作。不過這些就等下次講座再說囉!

2
任務
SQL SELF, 等級 19, 課堂 0
上鎖
建立帶有外鍵的資料表
建立帶有外鍵的資料表
2
任務
SQL SELF, 等級 19, 課堂 0
上鎖
「一對多」關聯:訂單與客戶
「一對多」關聯:訂單與客戶
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION