目录
前言
认识外键
外键的特点
外键的设计方式
多对多
组合主键
一对多/多对一
一对一
外键和外键约束的关系
外键的使用
添加约束
在建表时添加外键约束
如果已经创建表了,那我们可以修改表的方式给表添加外键约束:
应用实例
删除约束
删除/更新行为
含义
我们就称为删除/更新行为。具体的删除/更新行为有以下几种:
语法
理解
前言
本篇博客旨在帮助大家理解:外键的含义和外键的具体应用
认识外键
在现实生活中,一个公司有很多部门,一个部门又有很多职员。如果我们从学习数据库的知识来描述这种关系,我们是不是要创建两张表: 1 部门表 dept 2 员工表 emp。
部门表 dept有 部门id ,名字,类型 等字段 ,员工表 emp 有 员工id , 员工名字,工作,年龄,薪资 等字段
现在有个问题了,应该怎么描述他们之间的关系呢?-一个部门有多个员工
就需要在员工表在添加一个字段dept_id,表示该员工所在的部门id
在这里,认为添加的员工表的dept_id 字段 ,描述了员工表和部门表关系。是在一个emp表中引用dept表的主键,以建立两个表之间的关系。称为外键【指向部门表的主键】
外键的特点
- 如果两张表存在关联关系如:员工表 emp表和部门表dept 表 。
- 员工表的外键dept_id 是相对于部门表 dept 来说的,并且外键的对应的是dept表的主键
外键的设计方式
- 多对多
- 一对多/多对一
- 一对一
多对多
应用场景
在学校一个老师教多个学生,一个学生需要学习多门课:tb_teacher表和tb_stu表。
思路
这种情况需要中间表来处理多对多的关系
设计中间表 tb_teacher_stu表 其中新建的表中会有两个外键,一个相对于tb_teacher 表的外键;另一个相对于tb_stu表的外键。
注意:这两个外键都是对应另一方的主键
组合主键
含义
组合主键(Composite Primary Key),也称为复合主键,是指由两个或多个列共同组成的主键。这些列的组合值必须唯一地标识表中的每一条记录。
应用场景
员工表employee 和职务表 job 一个员工可以有多个职业,一个职业也存在多个员工。这就是多对多的关系。在上面提到 多对多的关系,我们需要建立中间表。那么一个表都应该有一个主键
但这时候,我们就发现,你加在任何一个字段都不合适。只有两个字段都添加才可以,这里就是用了组合主键
特点
只有两个都相等时,才违背主键约束,如果只是任何一个相等,并不会违背主键约束
创建中间表代码如下
create table tb_employee_job(eid int,job_id int , # 使用组合主键primary key (eid,job_id))
一对多/多对一
应用场景
订单和顾客 : Orders 表(订单表)和 Customers 表(客户表)
思路
一个客户有多个订单,,但一个订单只有一个客户在这里 : Orders 表(订单表)为子表
Customers 表(客户表)为父表
外键在“多”的一方:
- 在一对多关系中,外键位于“多”的表中,即子表。这个外键指向“一”的表(父表)的主键。
- 例如,在Orders 表和Customers 表的关系中,如果一个顾客Customers 表可以拥有多份订单 ,那么外键应该在Orders 表中,指向Customers 表的主键。
外键不在“一”的一方:
- 外键不会出现在“一”的表中,即父表。父表只有主键,没有外键。
- 继续上面的例子,Customers 表不会有指向Orders 表的外键,因为Customers 表是“一”的一方。
一对一
应用场景
身份证和人的关系:Card 表(身份证表) 和 Person 表(个人表)
思路
一个人只有一张身份证,一个身份证,同时也只对应一个人
外键在任意一方都可以。在Card 表 指向Person 表的主键;在Person 表 表示指向Card 表 的主键
外键和外键约束的关系
外键约束,既是外键的一种保护措施为了防止恶意删除数据,又是确保数据库中数据的引用完整性和一致性。
外键的使用
添加约束
在建表时添加外键约束
语法
CREATE TABLE 表名 (字段名 数据类型,...[ CONSTRAINT ] [ 外键名称 ] FOREIGN KEY (外键字段名) REFERENCES 主表 (主表列名) );
如果已经创建表了,那我们可以修改表的方式给表添加外键约束:
语法
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表 (主表列名) ;
应用实例
部门表dept 表 员工表 emp表 ,删除部门表id=1 的部门信息
// 创建部门表dept CREATE TABLE dept (id INT AUTO_INCREMENT COMMENT 'ID' PRIMARY KEY,NAME VARCHAR (50) NOT NULL COMMENT '部门名称' ) COMMENT '部门表' ; // 插入数据 INSERT INTO dept (id, NAME) VALUES(1, '研发部'),(2, '市场部'),(3, '财务部'),(4, '销售部'),(5, '总经办'); //创建员工表 CREATE TABLE emp (id INT AUTO_INCREMENT COMMENT 'ID' PRIMARY KEY,NAME VARCHAR (50) NOT NULL COMMENT '姓名',age INT COMMENT '年龄',job VARCHAR (20) COMMENT '职位',salary INT COMMENT '薪资',entrydate DATE COMMENT '入职时间',managerid INT COMMENT '直属领导ID',dept_id INT COMMENT '部门ID' ) COMMENT '员工表' ; // 插入数据 INSERT INTO emp VALUES(1, '金庸',66,'总裁',20000,'2000-01-01',NULL,5),(2,'张无忌',20,'项目经理',12500,'2005-12-05', 1,1),(3,'杨逍',33,'开发',8400,'2000-11-03',2,1),(4,'韦一笑',48,'开发',11000,'2002-02-05',2,1),(5, '常遇春',43,'开发',10500,'2004-09-07',3,1),(6,'小昭',19,'程序员鼓励师',6600,'2004-10-12',2,1) ; //在员工表emp表中,添加外键 alter table emp add foreign key (dept_id) references dept(id); // 删除部门表 id=1 的部门信息 delete from dept where id=1;
运行结果
报错的原因:外键约束阻止了,你删除部门表id =1 的信息,并且与它相关联的员工表的信息
删除约束
语法
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
删除/更新行为
含义
添加了外键之后,再删除父表数据时产生的约束行为,我们就称为删除/更新行为。
在数据库中,我们默认 NO ACTION/RESTRICT
我们就称为删除/更新行为。具体的删除/更新行为有以下几种:
行为 | 说明 |
---|---|
NO ACTION | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。 (与 RESTRICT 一致) 默认行为 |
RESTRICT | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。 (与 NO ACTION 一致) 默认行为 |
CASCADE | 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录。 |
SET NULL | 当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(这就要求该外键允许取null) |
SET DEFAULT | 父表有变更时,子表将外键列设置成一个默认的值 (Innodb不支持) |
语法
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 主表名 (主表字段名) ON UPDATE CASCADE ON DELETE CASCADE;
理解
在上面我说了数据库中,默认使用 NO ACTION/RESTRICT
NO ACTION/RESTRICT 理解
如果在父表中删除数据,判断在子表是否有对应的外键(删除的数据,是否在子表中有关联的),如果有则不允许删除、更新
CASCADE 理解
和 NO ACTION/RESTRICT 刚好相反。你在父表中删除的数据,判断外键所在的表是否有与之关联的数据,如果有则删除,更新