MySQL数据库之多表关联关系(一对一、一对多、多对多)

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)

总结

  • 中小型项目中的数据表,为了避免垃圾数据的出现,强制添加外键约束
    项目规模和项目本身对于数据的安全性约束较少,容易产生垃圾数据
  • 大型项目并且对数据查询性能较高的数据表,约定的方式关联(不额外添加外键)
    项目规模和项目本身对于数据安全性约束较多,不容易产生垃圾数据
    不需要额外添加外键提高查询数据时的性能消耗
    原文作者:乐温
    原文地址: https://blog.csdn.net/zhengrong9/article/details/114526113
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞