数据库三范式
一、关系数据结构及形式化定义
- 关系:二维表。
- 属性:二维表中的列。
- 元组:二维表中的行。
- n目关系:具有n列的二维表。
- 属性组:二维表中多个列组成一个属性组。
- 候选码:若一个属性组的值能够唯一标识一个元组,则该属性组位候选码。
- 主码:如果一个关系有多个候选码,那么选择一个作为主码。(主键)
- 主属性:候选码中的每一个属性都为主属性。
二、函数依赖
- 函数依赖:不可能存在两个元组在X属性上的值相等,在Y属性上的值不等。也就是X属性的值确定后,Y属性的值随之确定了。也可以是Y属性的值依赖于X。也就是X的值唯一确定一个Y值。记作:X->Y。
- 平凡函数依赖:X->Y,但是Y属性是X属性的一部分。因为Y是X的一部分,所以在X属性的值如果相等,那么Y的值必定相等。这里说的依赖都指非平凡函数依赖。
- 完全函数依赖:X->Y,不存在X的真子集X’->Y.
- 部分函数依赖:X->Y,存在X的真子集X’->Y.
三、数据库三范式
1NF:一张二维表必须满足分量是不可分割的数据项。也就是一个属性只表达一种信息,不要用一个属性表达多种信息。
下面这张二维表就不满足第一范式。
id | name | info |
---|---|---|
1 | 张三 | 地址:xxx,电话:yyy |
2 | 李四 | 年龄:21 |
2NF:在满足1NF后,每个非主属性完全函数依赖于任何一个候选码。
下面这张二维表就不满足第二范式。【Sno-学号,Cno-课程号,Sname-学生名字,Cname-课程名字】
Sno | Cno | Sname | Cname |
---|---|---|---|
1 | 1 | 张三 | 语文 |
1 | 2 | 张三 | 数学 |
2 | 1 | 李四 | 语文 |
2 | 2 | 李四 | 数学 |
对于上面这张二维表,(Sno, Cno)是候选码,也是主键,所以Sno,Cno是主属性,Sname和Cname是非主属性。(Sno,Cno)的值可以唯一确定Sname,也可以唯一确定Cname,所以(Sno,Cno)->Sname,(Sno,Cno)->Cname。但是我们发现,Sno可以唯一确定Sname,Cno可以唯一确定Cname;这就意味着:(Sno,Cno)->Sname,(Sno,Cno)->Cname都是部分函数依赖,所以不满足第二范式。
如何解决?看下面:
STU表。
Sno | Sname |
---|---|
1 | 张三 |
2 | 李四 |
COURSE表。
Cno | Cname |
---|---|
1 | 语文 |
2 | 数学 |
这样拆分成两张表后,Sno -> Sname,Cno -> Cname,就满足了第二范式。
第二范式告诉我们:不要把多个实体整到一张表里,一个实体对应一张表,就像面向对象中设计类时遵从单一职责原则一样。
3NF:满足1NF后,不存在码X,属性组Y和非组属性Z,使得X->Y,Y->Z成立。
第三范式中除了包含第二范式,还进行了更严格的约束。
如果在3NF中加入前提:Y是X的一部分,那么3NF就是2NF了。
X = (Sno, Cno) ,Y = Sno ,Z = Sname,那么就会出现X->Y,Y->Z成立,不满足3NF。
同理,X = (Sno, Cno) ,Y = Cno ,Z = Cname,那么就会出现X->Y,Y->Z成立,同样不满足3NF。
如果在3NF中加入另外一种前提:Y不是X的一部分,那么又是在约束哪一种情况呢?
下面就是。【Sno-学号,Sname-学生姓名,Sdept-系名,Sloc-系的地址】
STU表。
Sno | Sname | Sdept | Sloc |
---|---|---|---|
1 | 张三 | 数学系 | A角落 |
2 | 李四 | 语文系 | B角落 |
SDEPT表。
Sdept | Sloc |
---|---|
数学系 | A角落 |
语文系 | B角落 |
对于STU表而言,Sno是主键,Sdept是外键,Sdept和Sloc都是非主属性。Sno可唯一确定Sdept,Sno -> Sdept,Sdept又可以唯一确定Sloc, Sdept->Sloc,把Sno换成X, Sdept换成Y,Sloc换成Z,就出现了 X->Y,Y->Z,又不满足第三范式了。
那么如何解决呢?看下面。
STU表。
Sno | Sname | Sdept |
---|---|---|
1 | 张三 | 数学系 |
2 | 李四 | 语文系 |
3 | 张三 | 语文系 |
SDEPT表。
Sdept | Sloc |
---|---|
数学系 | A角落 |
语文系 | B角落 |
那么第三范式告诉了我们什么:除了一个实体对应一张表之外,还要求外键不能出现冗余,能一列搞定的事就不要出现第二列第三列。