学的时候就知道是一堆公式。
实际中在设计表的时候可能会用到。
前提是关系型数据库,比如mysql。
(实际中oracle比mysql更好用。但是他收费啊。)
第一范式:每个属性都是原子的(需要做到每个属性都是不可分割的。)
如上。建表的话,还需要把联系方式分成三列去保存,保证每个属性都是原子的。
不满足第一范式,mysql都无法建表。所以第一范式不需要太多关注。
第二范式:满足第一范式基础上,非主属性必须完全依赖于主属性。即主键的整体才能确定一个非主属性。
非主属性是指不构成主键的那些列。
跟着我的思路来,
假设我设计的 管理学生信息表结构如下,
(学号,课程号,成绩,姓名, 老师,老师职称)。主键加粗。
分析一下
-
成绩是完全依赖于主属性(即学号+课程号,可以确定一个人一门课的成绩)
-
姓名可以直接通过学号来确定,不用课程号就行了。不满足非主属性必须完全依赖于主属性。
不满足第二范式了有啥坏处呢?
新生入学了。你会发现无法新增内容。因为学生还没有选课,自然没有课程号。
我们按照第二范式,消除非主属性部分依赖主属性的情况。就把姓名提出来,新建一张表。两张表如下
1.选课表(学号,课程号,成绩, 老师,老师职称)
2.学生表(学号,姓名)。
学生表就一个主属性,天然满足第二范式。
第三范式:满足第二范式基础上,且消除对主属性的传递依赖。
选课表中,能决定教师职称并不是通过学号+课程号来确定的,而是先确定了老师才知道教师职称。
我们称教师职称是传递依赖于(学号,课程号)。
有什么坏处呢?
1.老师职称改变了,要修改很多条数据
2.新来老师还没有定教哪门课,教师职称不知该保存到什么地方。(插入异常)
按照第三范式,消除传递依赖的非主属性。最终得到表结构如下
选课表(学号,课程号,成绩,教师)
教师表(教师,教师职称)
学生表(学号,姓名)
BCNF:第三范式基础上,
BCNF与第三范式的不同之处在于:第三范式中不允许非主属性被另一个非主属性决定,但第三范式允许主属性被非主属性决定;而在BCNF中,任何属性(包括非主属性和主属性)都不能被非主属性所决定。
实际上,我们存表,一般都是用id做主键。假如这样设计表:
选课表(学号,课程号,成绩,教师,id)满足第三范式,却不满足BCNF。
因为id可以决定非主属性和主属性了。
所以直接把id作为主属性就满足BCNF了。