有关数据库设计中的几种范式的总结

关系数据库的几种数据库设计范式:一般设计中考虑三范式就足够高效了。

简要介绍下三范式。

第一范式:数据库中表的字段需满足原子性,也就是不可再分。这个不可再分性主要是指字段的属性需要是基本类型的,也就是整型、字符型、逻辑型等等,值得提一句的是,目前我们用的所有关系型数据库都满足第一范式,所以这是我们不需要操心的规则。

第二范式:第二范式是在满足第一范式的基础上设计的。

第一个要求是:要求表中不能存在完全相同的字段,要求表中的每个实例都可以被唯一的区分,这是我们经常使用主键的原因。

第二个要求是:数据库表中不存在非关键字段对任一候选关键字段的部分函数依赖(部分函数依赖指的是存在组合关键字中的某些字段决定非关键字段的情况),也即所有非关键字段都完全依赖于任意一组候选关键字。(另外,所有单关键字的数据库表都符合第二范式,因为不可能存在组合关键字。)

上段表述比较拗口,举个例子来表示:


image

上表满足第一范式,即每个字段具有不可再分性。但是不满足第二范式。从表可以看出组合关键字为(学号,课程名称),但表中“学分”完全依赖“课程名称”,而“姓名”和“年龄”完全依赖“学号”。也就是说在这一张表里描述了两个事情:学生信息、课程信息。这样的后果是:

(1) 数据冗余:同一门课程由n个学生选修,"学分"就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。
(2) 更新异常:若调整了某门课程的学分,数据表中所有行的"学分"值都要更新,否则会出现同一门课程学分不同的情况。
(3) 插入异常:假设要开设一门新的课程,暂时还没有人选修。这样,由于还没有"学号"关键字,课程名称和学分也无法记录入数据库。
(4) 删除异常:假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。但是,与此同时,课程名称和学分信息也被删除了。很显然,这也会导致插入异常。

修改后如下:

学生表

image

课程表

image

成绩表

image

上述修改后每个表中的信息完全依赖一个关键字,有效防止了数据冗余和各种异常情况。

稍微总结一下就是:尽可能的使用单关键字;每个表只表述一种信息就OK了,不要视图把所有信息放在一个表,当数据比较大的时候会非常影响效率。

第三范式:第三范式是基于第二范式的。要求关键字必须直接对应非关键字字段,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息,也就是决定某字段值的必须是主键。

一般满足这三种范式就可以设计出比较高效的数据表,但也有例外,有的情况需要使用逆范式,也就是在第三范式的基础上加上冗余以提供更高效的操作。

举个例子:一个相册表,里面含有各种相册的数据,包括相册ID,相册名称,相册创建时间,等等。再有一个图片表,字段包括图片ID,图片名称(路径),图片点击次数,图片所属相册id,图片创建时间等等。这个时候,我们的相册和图片是有联系的,因为一个图片的点击的增加会导致相应相册的点击数增加,如果我们不使用冗余,那么只有一个点击次数的字段,我们需要整个相册的点击数的时候,需要遍历整个图片然后把该相册ID的所有图片的点击次数加起来,这对于每一次查询对数据库服务器都是巨大的考验,而这仅仅是因为使用了三范式,所以在这种一(相册)对多(图片)的情况下,我们最好设置冗余字段,这就是在相册里面加一个点击次数,这样每次在图片点击次数增加后,所属相册ID的点击次数也会相应增加,这不用进行遍历,只用到一次查询,甚至加了外键索引后的效率只是一次常数指令运行的时间,这对于服务器的效率的节省非常有用。所以合适的逆范式会让数据库设计更加高效。这说明数据库设计是复杂需要考虑到很多因素的,在进行设计之前需要全面考虑各个方面。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值