文章目录
- 数据库设计
- 1. 实体
- 2. 关系
- 2.1 一对一关系
- 2.2 一对多关系
- 2.3 多对多关系
数据库面试中经常被问到某项目中的数据库如何设计的?
实际上并不是让你回答设计的过程,而是注重考察表的结构。回答该项目具体有几张表,每个表是做什么的,每张表中有哪些列,分别都是什么类型,代表了什么含义,有什么约束等等。这节我们详细讲一下数据库的设计问题。
数据库设计
我们采用一个案例来进行说明。假设现在需要设计一个教务系统来管理里很多的学生和班级。
1. 实体
实体:需求场景中的核心概念 / 重要名词。
对于教务系统来说,实体包含学生和班级。
2. 关系
关系:指的是实体与实体之间的关系。分别是一对一关系,一对多关系以及多对多关系。
Q:如何区分实体实体之间的关系?
A:造句。比如:
一对一关系:一个用户从属于一个学生,一个学生也只能拥有一个用户号。
一对多关系:一个学生从属于一个班级,但一个班级可以包含多个学生。
多对多关系:一个学生可以选多门课程,一个课程也可以被多名学生来选。
2.1 一对一关系
一对一关系是最简单的,可以采取以下几种方法来实现:
- 直接把两个实体数据放在一张表中即可,即用户表和学生表拼成一个大表;
- 在用户表中带有一个“学生id”字段,通过学生id字段的值和学生表关联起来;
- 在学生表中带有一个“用户id”字段,通过用户id字段的值和用户表关联起来;
2.2 一对多关系
对于一对多关系来讲,也有多种做法来关联数据:
- 给班级表中加一个字段students_id,students_id字段包含若干学生的id;
class[表名] | classId | className | students_id |
---|---|---|---|
1 | 高三一班 | 1,2,3,4,5 | |
2 | 高三二班 | 6,7,8,9,10 | |
… | … | … |
student[表名] | studentId | studentName |
---|---|---|
1 | 张三 | |
2 | 李四 | |
… | … |
此时根据班级表中的studentId这一列,就可以查询到当前班级包含了哪些学生。但是这种做法,对于MySQL这样的关系型数据库来说,不是很合适。
我们仔细看一下班级表中的studens_id字段,这一个字段需要表示多个值,显然数组是可以实现,但是MySQL里没有数组这样的数据类型哎,这就很麻烦了,所以我们看第二种方法。
- 给学生表中加一个字段record,表示该学生所从属的班级;
class[表名] | classId | className |
---|---|---|
1 | 高三一班 | |
2 | 高三二班 | |
… | … |
student[表名] | studentId | studentName | classId |
---|---|---|---|
1 | 张三 | 1 | |
2 | 李四 | 1 | |
… | … | … |
此时,我们可以根据学生表中的classId这一列,查询某个学生从属于哪个班级。这种做法更加简单高效。
2.3 多对多关系
对于多对多的关系,往往需要使用一个中间表来表示。
student[表名] | studentId | studentName |
---|---|---|
1 | 张三 | |
2 | 李四 | |
… | … |
course[表名] | courseId | courseName |
---|---|---|
1 | 语文 | |
2 | 数学 | |
… | … |
如果想要实现 [张三选择语文数学,李四选择数学] 这样的关系,仅仅靠学生表和课程表是无法实现的。此时需要引入一个中间表sutdent-course。
srudent-course[表名] | studentId | courseId |
---|---|---|
1 | 1 | |
1 | 2 | |
2 | 2 | |
… | … |
这张表第一行表示学号为1的学生选了课程号为1的课程,而学号和课程号又可以分别在学生表和课程表中查询,由此就实现了多对多的关系。