跳到主要内容

外键

通过外键保证表之间的关系,关联数据的完整性

  • 外键(Foreign Key)用于描述两张表之间的关联关系,并由数据库保证关联数据的完整性
  • 子表中的某个字段,引用父表中存在的数据
  • 外键也是数据库的一种约束

外键的主要作用​

保证引用完整性​

外键可以避免出现无效关联数据。

没有外键时,可能出现:

text
orders.user_id = 999

但是用户表中根本不存在用户 999 , 使用外键后,数据库会直接拒绝这种数据。

防止误删除父表数据​

  • 如果外键使用默认限制策略,数据库会拒绝删除
  • 比如删除某个表的数据,但是这条数据关联了其他表
    • 例如:删除了某个用户,通过用户id,但是这条用户id关联了某条订单,数据库就会拒绝删除,因为删除用户之后,订单就会失去关联对象

自动处理关联数据​

  • 外键可以配置级联行为
  • 删除用户时,自动删除该用户的全部订单:

外键配置​

  • 外键配置在子表中,用于引用父表的主键或唯一字段

外键配置组成​

  • constraint: 约束
    • 用于起外键约束名称
    • 外键约束名称可用于后续管理和维护
      • 删除外键,通过外键约束名称删除
      • 一个表有多个外键时用于区分
  • foreign: 外键
text
CONSTRAINT fk_orders_user -- 外键约束名称
FOREIGN KEY (user_id) -- 子表字段
REFERENCES users(id) -- 父表及被引用字段
ON DELETE RESTRICT -- 父记录删除时如何处理
ON UPDATE RESTRICT -- 父字段更新时如何处理

常见的删除策略

  • RESTRICT : 限制 (restrict)
  • CASCADE: 级联 (cascade)
配置含义
RESTRICT子表仍有引用时,禁止删除父记录
CASCADE删除父记录时,自动删除关联子记录
SET NULL删除父记录时,子表外键设为 NULL
NO ACTION通常与 RESTRICT 类似

外键配置例子​

  • 一个订单属于一个用户。
sql
CREATE TABLE users (
id BIGINT PRIMARY KEY,
name VARCHAR(100) NOT NULL
);

CREATE TABLE orders (
id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL,

CONSTRAINT fk_orders_user
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE RESTRICT
ON UPDATE RESTRICT
);

外键场景​

  • 关联的业务数据
    • 用户-订单数据
      • 订单必须要属于某个用户
    • 订单明细-订单
      • 订单明细必须输入某个订单
    • 员工-部门
      • 员工必须属于某个部门

外键和索引关系​

  • 父表被引用字段必须有索引
    • 通常父表引用的是主键
    • 用于在数据库需要快速确认子表引用的父记录是否真实存在
    • 如果没有索引,如果子表更新数据,父表存在很多条数据, 都要去查看父表的大量的记录去确认检查,性能比较差

外键优化​

  • 给外键字段建立索引
  • 使用稳定主键作为外键
    • 外键最好引用主键
    • 稳定的唯一键