数据表对应关系(一对一、一对多、多对多)
Ø 前言
本文主要介绍数据表的关联关系,这是数据库设计的常见问题之一。一个好的表结构设计,可以减少一些不必要的表或字段等。数据表之间的关联关系分为三种:一对一、一对多、多对多。下面就逐一介绍下:
- 一对一
Ø 一对一是将数据表“垂直切分”,其实是不常见,或不常用的。也就是 A 表的一条记录对应 B 表的一条记录,为什么要这样的设计呢,不是增加了程度的复杂性吗,然而并不一定,举例说明:
-
一个系统必然有 Employee(员工表)(包含字段:EmployeeId、姓名、性别、年龄、电话、地址等),每个员工都为一个用户,所以还有张 User 表(包含字段:UserId(关联 EmployeeId)、用户名、密码、角色等),这样你会发现,整合为一张表是否不太妥当?因为,User 的记录只会在登录时用到,感觉有点违背三大范式中的“确保每列都和主键列直接关联,而不是间接关联”。
-
还有种情况,这就要根据具体的业务来决定了。如果,当一张表的字段过于太多,而很多字段可能只有在某些情况下,才会使用到,这时也可以考虑使用一对一设计。
Ø 优点
-
便于管理、可提高一定的查询速度
-
减轻 CPU 的 IO 读写,提高存取效率。
-
符合数据库设计的三大范式。
-
符合关系性数据库的特性。
Ø 缺点
-
增加一定的复杂程度,程序中的读写难度加大。
-
一对多
Ø 一对多,是最常见的一种设计。就是 A 表的一条记录,对应 B 表的多条记录,且 A 的主键作为 B 表的外键。这主要看以哪张表为中心,以上示例以 A 表为中心,就是一对多,如果以 B 表为中心,则是多对一。举几个例子:
-
班级表 与 学生表,一个班级对应多个学生,或者多个学生对应一个班级。
-
角色表 与 用户表,一个角色对应多个用户,或者多个用户对应一个角色。
-
商品表 与 图片表,一个商品对应多张图片,或者多张图片对应一个商品。
-
多对多
Ø 多对多,在数据库中也比较常见,可以理解为是一对多和多对一的组合。要实现多对多,一般都需要有一张中间表(也叫关联表),将两张表进行关联,形成多对多的形式。例如:
- 老师表、班级表、科目表,中间表为:课程表
- SQL:
–教师表
mysql> CREATE TABLE Teacher(TeacherId int, Name varchar(20));
Query OK, 0 rows affected (0.45 sec)
mysql> insert into teacher values(1,‘张老师’),(2,‘王老师’);
Query OK, 2 rows affected (0.14 sec)
Records: 2 Duplicates: 0 Warnings: 0
–班级表
mysql> create table class(chassId int,Name varchar(20));
Query OK, 0 rows affected (0.33 sec)
mysql> insert into class values(1,‘一班’),(2,‘二班’);
Query OK, 2 rows affected (0.13 sec)
Records: 2 Duplicates: 0 Warnings: 0
–课程表(关联表)
CREATE TABLE #Courses(CoursesId int IDENTITY(1, 1), TeacherId int, ClassId int, Name nvarchar(20));
INSERT INTO #Courses VALUES(1, 1, ‘语文’), (1, 2, ‘语文’);
INSERT INTO #Courses VALUES(2, 1, ‘数学’), (2, 2, ‘英语’);
mysql> SELECT Courses.TeacherId , teacher.Name, courses.ClassId, class.Name, cou
rses.Name FROM Courses,Teacher, Class
-> WHERE Courses.TeacherId=Teacher.TeacherId;
±----------±-------±--------±-----±-----+
| TeacherId | Name | ClassId | Name | Name |
±----------±-------±--------±-----±-----+
| 1 | 张老师 | 1 | 一班 | 语文 |
| 1 | 张老师 | 2 | 一班 | 语文 |
| 2 | 王老师 | 1 | 一班 | 数学 |
| 2 | 王老师 | 2 | 一班 | 英语 |
| 1 | 张老师 | 1 | 二班 | 语文 |
| 1 | 张老师 | 2 | 二班 | 语文 |
| 2 | 王老师 | 1 | 二班 | 数学 |
| 2 | 王老师 | 2 | 二班 | 英语 |
±----------±-------±--------±-----±-----+
8 rows in set (0.00 sec)
或者:
mysql> SELECT Courses.TeacherId , teacher.Name, courses.ClassId, class.Name, cou
rses.Name FROM Courses,Teacher, Class WHERE Courses.TeacherId=Teacher.TeacherId
and courses.classId=Class.ClassId;
±----------±-------±--------±-----±-----+
| TeacherId | Name | ClassId | Name | Name |
±----------±-------±--------±-----±-----+
| 1 | 张老师 | 1 | 一班 | 语文 |
| 2 | 王老师 | 1 | 一班 | 数学 |
| 1 | 张老师 | 2 | 二班 | 语文 |
| 2 | 王老师 | 2 | 二班 | 英语 |
±----------±-------±--------±-----±-----+
4 rows in set (0.01 sec)
如图片:
参考:https://www.cnblogs.com/abeam/p/7406285.html