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语句添加外键约束:
ALTER TABLE audit ADD CONSTRAINT fk_audit_emp_no FOREIGN KEY (EMP_no) REFERENCES employees_test(ID);如果只需要最简形式(系统自动生成约束名)
ALTER TABLE audit ADD FOREIGN KEY (EMP_no) REFERENCES employees_test(ID);注意事项:
外键约束要求
employees_test表中的ID字段必须是主键(已满足)要求
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 |
| 确保插入的数据是有效的 | ✅ 需要,外键自动帮您检查 |
| 防止误删被引用的数据 | ✅ 需要,外键会阻止或级联 |
| 提高查询性能 | ❌ 不会,用索引来提速 |
一句话记住:外键约束是"守门员"(保护数据质量),不是"导航员"(查询数据不需要它)。
