在设计表的时候会遵守一些规则,这些规则称之为范式。在设计表时,遵守三大范式即可
1 第一范式(1NF)
第一范式是关系型数据库的一个最基本的要求,不满足第一范式就不可以称为关系型数据库。第一范式的要求就是:表里的字段不可再进行拆分,这就确保了数据表中每个字段的值都具有了原子性
创建一个学生表
正例:学号,姓名,年龄,班级名,学校名,学校地址,学校电话
虽然这样不符合数据库设计的规范,但是每一列都是不可再分的,因此满足第一范式
反例:学号,姓名,年龄,班级名,学校
由于学校可以再细分为学校名、学校地址、学校电话,因此这样设计表不满足第一范式
在定义每一个字段时,如果都可以用一个基本数据类型来表示,那么这个表就天然满足第一范式,上面的反例中的学校字段就不能用一个基本数据类型来表示,因此这个表就不满足第一范式
2. 第二范式(2NF)
第二范式的要求:在满足第一范式的基础上,不存在非关键字段对任意候选键的部分函数依赖,也就是说,数据表中的所有非关键字段,都必须完全依赖于主键,不能只依赖于主键中的一部分
注解:
- 非关键字段:可以理解为非主键字段
- 候选键:可以理解为主键、外键、没有主键时的唯一键
- 部分函数依赖:对于由两个(或多个关键字段)决定一条记录的情况,如果一行数据中有些字段只与关键字段中的一个(并不是全部关键字段)有关系,那么就说它只存在部分函数依赖
这也就是说,如果一个表中没有复合主键,那么这个表就天然满足第二范式
正例:
学生表:学号,姓名,年龄
课程表:课程编号,课程名,学分
学生选修课成绩表:学号,课程编号,成绩
学生表中的主键为学号,里面的其他字段都对这个主键存在依赖关系
课程表中的主键为课程编号,里面的其他字段都对这个主键存在依赖关系
成绩表的主键为学号和课程编号,成绩对这个复合主键中的两个字段都存在依赖关系,因为成绩取决于是哪个学生和选修了哪门课
反例:
学生选修课的成绩表:学号,学生姓名,年龄,课程名,学分,成绩
学生的相关信息可以通过学号来确定,学分可以通过课程来确定,成绩通过学生和课程共同确定,也就是说这个表可以用学生和课程作为复合主键来确定学生选修课的成绩
但是,学生的姓名、年龄和课程都没有关系,即学生的姓名、年龄只依赖于学号,不依赖于课程;学分与学生没有关系,即学分只依赖于课程,不依赖于学生
因此,这个表设计出来是不满足第二范式的
不满足第二范式可能出现的问题
a. 数据冗余
学生姓名、年龄、学分都重复出现,造成了大量的数据冗余
b. 更新异常
如果需要调整MySQL的学分,那么就需要去调整表中所有关于MySQL的记录,如果某些记录更新成功,而一些记录更新失败,就会造成数据表中,一门课程出现不同学分的情况
c. 插入异常
如果按照这样设计表,一个学生只有考完试才能取得成绩,也就是说,当考试前,成绩这一列是没有记录的,而学生成绩为空时的记录时,设计这个学生成绩表时没有意义的
d. 删除异常
当这些学生毕业时,可以考虑把学生信息和成绩记录删除,如果按照这样设计表,删除学生信息和成绩记录只能把整张表删除掉,这样也会把课程以及课程对应的学分也同样删除掉,导致数据库中没有课程和对应学分的信息
3. 第三范式(3NF)
第三范式的要求:在第二范式的基础上,不存在非关键字段,对任一候选键的传递依赖,也就是要求数据表中所有非关键字段不能依赖于其他非关键字段
,这就确保了数据表中每一个非关键字段都和主键字段直接相关
反例:
学生表:学号,姓名,年龄,所在学院,学院地址,学院电话
因为现在要描述的是学生,所以可以明显的判定出学号就是这个表的主键
在这个表设计中,姓名和年龄与学号是强相关的,也就是非关键字段与关键字段是直接相关的;所在学院也是与学号直接关联的;但学院地址和学院电话与所在学院是强相关的,也就是非关键字段与非关键字段存在相关联关系,这就不符合第三范式了
因为,学号 -> 所在学院 -> 学院的电话和学院的地址,也就是学院的电话和学院的地址并不是直接与主键学号直接关联的,而是通过所在学院进而与学号间接关联的,这也就是非关键字段对候选键的传递依赖
正例:
根据学生与学院的关系,拆分成两张表即可
学院表:学院编号,学院名,学院电话,学院地址
学生表:学号,姓名,年龄,所在学院编号
这样设计数据表,两张表中的非关键字段都只依赖于自己表中的主键,学生表可以通过外键与学院表建立关联关系