SQL示例:外键约束是关系型数据库中用于建立两个表之间链接的一种规则

本文介绍了在SQL中创建外键约束的方法,以audit表的EMP_no字段关联employees_test表的主键ID为例。


通过ALTER TABLE语句添加外键约束,确保audit表中的每个EMP_no值都存在于employees_test表的ID中。


文章解释了外键约束的作用是维护数据一致性,防止插入无效数据或误删被引用数据,并区分了外键约束与连表查询的不同用途。


外键约束是数据写入时的保护机制,而非查询的前提条件,适用于需要严格数据完整性的场景,但对性能要求高的场景可能不适用。


SQL示例

题目描述

在audit表上创建外键约束,其emp_no对应employees_test表的主键id。

(以下2个表已经创建了)

复制代码
CREATE TABLE employees_test(
ID INT PRIMARY KEY NOT NULL,
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);

CREATE TABLE audit(
EMP_no INT NOT NULL,
create_date datetime NOT NULL
);

后台会判断是否创建外键约束,创建输出1,没创建输出0

解法

可以使用 ALTER TABLE 语句添加外键约束:

sql 复制代码
ALTER TABLE audit 
ADD CONSTRAINT fk_audit_emp_no 
FOREIGN KEY (EMP_no) REFERENCES employees_test(ID);

如果只需要最简形式(系统自动生成约束名)

sql 复制代码
ALTER TABLE audit 
ADD FOREIGN KEY (EMP_no) REFERENCES employees_test(ID);

注意事项:

  1. 外键约束要求 employees_test 表中的 ID 字段必须是主键(已满足)

  2. 要求 audit 表中的 EMP_no 字段类型与 employees_test 表的 ID 字段类型兼容(都是整型,已满足)


外键约束 是关系型数据库中用于建立两个表之间链接的一种规则


它确保一个表中的数据与另一个表中的数据保持一致性和完整性。


通俗理解

可以把外键理解为一种"引用"关系。例如:

  • 主表 (被引用的表):employees_test(员工表),ID 是主键

  • 从表 (引用别人的表):audit(审计表),EMP_no 是外键


外键约束的意思是:audit 表中的 EMP_no 字段的每一个值 ,都必须在 employees_test 表的 ID 字段中存在


具体作用

1. 保证数据一致性

sql

复制代码
-- 如果 employees_test 表中没有 ID=999 的员工
INSERT INTO audit (EMP_no, create_date) VALUES (999, NOW());
-- 外键约束会阻止这条插入,因为 999 不存在于主表中

2. 防止删除被引用的数据

sql

复制代码
-- 如果 audit 表中还有某个 EMP_no 的记录
DELETE FROM employees_test WHERE ID = 10001;
-- 外键约束会阻止删除(除非设置了级联删除)

三种常见行为

行为 说明
RESTRICT 有引用时禁止删除/更新主表记录
CASCADE 主表删除/更新时,从表同步删除/更新
SET NULL 主表删除/更新时,从表外键设为 NULL

你题目中的例子

sql

复制代码
ALTER TABLE audit 
ADD FOREIGN KEY (EMP_no) REFERENCES employees_test(ID);

这条语句的含义:

  • audit 表中的每条记录,都必须对应一个真实存在的员工

  • 不能为不存在的员工创建审计记录

  • 不能随意删除还在审计表中留有记录的员工信息

简单记忆:外键就像是"查字典"------写进去的词,必须在字典里已经存在。


外键约束怎么用,是连表查询的时候用吗


需要澄清一个常见的误区:外键约束和连表查询是两件完全不同的事情

核心区别

外键约束 连表查询 (JOIN)
作用 保证数据完整性 从多个表获取数据
使用时 插入/更新/删除数据时自动生效 查询数据时手动写SQL
是否必须 可选,不是查询的前提 需要时就用
关系 约束规则 查询技巧

外键约束的真正用途

外键约束是写数据时的保护机制,和查询无关:

sql

复制代码
-- 1. 创建外键约束(建表时或后添加)
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    FOREIGN KEY (customer_id) REFERENCES customers(id)
);

-- 2. 约束会在插入时自动检查
INSERT INTO orders (customer_id) VALUES (999);  -- ❌ 如果 customers 表没有 id=999,会被拒绝

-- 3. 约束会在删除时自动检查
DELETE FROM customers WHERE id = 1;  -- ❌ 如果 orders 表还有该客户的订单,会被拒绝

连表查询不需要外键约束

即使没有外键约束,也能正常连表查询:

sql

复制代码
-- 没有外键约束,照样可以 JOIN
SELECT * FROM audit a
JOIN employees_test e ON a.EMP_no = e.ID;

外键约束不是连表查询的前提条件,只要两个表有逻辑关联的字段(哪怕没有约束),就可以 JOIN。

什么时候用外键约束?

sql

复制代码
-- ✅ 推荐使用外键约束的场景
-- 1. 订单系统的订单表引用用户表(不能有不存在的用户下单)
-- 2. 评论表的文章ID引用文章表(不能有不存在的文章的评论)
-- 3. 银行转账记录引用账户表(不能有无效账户的交易)

-- ❌ 可以不用的场景
-- 1. 日志表(偶尔数据不一致影响不大)
-- 2. 数据仓库/大数据场景(约束影响插入性能)
-- 3. 分库分表的系统(跨库无法建外键)

总结

你想做什么 需要外键约束吗?
查询两个表的数据 ❌ 不需要,直接用 JOIN
确保插入的数据是有效的 ✅ 需要,外键自动帮您检查
防止误删被引用的数据 ✅ 需要,外键会阻止或级联
提高查询性能 ❌ 不会,用索引来提速

一句话记住:外键约束是"守门员"(保护数据质量),不是"导航员"(查询数据不需要它)。

相关推荐
zshs0002 小时前
从 Raft 到 MySQL:我是怎么推导出半同步复制原理的
数据库·分布式·mysql
这个DBA有点耶2 小时前
MySQL深分页优化:从LIMIT 1000000,10到毫秒级响应的三种写法
数据库·程序人生·mysql·性能优化·学习方法·dba·改行学it
东风破1372 小时前
DM8搭建同构(dm-dm)及异构数据库(dm-oracle,dm-mysql)的dblink
数据库·mysql·oracle
青云计划2 小时前
Mysql
数据库·mysql
海棠Flower未眠3 小时前
Spring Boot 3 + JPA多模块系统对MySQL和DORIS进行多数据源集成实战(荣耀典藏版)
spring boot·后端·mysql
ClouGence3 小时前
我们做了个疯狂的决定,把 CloudDM 全部开源了
数据库·后端·mysql
努力努力再努力wz3 小时前
【Qt入门系列】深入理解信号与槽:从事件响应到自定义信号机制
c语言·开发语言·数据结构·数据库·c++·qt·mysql
Java成神之路-3 小时前
解密 MySQL 索引性能:为什么主键必须有序?
mysql
未若君雅裁3 小时前
MySQL索引原理-InnoDB-B+树结构与查询过程
b树·mysql