在设计数据库的时候要满足数据库的范式
第一范式:每个字段都是最小的,不能再分
第二范式:在数据库字段中,不存在某个非关键字段对关键字段的部分依赖。
eg:
加入选课关系表如下:SelectCourse(学号,姓名,课程号,成绩,年龄,性别,学分)
我们可以看到,(学号,课程号)->(姓名,年龄,成绩,性别)
即存在部分依赖,所以这个不符合数据库的第二范式
由于不符合第二范式,所以就会产生数据冗余:
例如:
同一个学生选取不同的课程的时候,这个时候就会重复的插入该学生的性别,年龄。
不同的学生选同一种课时,学分这一项也会重复的插入数据库
更新异常:
同样也会产生更新异常,例如,当我们改变一个课程的学分的时候,我们就需要改变所有选这门课的学生的学分字段。如不修改就会产生更新异常
插入异常:
假设要开设一门新课程,但是没有人去选修,那么这时候就无法插入到数据库中
删除异常:
例如当一批人选修课程结束了,我们要从中删除它们的记录,那么如果我们删除了,明显就会造成插入异常
但是如果我们把该数据库表分解成三个,就很好的达标了。SelectCourse(学号,姓名,课程号,成绩,年龄,性别,学分)
Student(学号,姓名,年龄,性别)
Course(课程名称,学分)
SelectCourse(学号,课程名称,成绩)
这样我们就消除了部分依赖,符合了第二范式
第三范式:
第三范式就是在数据表中不存在传递依赖
什么叫传递依赖呢:关键字段->非关键字段x->非关键字段y
eg:
Student(学号,姓名,学生所在学院,学院电话)
由于关键字段只有一个“学号”
但是在这里我们知道
学号->学生所在学院->学院电话
所以存在传递依赖,故不符合第三范式
应修改为
Student(学号,姓名,所在学院)
College(学院,学院电话)
于是符合了第三范式
BCNF
在符合第三范式的基础上如果在数据库表中不存在关键字段对任一字段的依赖,那么就符合BCNF
eg:例如Storage(仓库ID,管理员ID,货物ID,数量)并且有一个仓库只有一个管理员,一个管理员只能在一个仓库当中
在这个表中,我们可以看到
(仓库ID,货物ID)->(管理员ID,数量)
(货物ID,管理员ID)->(仓库ID,数量)
由于只存在一个非关键字段“数量”没有传递依赖,所以符合第三范式
但是由于存在仓库ID->管理员ID,管理员ID->仓库ID所以存在关键字对关键字的依赖,所以不符合BCNF范式
应修改为
StorageHouse(仓库ID,管理员ID)
Storage(仓库ID,货物ID,数量)
//////
我们来逐步搞定一个论坛的数据库,有如下信息:
(1) 用户:用户名,email,主页,电话,联系地址
(2) 帖子:发帖标题,发帖内容,回复标题,回复内容
(用户名,email,主页,电话,联系地址,发帖ID,发帖标题,发帖内容,回复ID,回复标题,回复内容
)
(用户名,发帖ID,回复ID)为关键字段
用户名->(email,主页,电话,联系地址)
发帖ID->(发帖标题,发帖内容)
回复ID->(回复标题,回复内容)
寄存在部分依赖,不符合第二范式
用户(用户名,email,主页,电话,联系地址)
发帖(用户名,发帖ID,发帖标题,发帖内容)
回复(发帖ID,回帖ID,回复标题,回复内容)