CodeGym /课程 /SQL SELF /外键: FOREIGN KEY

外键: FOREIGN KEY

SQL SELF
第 19 级 , 课程 0
可用

想象一下你有两张表:一张存学生信息,一张存课程信息。你觉得怎么表达哪些学生选了哪些课程?你可以在学生表里加一列存所有他们选的课程,但这样很快就乱套了。最好的办法之一就是用外键

外键 (FOREIGN KEY) 就是一列或者几列,用来在表之间建立关联。它指向另一张表的某一列(通常是PRIMARY KEY),保证两张表之间的数据引用是靠谱的。这样,如果某个学生选了某门课,我们就能确定这门课真的存在。

外键的作用:

  • 帮你保持数据一致性,保证一张表里的记录在另一张表里也有对应的数据。
  • 让数据库结构更清晰、更有逻辑。
  • 简化数据处理,防止重复和出错。

现实生活的例子

想象一下图书馆。books表存书的信息,members表存读者的信息。为了追踪谁借了哪本书,我们可以建一个borrowed_books表,通过外键关联booksmembers。这样每次有人借书,我们都能知道是谁借的,借的是哪本。

表之间的关联类型

外键可以描述不同的表关联。我们来看看三种最常见的类型:

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表就是studentscourses之间的“桥”。

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