详解数据库范式:第一范式到第五范式
2011-08-16 10:43阅读:
转自:
缘来聚散
--------------------------------------------------------------------
1NF:一个table中的列是不可再分的(即列的原子性)
2NF:一个table中的行是可以唯一标示的,(即table中的行是不可以有重复的)
3NF:一个table中列不依赖以另一个table中的非主键的列,还是不通俗!巨寒!!
举个例子吧:有一个部门的table,我们叫它tbl_department,
它有这么几列(dept_id(pk),dept_name,dept_memo...)
有一个员工table,我们叫它tbl_employee,在这个table中有一列dept_id(fk)描述关于部门的信息,若tbl_employee要满足3NF,则在tbl_employee中就不得再有除dept_id列的其它有关部门信息的列!
一般数据库的设计满足3NF即可!(个人觉得应该尽可能的满足3NF,一家之言^_^)
BCNF:通常认为BCNF是修正的第三范式,它比3NF又进一步!
4NF:
5NF:将一个table尽可能的分割成小的块,以排除在table中所有冗余的数据
--------------------------------------------------------------------
范式简介
为了回答上述问题,了解3NF、BCNF、4NF和5NF之间的区别很重要。以下为每个范式的准确定义。
第一范式(1NF)
每个表必须有一个首要键,即最少的一组属性,它与每条记录一一对应。通过适当定义键属性和非键属性,删除重复的组(不同记录似乎需要不同次重复的数据种类)。注:每个属性必须包含单独一个值,而非一组值。
第二范式(2NF)
数据库必须满足1NF的所有要求。另外,如果一个表有一个复合键,所有属性必须与整个键相关联。而且,在表的多行之间多余重复的数据被移动一个单独的表中。
第三范式(3NF)
存储在表中的数据不得依赖表的任何域,必须唯一依赖于首要键。数据库必须满足2NF的所有要求。既依赖首要键,又依赖其它域的数据被移动到一个单独的表中。
Boyce-Codd范式(BCNF)
除对一个候选键扩展集(称作一个超级键)存在属性函数依赖外,不存在其它非平凡函数依赖。
第四范式(4NF)
除对一个候选键扩展集存在属性组函数依赖外,不存在其它非平凡多值函数依赖。如果且只有一个表符合BCNF,同时多值依赖为函数依赖,此表才符合第四范式。4NF删除了不必要的数据结构:多值依赖。
第五范式(5NF)
不得存在不遵循键约束的非平凡连接依赖。如果且只有一个表符合4NF,同时其中的每个连接依赖被候选键所包含,此表才符合第五依赖。
--------------------------------------------------------------------
数据库范式
注:
表在定义中被称为关系,记作R
字段在定义中被称作属性
模式:数据库中有三种模式,外模式,内模式,模式
粗体是关键字的意思
斜体为外键
第一范式:
定义:如果关系R 中所有属性的值域都是单纯域,那么关系模式R是第一范式的
那么符合第一模式的特点就有
1)有主关键字
2)主键不能为空,
3)主键不能重复,
4)字段不可以再分
例如:
StudyNo
|
Name
|
Sex
|
Contact
20040901
john
Male
Email:kkkk@ee.net,phone:222456
20040901
mary
famale
email:kkk@fff.net phone:123455
以上的表就不符合,第一范式:主键重复(实际中数据库不允许重复的),而且Contact字段可以再分
所以变更为正确的是
StudyNo |
Name
|
Sex
|
Email
|
Phone
20040901
john
Male
kkkk@ee.net
222456
20040902
mary
famale
kkk@fff.net
123455
第二范式:
定义:如果关系模式R是第一范式的,而且关系中每一个非主属性不部分依赖于主键,称R是第二范式的。
所以第二范式的主要任务就是
满足第一范式的前提下,消除部分函数依赖。
StudyNo | Name | Sex |
Email
| Phone | ClassNo| ClassAddress
01
john
Male
kkkk@ee.net
222456
200401
A楼2
01
mary
famale
kkk@fff.net
123455
200402
A楼3
这个表完全满足于第一范式,
主键由StudyNo和ClassNo组成,这样才能定位到指定行
但是,ClassAddress部分依赖于关键字(ClassNo-〉ClassAddress),
所以要变为两个表
表一
StudyNo | Name | Sex |
Email
| Phone |
ClassNo
01
john
Male
kkkk@ee.net
222456
200401
01
mary
famale
kkk@fff.net
123455
200402
表二
ClassNo | ClassAddress
200401
A楼2
200402
A楼3
第三范式:
满足第二范式的前提下,消除传递依赖。
例:
StudyNo | Name | Sex |
Email
| bounsLevel | bouns
20040901 john
Male
kkkk@ee.net
优秀
$1000
20040902 mary
famale
kkk@fff.net
良
$600
这个完全满足了第二范式,但是bounsLevel和bouns存在传递依赖
更改为:
StudyNo
|
Name
|
Sex
|
Email
|
bouunsNo
20040901
john
Male
kkkk@ee.net
1
20040902
mary
famale
kkk@fff.net
2
bounsNo
|
bounsLevel
|
bouns
1
优秀
$1000
2
良
$600
这里我比较喜欢用bounsNo作为主键,
基于两个原因
1)不要用字符作为主键。可能有人说:如果我的等级一开始就用数值就代替呢?
2)但是如果等级名称更改了,不叫 1,2 ,3或优、良,这样就可以方便更改,所以我一般优先使用与业务无关的字段作为关键字。
一般满足前三个范式就可以避免数据冗余。
第四范式:
主要任务:满足第三范式的前提下,消除多值依赖
product
| agent | factory
Car
A1
F1
Bus
A1
F2
Car
A2
F2
在这里,Car的定位,必须由 agent 和 Factory才能得到(所以主键由agent和factory组成),可以通过
product依赖了agent和factory两个属性
所以正确的是
表1
表2:
product
|
agent
factory |
product
Car
A1
F1
Car
Bus
A1
F2
Car
Car
A2
F2
Bus
第五范式:
定义: 如果关系模式R中的每一个连接依赖, 都是由R的候选键所蕴含, 称R是第五范式的
看到定义,就知道是要消除连接依赖,并且必须保证数据完整
例子
A
|
B |
C
a1
b1
c1
a2
b1
c2
a1
b2
c1
a2
b2
c2
如果要定位到特定行,必须三个属性都为关键字。
所以关系要变为 三个关系,分别是A 和B,B和C ,C和A
如下:
表1
表2
表3
A
|
B
B
|
C
C
|
A
a1
b1
b1
c1
c1
a1
a1
b2
b1
c2
c1
a2
范式可以避免数据冗余,减少数据库的空间,减轻维护数据完整性的麻烦,但是操作难,因为需要联系多个表才能得到所需要数据,而且越高范式性能就会越差。要权衡是否使用更高范式是比较麻烦。
一般我在做项目中都,用得最多的也就是第三范式,我认为使用到第三范式也就足够了,性能好
而且方便管理数据
--------------------------------------------------------------------
I、关系数据库设计范式介绍
1.1 第一范式(1NF)无重复的列
所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,新的实体由重复的属性构成,新实体与原实体之间为一对多关系。在第一范式(1NF)中表的每一行只包含一个实例的信息。
简而言之,第一范式就是无重复的列。
说明:在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。
1.2 第二范式(2NF)属性完全依赖于主键
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。例如员工信息表中加上了员工编号(emp_id)列,因为每个员工的员工编号是惟一的,因此每个员工可以被惟一区分。这个惟一属性列被称为主关键字或主键、主码。
第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体