【SQL性能优化】【范式设计与反范式设计】

范式设计

数据库的设计范式

关系型数据库总共有6种范式,按照范式级别从低到高有:

  1. 第一范式(1NF)
  2. 第二范式(2NF)
  3. 第三范式(3NF)
  4. 巴斯-科德范式(BCNF)
  5. 第四范式(4NF)
  6. 第五范式(5NF, 完美范式)

特点:高阶范式一定符合低阶范式的要求。越高阶,冗余度越低

设计数据表时,通常尽量满足3NF足矣,甚至有时我们会为了提高一些查询性能,选择破坏范式规则,这叫反规范化。

数据表的键

范式的使用主要来源于键,主键、候选键、超键等等,键是由一个或多个属性组成
在这里插入图片描述
我们从上图理解这些键的意思,

  • 超键:包括唯一标识的属性集,如(ID,NAME)(S_ID,AGE)
  • 候选键:最小超键,球员表就是(ID)和(S_ID),SID是身份证,ID是球员编码
  • 主键:我们自己从候选键选一个
  • 外键:球员表中的TEAM_ID
  • 主属性:就是候选键,其他属性例如姓名年龄就是非主属性

1NF\2NF\3NF介绍

  1. 1NF指数据表中任何属性都是不可拆分的原子性的
  2. 2NF指数据表里非主属性都要和这个数据表的候选键有完全依赖关系
  3. 3NF指满足2NF下,对任何非主属性不传递依赖候选键
1NF:

这个很好理解,就是字段不可以拆分,字段X无法拆分成X1,X2这样,基本都会满足这要求

2NF:

意思是非主属性是完全依赖候选键,是通过候选键来查找的,不能仅仅依赖一部分

实例解释:球员比赛表

球员编号姓名年龄比赛编号比赛时间比赛场地
1qaq15014.9洛杉矶

可以看出这个表格的候选键有“球员编号”与“比赛编号”,

得到关系:(球员编号, 比赛编号) → (姓名, 年龄, 比赛时间, 比赛场地)

但是数据表中存在以下对应关系:
(球员编号) → (姓名,年龄)
(比赛编号) → (比赛时间, 比赛场地)

就是说有一些字段只是依赖了部分的候选键,没有完全依赖所有的候选键,这样不符合2NF。

这 种 情 况 会 导 致 什 么 问 题 呢 ? \color{red}这种情况会导致什么问题呢?

  1. 数据冗余
    一个球员参加m场比赛,球员姓名&年龄重复m-1次
    一个比赛有n个球员参加,时间和地点重复n-1次

  2. 插入异常
    添加新的比赛,但不知道有哪些球员,无法插入

  3. 删除异常
    删除某个球员编号,如果没有单独的比赛表,会同时把比赛信息删掉

  4. 更新异常
    若调整某个比赛时间,那么关于这个比赛的所有时间都需要更新,否则会出现一场比赛时间不同的情况

2 N F 核 心 思 想 : 一 张 表 是 一 个 独 立 对 象 , 只 表 达 一 个 意 思 \color{blue}2NF核心思想:一张表是一个独立对象,只表达一个意思 2NF

3NF:

存在一张这样的表:

球员编号姓名球队名称球队教练
1qaqabc哈皮

在这里插入图片描述
球员编号决定了球队名称,但是球队名称也能决定球队教练,说明球队教练就会传递依赖于球员编号.
3nf的关键是看非主键列是直接依赖于主键不?

总结

其实上面的名词解释有点过多,我觉得不太好理解,我们应该用简单的话去描述会更加容易记忆。

1NF:把字段分开,姓名和年龄分开
2NF:加个主键,如id,所有列完全依赖这个id
3NF:加个外键,建个新表。因为有些属性不是完全依赖主键

缺点:范式越高,会设计越多数据表出来,那么查询时就要关联多张表,影响查询效率

额外题目练习

有一张学生选课表,包含的属性有学号、姓名、课程名称、分数、系别和系主任,如果要改成符合 3NF 要求的设计,需要怎么修改呢?
答 : \color{blue}答: 学号、课程名称、系别是候选键。分数不是完全依赖于学号,违反2NF。系主任违反3NF,不是直接依赖于学号主键。

拆分成4张表:
学生表:

学号姓名系别id

课程表:

课程id课程名

成绩表:

学号课程id分数

院系表:

系别id系别名称系主任

反范式设计

BCNF(巴斯范式)

所有非主属性对于每一个候选键都是完全依赖,所有主属于对于每一个不包含它的候选键也是完全依赖。

反范式设计的场景

数据表越多,数据冗余度越低,但是为了性能和读取效率,有时候违反原则,允许少量的冗余,通过空间来换时间。

  • 简单实例:有一个商品评论表,一个用户表,查询评论者、评论内容和评论时间
    查询评论者要去用户表获取用户名,查询时要关联两张表,进行聚集索引扫描再嵌套循环,这一操作会耗费较多时间,如果数据量不大,那么还好;如果是百万级别的数据,会响应很慢。
    如果直接在商品评论表添加用户名字段,那么就可以做到快速查询,只需做一次聚集索引
反范式设计可能存在的问题
  1. 数据量小时,反映不出性能的优势,可能会导致数据库设计更加复杂,增加维护成本
  2. 用户昵称频繁更新,需要执行存储过程来更新,会消耗系统资源
反范式设计适用场景

当冗余信息有价值或能大幅度提高查询效率,可以采用反范式去优化,例如订单中的各种用户信息。

数据仓库也常用这种设计,因为仓库通常是存储历史数据,不需要实时性很强的增删改,适当允许数据冗余度,方便进行数据分析

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值