数据库三大范式的理解

对于三大范式一直没有好好理解过,这次打算花时间搞懂这个概念。经过百度、翻阅博客以及看视频,算是搞清楚了范式是什么,记录下来,供以后复习。

百度知道 的一则回答非常好:

image-20220301233109198

由此可见,范式,就是一种规范,在设计一张表时所遵循的规范。为什么有这种规范,目的就是更好解决数据冗余,提高存储效率。

然而,

实际中并没有去严格遵守这种规范。因为规范和性能不可兼得!规范越高,性能越低。

比如:

《阿里巴巴JAVA开发手册》里面写超过三张表禁止join

image-20220302154745068

在实际的开发中需要考虑诸多问题,如:

  • 考虑商业化的需求和目标(成本,用户体验),数据库的性能更加重要
  • 在规范性能问题的时候,需要适当地考虑一下规范性
  • 有时候会故意给某些表增加一些冗余的字段(多表查询→单表查询)
  • 有时会故意增加一些计算列(比如当有几百万条数据时,SELECT COUNT(*)会非常慢,直接增加一个计算列,每次增加一条数据时,这个列自动加一 )(大数据量→小数据量)

范式(Normal Form,NF)

范式是符合某一种级别的关系模式的集合。关系数据库中的关系是要满足一定要求的,满足不同程度要求的为不同范式。

目前关系数据库有六种范式:1NF,2NF,3NF,BCNF,4NF,5NF

这六种范式是包含关系:5NF ⊂ 4NF ⊂ BCNF ⊂ 3NF ⊂ 2NF ⊂ 1NF

常用的是第一范式(1NF)、第二范式(2NF)、第三范式(3NF),俗称“三大范式”。

以下参考博客:https://www.cnblogs.com/wsg25/p/9615100.html

第一范式(1NF)

第一范式是指数据库表的每一列都是不可分割的基本数据项。

举例:

image-20220301224319457

上面的表中,家庭信息”和“学校信息”就不满足第一范式,它们还可以再分割,调整如下:

image-20220301224508334

调整后每一列都不能再分了,故满足第一范式。

第二范式(2NF)

第二范式

  • 必须满足第一范式

  • 非主属性完全依赖于主关键字,不能依赖于主键的一部分

    注:什么叫依赖于主键的一部分?这是针对联合主键而言的,联合主键就是用多个属性组成的主键。

例子

image-20220301224947409

上表中,主键为联合主键[订单号,产品号],(只有这两个属性组合在一起,才能唯一地标识一行信息),这个表满足第一范式(不可再分),但不满足第二范式,因为“订单金额”和“订单时间”只依赖于“订单号”(知道订单号,订单金额和时间也就确定了),不依赖于“产品号”,换句话说,他们不完全依赖主键[订单号,产品号],而是依赖于主键的一部分,因此不满足第二范式。调整如下:

image-20220301230140764

分成了两个表,每个表都满足第二范式,左表的非主属性完全依赖于主键[订单号,产品号],右表的非主属性完全依赖于主键[订单号]。

第三范式(3NF)

第三范式

  • 必须满足第二范式
  • 任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

就是说,对于一个满足第二范式的表,表中有可能存在某些列不直接依赖主键,而是间接依赖,必须消除。

例子

image-20220301231404974

上表中,所有属性都完全依赖于学号这个主键,但是“班主任性别”和“班主任年龄”不是直接依赖学号的,而是通过直接依赖于“班主任姓名”而间接依赖于学号的(班主任姓名是直接依赖于学号的),故不满足第三范式。调整如下:

image-20220301232010470

分成了两个表,每个表都满足第三范式。

posted @ 2022-03-02 16:12  sxkio  阅读(1199)  评论(0编辑  收藏  举报