Foreign Key
概述
- 外键约束用于在两个表之间建立参照完整性(
Referential Integrity
),确保数据的一致性和完整性 - 外键是一个表中的列或一组列,其值必须匹配另一个表中主键或唯一键的值
- 通过外键,可以在不同表之间建立关系,从而维护数据库的逻辑结构
- 按个数分类
- 单一外键(给一个字段添加外键约束)
- 复合外键(给多个字段联合添加一个外键)
- 外键约束,外键字段,外键值
- 给某个字段添加外键约束后,它就变成了外键字段,外键字段出现的每一个数据都被称为外键值
- 外键字段可以为空,外键为空的数据叫孤儿数据
- 被引用的字段必须具有
unique
约束 - 有了外键引用之后,表分为父表和子表。创建表时应该先创建父表,再创建子表;插入数据时应该父表数据再插入子表数据
- 一对多的关系,多的一方添加外键,可以减少数据冗余
特点
- 确保外键列的值必须存在于被引用表的主键或唯一键列中
- 外键通常用于表示多对一(
Many-to-One
)关系- 例如,订单项表的每一行都引用订单表中的一个订单
- 级联操作:
- 级联删除(
CASCADE DELETE
):当被引用表中的一行被删除时,自动删除引用该行的所有行 - 级联更新(
CASCADE UPDATE
):当被引用表中的一行被更新时,自动更新引用该行的所有行
- 级联删除(
- 可以显式为外键约束命名,便于引用和管理
语法
1 2 3 4 5 6 |
CREATE TABLE table_name ( column1 datatype, column2 datatype, ... FOREIGN KEY (column1) REFERENCES other_table (other_column) ); |
- 创建表时添加
1 2 3 4 5 6 7 8 9 10 11 |
CREATE TABLE departments ( dept_id INT PRIMARY KEY, dept_name VARCHAR(255) NOT NULL ); CREATE TABLE employees ( emp_id INT PRIMARY KEY, emp_name VARCHAR(255) NOT NULL, dept_id INT, FOREIGN KEY (dept_id) REFERENCES departments(dept_id) ); |
- 创建表后添加
1 2 |
ALTER TABLE table_name ADD CONSTRAINT constraint_name FOREIGN KEY (column1) REFERENCES other_table (other_column); |
1 2 |
ALTER TABLE employees ADD CONSTRAINT fk_dept_id FOREIGN KEY (dept_id) REFERENCES departments(dept_id); |
优缺点
- 优点
- 数据完整性:确保引用关系的有效性,防止孤立记录
- 维护参照完整性:通过级联操作自动维护表之间的关系
- 逻辑结构清晰:明确表之间的关系,便于理解数据库结构
- 缺点
- 性能开销:在插入、更新和删除操作时,外键检查和级联操作可能会带来额外的性能开销
- 复杂性增加:设计和维护外键约束需要仔细考虑,尤其在复杂的数据库结构中
级联操作
- 级联删除
- 当被引用表中的记录被删除时,自动删除引用该记录的所有记录
1 2 3 4 5 6 |
CREATE TABLE employees ( emp_id INT PRIMARY KEY, emp_name VARCHAR(255) NOT NULL, dept_id INT, FOREIGN KEY (dept_id) REFERENCES departments(dept_id) ON DELETE CASCADE ); |
- 级联更新
- 当被引用表中的记录被更新时,自动更新引用该记录的所有记录
1 2 3 4 5 6 |
CREATE TABLE employees ( emp_id INT PRIMARY KEY, emp_name VARCHAR(255) NOT NULL, dept_id INT, FOREIGN KEY (dept_id) REFERENCES departments(dept_id) ON UPDATE CASCADE ); |
外键约束的删除
1 2 |
ALTER TABLE table_name DROP FOREIGN KEY constraint_name; |
1 2 |
ALTER TABLE employees DROP FOREIGN KEY fk_dept_id; |
示例
- 创建部门表
1 2 3 4 |
CREATE TABLE departments ( dept_id INT PRIMARY KEY, dept_name VARCHAR(255) NOT NULL ); |
- 创建员工表并添加外键
1 2 3 4 5 6 |
CREATE TABLE employees ( emp_id INT PRIMARY KEY, emp_name VARCHAR(255) NOT NULL, dept_id INT, FOREIGN KEY (dept_id) REFERENCES departments(dept_id) ON DELETE CASCADE ON UPDATE CASCADE ); |
- 插入数据
1 2 3 4 5 |
-- 插入部门数据 INSERT INTO departments (dept_id, dept_name) VALUES (1, 'HR'), (2, 'Engineering'); -- 插入员工数据 INSERT INTO employees (emp_id, emp_name, dept_id) VALUES (1, 'Alice', 1), (2, 'Bob', 2); |
- 删除被引用的记录
1 2 |
-- 删除部门ID为1的记录,自动删除所有引用该部门的员工记录 DELETE FROM departments WHERE dept_id = 1; |
问题
- 关于外键的选择?
- 表
B
可以使用表A
的主键或唯一键作为外键 - 也就是说,表
B
中外键引用的列可以是表A
中的主键(PRIMARY KEY
)或具有唯一约束(UNIQUE
)的列
- 表
- 当表
A
中删除了某一项数据后,表B
也会删除关联数据?- 当表
A
中删除了某一项数据后,表B
是否也会删除关联数据,取决于外键约束中设置的级联删除(ON DELETE CASCADE
)规则
- 当表
- 表
B
删除了某些数据后,不会影响到表A
吧?- 当表
B
删除某些数据后,通常不会影响到表A
- 外键约束主要用于维护参照完整性,确保表
B
中的数据在表A
中有对应的记录
但它不会反向操作,即删除表B
中的记录不会影响表A
中的数据
- 当表
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ 数据库设计三范式简介10/28
- ♥ 表操作_查询-结果去重10/24
- ♥ union && limit10/26
- ♥ 表操作_数据排序10/23
- ♥ 事务_介绍 && 事务隔离11/01
- ♥ 表操作_查询-分组 || 分组筛选10/24