在设计数据库的时候切记遵守范式规则,才能更好的解决数据冗余,数据有效性检查,提高存储效率。
第一范式
属性不可分
错误示例
正确示例
第二范式
每个非主属性完全函数依赖于键码。
什么是依赖
A->B 表示 A 函数决定 B,也可以说 B 函数依赖于 A。
如果 {A1,A2,… ,An} 是关系的一个或多个属性的集合,该集合函数决定了关系的其它所有属性并且是最小的,那么该集合就称为键码。
对于 A->B,如果能找到 A 的真子集 A’,使得 A’-> B,那么 A->B 就是部分函数依赖,否则就是完全函数依赖。
对于 A->B,B->C,则 A->C 是一个传递函数依赖。
下图满足第一范式但不满足第二范式
从上图可以看出
这里的键码是{Sno,Cname}
Sname和Sdept都是依赖于Sno的,即Sno可以推出Sname和Sdept(部分依赖)
Grade是依赖于Sno和Cname的(完全依赖)
Mname是依赖于Sdept的,也能推出Mname部分依赖于Sno
所以不满足第二范式
不满足第二范式带来的问题:
当新增一条数据的时候,Grade不会有冗杂数据,而Sname,Sdept,Mname都会多次重复出现,造成大量冗杂数据。
删除一条数据,会将这条数据中的其他信息删除。
修改一条数据中的其中一个信息的时候,还需要修改与这个信息相关的信息。比如修改了Sdept之后,Mname也需要被修改。
通过分解来达到第二范式的要求
分解之后键码分别是{Sno}和{Sno,Cname}
Sno->Sname,Sdept
Sdept->Mname
Sno,Cname->Grade
第三范式
非主属性不传递函数依赖于键码。
在第二范式的基础上,我们可以看到,出现了传递函数依赖Sno->Sdept->Mname
再次进行分解消除传递函数依赖