数据库设计概要--函数依赖和范式

数据库设计

函数依赖

A -> B,称为 B 依赖于 A ,也可以称为 A 决定 B。
例如:通过身份证号可以知道人的名字和住址,可以称为身份证号决定名字和住址。

身份证号 -> (名字,住址)

如果 A -> B,B -> C,则称为依赖的传递。

可能引发的数据库异常

如果在设计数据库字段的时候没有考虑全面,可能会造成一些异常:

  • 数据冗余
  • 修改异常
  • 删除异常
  • 插入异常

表一(反面例子):

student_idclass_idstudent_nameclass_namegrade
11小李一班90
21小王一班98
31小潘一班89
12小孙二班93
22小霞一班95

数据冗余

表一中 student_id 代表学生在班里的学号。因为有多个同班的学生导致出现了 3 个一班和 2 个二班,造成了数据冗余。

修改异常

将 class_id 为 1 的班级的 class_name 修改为“三班”时,如果只修改了第一行的数据,第二行的 class_id 为 1 的班级的 class_name 还是一班,这就造成了修改异常。而如果为了防止这个异常将全部 class_id 为 1 的班级的 class_name 都修改一遍的话,效率将会十分低下。

删除异常

删除一个信息,那么也会丢失其它信息。例如删除了 班级1 需要删除第一行到第三行,那么 学生1-3 的信息就会丢失。

插入异常

在表一中如果要插入一个学生,这个学生如果没有成绩,就不能插入,产生插入异常。

范式(能有效解决异常)

1NF(第一范式)

第一范式中属性不可分。
表A:

student_idclass_idstudent_nameclass_name
(1,2,3)1(小李,小王,小潘)一班
(1,2)2(小孙,小霞)二班

表A中 student_id 和 student_name 都能分成更小的单位,这是不满足第一范式的,但是修改为上面表一的样子后,就满足第一范式了。

2NF(第二范式)

在满足第一范式的基础上,第二范式中每个非主属性完全函数依赖于键码。

例子还是表一,表一中键码为(class_id,student_id)。因为我们通过班级和学号就能确定一个具体的学号,比如一班一号就是小李、二班的一号就是小孙。满足第二范式的表应该是通过键码:(class_id,student_id)就能决定剩下的非主属性。但是在表一中班级名字 class_name 只依赖于班级编号 class_id,它是部分依赖于键码,而不是完全依赖键码(class_id,student_id)。

表一依赖关系:
class_id -> class_name
(class_id,student_id) -> student_name

于是我们可以通过分解成表B和表C,得到满足第二范式的表:
表B:

student_idclass_idstudent_namegrade
11小李90
21小王98
31小潘89
12小孙93
22小霞95

表C:

class_idclass_name
1一班
2二班

3NF(第三范式)

在满足第二范式的基础上,非主属性不传递函数依赖于键码。

表D:

广东广州越秀区
广东广州天河区
广东广州海珠区
四川成都温江区
四川成都成华区

在表D中,有如下的依赖关系:

省 -> 市
市 -> 区

同样产生了冗余的数据,只要进行拆分为表E和表F就能满足第三范式:
表E:

广东广州
四川成都

表F:

广州越秀区
广州天河区
广州海珠区
成都温江区
成都成华区
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值