1、多表关联关系的分类
既然数据库是存储项目中的数据的,项目中的数据主要是类型创建的对象,项目中类型和类型之间是有关系的,数据库中怎么体现出来?
不论是生活中,还是抽象出来的软件中,描述生活中的多个类型之间的关系,总结如下:
一对一关系一对多关系、多对一关系多对多关系
2、多表关联关系的实现
可以通过添加外键
来实现。
2.1 一对一
主键共享两张表的主键,建立外键约束。
-- 建立一对一关系:一夫一妻mysql> create table husband(-> hid int primary key auto_increment comment '丈夫编号',-> hname varchar(20) not null comment '丈夫姓名'-> );Query OK, 0 rows affected (0.03 sec)mysql> create table wife(-> wid int primary key auto_increment comment '妻子编号',-> wname varchar(20) not null comment '妻子姓名'-> ,foreign key(wid) references husband(hid)-> );Query OK, 0 rows affected (0.02 sec)-- 测试数据mysql> insert into husband(hname) values('邓超');Query OK, 1 row affected (0.01 sec)mysql> insert into husband(hname) values('张若昀');Query OK, 1 row affected (0.01 sec)mysql> insert into wife(wname) values('孙俪');Query OK, 1 row affected (0.01 sec)mysql> insert into wife(wname) values('唐艺昕');Query OK, 1 row affected (0.00 sec)mysql> insert into wife(wname) values('孙怡');ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`power`.`wife`, CONSTRAINT `wife_ibfk_1` FOREIGN KEY (`wid`) REFERENCES `husband` (`hid`))
外键唯一
子表添加一个新的字段并给该字段添加唯一约束和外键约束,然后关联父表主键字段。
-- 建立一对一关系:一夫一妻mysql> create table wife(-> wid int primary key auto_increment comment '妻子编号',-> wname varchar(20) not null comment '妻子姓名',-> w_hid int unique, -> foreign key (w_hid) references husband(hid));Query OK, 0 rows affected (0.03 sec)-- 测试数据:可以不按顺序插入,只要丈夫编号对应即可mysql> insert into wife(wname,w_hid) values('唐艺昕',2);Query OK, 1 row affected (0.01 sec)mysql> insert into wife(wname,w_hid) values('孙俪',1);Query OK, 1 row affected (0.01 sec)mysql> select * from wife;+-----+--------+-------+| wid | wname | w_hid |+-----+--------+-------+| 1 | 唐艺昕 |2 || 2 | 孙俪 |1 |+-----+--------+-------+2 rows in set (0.00 sec)
2.2 一对多
外键添加在多的一方,关联一的主键。-- 建立一对多关系:一个学生有多门课程mysql> create table stu(-> id int primary key auto_increment,-> sname varchar(20) not null);Query OK, 0 rows affected (0.02 sec)mysql> create table course(-> id int primary key auto_increment,-> cname varchar(50) not null,-> score int default 0,-> sid int,-> foreign key (sid) references stu(id)-> );Query OK, 0 rows affected (0.03 sec)-- 测试数据mysql> insert into stu (sname) values('zhangsan');Query OK, 1 row affected (0.01 sec)mysql> insert into course(cname,score,sid) values('math',98,1);Query OK, 1 row affected (0.00 sec)mysql> insert into course(cname,score,sid) values('chinese',99,1);Query OK, 1 row affected (0.01 sec)mysql> insert into course(cname,score,sid) values('english',111,1);Query OK, 1 row affected (0.01 sec)mysql> select * from course;+----+---------+-------+------+| id | cname | score | sid |+----+---------+-------+------+| 1 | math | 98 | 1 || 2 | chinese | 99 | 1 || 3 | english | 111 | 1 |+----+---------+-------+------+3 rows in set (0.00 sec)
2.3 多对多
外键:两张表的普通字段,直接建立关联关系(不推荐)中间表:创建一个中间表,中间表的两个普通字段分别关联另两张表的主键。-- 建立多对多关系:一个学生有多个老师,一个老师有多个学生-- 我这里之前已经创建过学生表mysql> desc stu;+-------+-------------+------+-----+---------+----------------+| Field | Type | Null | Key | Default | Extra|+-------+-------------+------+-----+---------+----------------+| id | int | NO | PRI | NULL | auto_increment || sname | varchar(20) | NO || NULL ||+-------+-------------+------+-----+---------+----------------+2 rows in set (0.01 sec)mysql> create table teacher(-> tid int primary key auto_increment,-> tname varchar(10));Query OK, 0 rows affected (0.03 sec)-- 中间表mysql> create table stu_tea(-> id int primary key auto_increment,-> sid int,-> tid int,-> foreign key(sid) references stu(sid),-> foreign key(tid) references teacher(tid));Query OK, 0 rows affected (0.02 sec)
总结
中小型项目中的数据表,为了避免垃圾数据的出现,强制添加外键约束项目规模和项目本身对于数据的安全性约束较少,容易产生垃圾数据大型项目并且对数据查询性能较高的数据表,约定的方式关联(不额外添加外键)
项目规模和项目本身对于数据安全性约束较多,不容易产生垃圾数据
不需要额外添加外键提高查询数据时的性能消耗
如果觉得《MySQL数据库之多表关联关系(一对一 一对多 多对多)》对你有帮助,请点赞、收藏,并留下你的观点哦!