本文主要是介绍BCNF(巴斯范式)与反范式设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
BCNF与反范式设计
- BCNF(巴斯范式)
- 反范式设计
- 反范式存在的问题和适用场景
- 数据仓库和数据库在使用上的区别
- 总结
反范式设计是什么,有了范式设计,为什么还需要反范式设计。反范式设计适用的场景是什么?存在什么问题
3NF有什么不足?除了3NF,我们为什么需要BCNF。
BCNF(巴斯范式)
有如下仓库warehouse_keeper表, 一个仓库只有一个管理员,同时一个管理员也只能管理一个仓库
- 候选键:(管理员,物品名) (仓库名,物品名)
- 主键:(仓库名,物品名)
- 主属性:仓库名,管理员和物品名
- 非主属性:数量
如何判断一张表的范式?我们需要根据范式的等级,从低到高判断。
- 数据库每个属性都是原子性的,符合1NF的要求
- 数据表中的非主属性 数量 都与候选键全部依赖, (仓库名,物品名)决定数量, (管理员,物品名)决定数量,因此,符合2NF的要求
- 数据表中的非主属性,不传递依赖于候选键。因为符合3NF的要求
既然数据表已经符合3NF的要求,是不是就不存在问题呢?
- 增加一个仓库,但是没有存放任何物品。根据数据表实体完整性的要求,主键不能有空值,因此会出现插入异常
- 如果仓库更换了管理员,我们就可能会修改数据表中的多条记录
- 如果仓库里面的商品都卖空了,那么此时仓库名称和相应的管理员名称也会随之被删除
所以,即便数据表满足3NF的要求,同样存在插入,更新和删除数据的异常情况
造成这种异常的原因是: 主属性仓库名对候选键(管理员,物品名)是部分依赖的关系,这样就有可能导致上面的异常情况。
BCNF:人们在3NF的基础上进行了改进,提出了BCNF,也叫做巴斯-科德范式,它在3NF的基础上消除了主属性对候选键的部分依赖或者传递依赖的关系。
根据BCNF的要求,我们将仓库管理关系表 拆分成下面的这样
- 仓库表:(仓库名,管理员)
- 库存表:(仓库名,物品名,数量)
这样就不存在主属性对于候选键的部分依赖或传递依赖,上面数据表的设计就符合BCNF
反范式设计
越高阶的范式得到的数据表越多,数据冗余就越低。但有时候,我们设计数据表的时候,需要为了性能和读取效率违反范式化得到原则。反范式就是允许少量的冗余,通过空间换时间。
比如商品表和用户表,我们每次 查询商品的时候需要展示用户名字,这个时候可以再新建一张表,和商品表保持一致,并且将用户名字段也加载里面,然后就不需要每次查询都连表,增加查询效率。新建的冗余表,注重数据同步
反范式存在的问题和适用场景
存在的问题:
在数据量小的情况下,反范式不能体现性能的优势,可能还会让数据库的设计更加复杂。
- 比如采用存储过程来支持数据的更新、删除等额外操作,很容易增加系统维护的成本
- 比如用户每次更改昵称的时候,都需要执行存储过程来更新,如果昵称更改频繁,会非常消耗系统资源。
使用场景:
- 当冗余信息有价值或者能大幅度提高查询效率的时候,我们就看可以采取反范式的优化。
- 常用于数据仓库的设计中,因为数据仓库通常存储历史数据,对增删改的实时性要求不强,对历史数据的分析需求强。
数据仓库和数据库在使用上的区别
- 数据库设计的目的在于捕获数据,而数据仓库的设计目的在于分析数据
- 数据库对数据的增删改实时性要求强,需要存储在线的用户数据,而数据仓库的一般都是历史数据
- 数据库设计需要尽量避免冗余,但为了提升查询效率也允许一定的冗余性,而数据仓库在设计上更偏向于采用反范式设计
总结
范式设计越高阶,数据表就会越精细,数据的冗余度也就减少,在一定程度上可以让数据库在内部关联上更好的组织数据。但有时候我们也需要采用反范式进行优化,通过空间来换取时间。
范式本身没有优劣之分,只有使用场景不同。没有完美的设计,只有合适的设计,我们在数据表的设计中,还需要根据需求将范式和反范式混合使用。
这篇关于BCNF(巴斯范式)与反范式设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!