依赖关系:B = F(A)则A依赖于B
决定关系:B = F1(A)且A = F2(B)则A
关系型数据库
为什么叫关系型数据库,个人的理解是是每张表中的各个字段是有依赖关系的。
范式
数据库的设计范式是数据库设计所需要满足的规范,满足这些规范的数据库是简洁的、结构明晰的,同时不会发生插入(insert)、删除(delete)和更新(update)操作异常。反之则可能会给数据库的开发维护人员造成麻烦,而且可能存储了大量不需要的冗余信息。
1NF:属性具有原子性,不可再分
2NF:每个依赖都包含侯选关键字,即不存在部分依赖
3NF:每个依赖都是包含最小关键字的依赖,即不存在传递依赖
BCNF:要么不存在非关键字段,要么候选关键字段之间不会相互依赖
第一范式(1NF)
关键字:不存在复合字段
数据库表中的字段都是单一属性的,不可再分。这个单一属性由基本类型构成,包括整型、字符型、布尔型、日期型等。
例如,如下的数据库表是符合第一范式的:
第二范式(2NF)
关键字:不能有部分依赖
官方定义-所有非关键字段都完全依赖于任意一组候选关键字。
通俗理解-表结构为(a,b,c,d,e)中肯定有至少一个候选键,这个候选键只有一个字段那肯定符合第二范式。
如果是多个字段,比如是[a,b],那么剩下的每个字段c、d、e的值都必须要同时知道a,b两个值之后才能得到。
也就是说: c = f1(a,b)且d=f2(a,b)且e=f3(a,b)且c≠f4(a)且c≠f5(b)且d≠f6(a)且d≠f7(b)且e≠f8(a)且e≠f9(b)
相比于第一范式有哪些好处?
假设:A->B X->Y
那么:T(A,B,X,Y)这个满足第二范式,因为要想得到所有值,则至少得由A,X两个字段决定,所以(A,X)是候选键,但是A可以决定B这一个字段,X可以决定Y字段。
所以:改成T1(A,B,X) T2(X,Y)就可以满足第二范式了
比如:选课关系表为T(学号,姓名,年龄,课程名称,成绩,学分),关键字为组合关键字(学号,课程名称),这张表不满足第二范式
,存在如下决定关系:
(学号,课程名称) → (姓名,年龄,成绩,学分)
(课程名称) → (学分)
(学号) → (姓名,年龄)
由于不符合2NF,这个选课关系表会存在如下问题:
数据冗余-同一门课程由n个学生选修,”学分”就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。
更新异常-若调整了某门课程的学分,数据表中所有行的”学分”值都要更新,否则会出现同一门课程学分不同的情况。
插入异常-假设要开设一门新的课程,暂时还没有人选修。这样,由于还没有”学号”关键字,课程名称和学分也无法记录入数据库。
删除异常-假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。但是,与此同时,课程名称和学分信息也被删除了。
把选课关系表T改为如下三个表:
学生:T1(学号,姓名,年龄)
课程:T2(课程名称,学分)
选课关系:T3(学号,课程名称,成绩)
这样的数据库表是符合第二范式的,消除了数据冗余、更新异常、插入异常和删除异常。
另外,所有单关键字的数据库表都符合第二范式,因为不可能存在组合关键字
第三范式(3NF)
关键字:非关键字段不能对候选关键字段有传递依赖
在第二范式的基础上,数据表中如果不存在非关键字段对任一候选关键字段的传递函数依赖则符合第三范式。所谓传递函数依赖,指的是如果存在”A → B → C”的决定关系,则C传递函数依赖于A。因此,满足第三范式的数据库表应该不存在如下依赖关系:
关键字段→非关键字段x →非关键字段y
通俗理解-表结构为(a,b,c,d)中有至少一个候选键为a,那么b、c、d之间不可以有依赖关系
也就是说: b = f1(a)且c=f2(a)且d=f3(a)且b≠f4(c)且b≠f5(d)且c≠f6(b)且c≠f7(d)且d≠f8(b)且d≠f9(c)
假定学生关系表为T(学号,姓名,年龄,所属学院,学院地址,学院电话),关键字为单一关键字”学号”,因为存在如下决定关系:
(学号) → (姓名,年龄,所属学院,学院地址,学院电话)
这个数据库是符合2NF的,但是不符合3NF,因为存在如下决定关系:
(学号) → (所属学院) → (学院地址,学院电话)
即存在非关键字段”学院地址”、”学院电话”对关键字段”学号”的传递函数依赖。
它也会存在数据冗余、更新异常、插入异常和删除异常的情况。
把学生关系表分为如下两个表:
学生:(学号,姓名,年龄,所属学院);
学院:(学院,地址,电话)。
这样的数据库表是符合第三范式的,消除了数据冗余、更新异常、插入异常和删除异常。
BCNF
关键字:存在非关键字段,并且候选关键字段之前不能存在相互依赖的关系
通俗理解-表结构为(a,b,c,d)中有至少两个候选键为a、b那么a、b之间不可以有决定关系
也就是说: b = f1(a)且c=f2(a)且d=f3(a)且b≠f4(c)且b≠f5(d)且c≠f6(b)且c≠f7(d)且d≠f8(b)且d≠f9(c)
在第三范式的基础上,数据库表中如果不存在任何字段对任一候选关键字段的传递函数依赖则符合第三范式。
假设仓库管理关系表为T(仓库ID,存储物品ID,管理员ID,数量),且有一个管理员只在一个仓库工作;一个仓库可以存储多种物品。这个数据库表中存在如下决定关系:
(仓库ID,存储物品ID) →(管理员ID,数量)
(管理员ID,存储物品ID) → (仓库ID,数量)
所以,(仓库ID,存储物品ID)和(管理员ID,存储物品ID)都是候选关键字,表中的唯一非关键字段为数量,它是符合第三范式的。但是,由于存在如下决定关系:
(仓库ID) → (管理员ID)
(管理员ID) → (仓库ID)
即存在关键字段决定关键字段的情况,所以其不符合BC范式。它会出现如下异常情况:
(1)删除异常:
当仓库被清空后,所有”存储物品ID”和”数量”信息被删除的同时,”仓库ID”和”管理员ID”信息也被删除了。
(2)插入异常:
当仓库没有存储任何物品时,无法给仓库分配管理员。
(3)更新异常:
如果仓库换了管理员,则表中所有行的管理员ID都要修改。
把仓库管理关系表分解为二个关系表:
仓库管理:T1(仓库ID,管理员ID);
仓库:T2(仓库ID,存储物品ID,数量)。
这样的数据库表是符合BCNF范式的,消除了删除异常、插入异常和更新异常。
领取专属 10元无门槛券
私享最新 技术干货