MySQL范式

为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中,这种规则就是范式。范式是符合某一种级别的关系模式的集合。关系型数据库中的关系必须满足一定的要求,即满足不同的范式。

目前关系型数据库有六种范式,分别为:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、第四范式(4NF)、第五范式(5NF)和第六范式(6NF)。要求最低的范式是第一范式。第二范式在第一范式的基础上又进一步的添加了要求,其余范式依次类推。

一般说来,数据库只需满足第三范式就行了,而通常我们用的最多的就是第一范式、第二范式、第三范式,也就是接下来要讲的”三大范式”。

1)第一范式

第一范式(1NF)用来确保每列的原子性,要求每列(或者每个属性值)都是不可再分的最小数据单元(也称为最小的原子单元)。

例如,客人住宿信息表 (姓名, 客人编号, 地址, 客房号, 客房描述, 客房类型, 客房状态, 床位数, 入住人数, 价格)。

其中,”地址”列还可以细分为国家、省、市、区等,甚至有的程序还把”姓名”列也拆分为”姓”和”名”等。如果业务需求中不需要拆分”地址”和”姓名”列,则该数据表符合第一范式,如果需要将”地址”列拆分,则下列写法符合第一范式:

客人住宿信息表(姓名, 客人编号, 国家, 省, 市, 区, 门牌号, 客房号, 客房描述, 客房类型, 客房状态, 床位数, 入住人数, 价格)。

2)第二范式

第二范式(2NF)在第一范式的基础上更进一层,要求表中的每列都和主键相关,即要求实体的唯一性。如果一个表满足第一范式,并且除了主键以外的其他列全部都依赖于该主键,那么该表满足第二范式。

客人住宿信息表中的数据主要用来描述客人住宿信息,所以该表主键为(客人编号,客房号):

  • “姓名”列、”地址”列➡”客人编号”列。
  • “客房描述”列、 “客房类型”列、”客房状态”列、”床位数”列、”入住人数”列、”价格”列➡”客房号”列。

其中,”➡”符号代表依赖。以上各列没有全部依赖于主键(客人编号,客房号),只是部分依赖于主键,不符合第二范式。

使用第二范式后,客人住宿信息表可以分解成以下两个表:

  • 客人信息表(客人编号,姓名,地址,客房号,入住时间,结账日期,押金,总金额),主键为”客人编号”列,其他列都全部依赖于主键列。
  • 客房信息表(客房号,客房描述,客房类型,客房状态,床位数,入住人数,价格),主键为”客房号”列,其他列都全部依赖于主键列。

3)第三范式

第三范式(3NF)在第二范式的基础上更进一层,第三范式是确保每列都和主键列直接相关,而不是间接相关,即限制列的冗余性。如果一个关系满足第二范式,并且除了主键以外的其他列都依赖于主键列,列和列之间不存在相互依赖关系,则满足第三范式。

为了更好的理解第三范式,这里我们需要了解传递依赖。假设A、B 和 C 是关系 R 的三个属性,如果 A➡B 且 B➡C,则从这些函数依赖中,可以得出 A➡C。如上所述,依赖 A➡C 称之为传递依赖。

以第二范式中的客房信息表为例,初看该表时没有问题,满足第三范式,每列都和主键列”客房号”相关,再细看会发现:

  • “床位数” 列、”价格”列➡”客房类型”列。
  • “客房类型”列➡”客房号”列。
  • “床位数”列、”价格”列➡”客房号”列

为了满足第三范式,应该去掉”床位数”列,”价格”列和”客房类型”列,将客房信息表分解为如下两个表。

  • 客房表(客房号,客房描述,客房类型编号,客房状态,入住人数)
  • 客房类型表(客房类型编号,客房类型名称,床位数,价格)

主键与外键在多表中的重复出现不属于数据冗余,非键字段的重复出现才是数据冗余。在客房表中客房状态存在冗余,需要进行规范化,规范化以后的表如下:

  • 客房表(客房号,客房描述,客房类型编号,客房状态编号,入住人数)。
  • 客房状态表(客房状态编号,客房状态名称)

最后,满足三大范式的 E-R 图如下所示:

满足三大范式的数据库模型图如下所示:

MySQL范式

4)反范式化

不满足范式的数据库设计,就是反范式化。

我们需要知道对于项目的最终用户来说,用户关心的是方便,清晰的数据结果。所以在设计数据库时,设计人员和客户在数据库的设计规范化和性能之间会有一定的矛盾。

上面我们通过三大范式将客房表分解出两个表,为了满足客户的需求,最终可能需要通过三个或四个表之间的连接查询,来得到客户需要的数据结果,插入数据同样如此,对于客户输入的数据,我们需要分开插入到三个或四个不同的表中。

由此可以看出,为了满足三大范式,我们的数据操作性能会受到相应的影响。

所以,在实际的数据库设计中,既要考虑三大范式,避免数据的冗余和各种数据操作异常,又要考虑数据访问性能。为了减少表连接,提高数据库的访问性能,也可以允许适当的数据冗余列,这也许就是最合适的数据库设计方案。

比如,有一张存放商品的基本表,数据表中包括”单价”、”数量””金额”等字段。”金额”这个字段就说明该表的设计不满足第三范式,因为”金额”可以由”单价”乘以”数量”得到,说明”金额”是冗余字段。

与第三范式中介绍的冗余相比,前面介绍的冗余属于低级冗余,我们反对低级冗余,但这里的冗余为高级冗余,目的是提高数据的处理速度,增加”金额”列后,可以提高查询统计的速度,这是以空间换取时间的做法。

注意:不要轻易违反数据库设计的规范化原则,如果处理不好,可能会适得其反,使应用程序运行速度更慢。

优缺点

最后我们来总结一下范式化和反范式化的优缺点。

1)范式化

优点如下:

  • 减少数据冗余
  • 范式化后的表中只有很少的重复数据,更新时只需要更新较少的数据,所以范式化的更新操作比反范式化更快
  • 范式化的表通常比反范式化更小

缺点如下:

  • 范式化的表在查询时经常需要很多的关联,这回导致性能降低
  • 增加了索引优化的难度

2)反范式化

优点如下:

  • 可以减少表的关联
  • 可以更好的进行索引优化

缺点如下:

  • 数据表存在数据冗余及数据维护异常
  • 对数据的修改需要更多的成本

源地址;

Original: https://www.cnblogs.com/wojiuyishui/p/16494276.html
Author: 我就一水
Title: MySQL范式

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/578670/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • linux挂载文件系统

    当使用光驱等硬件设备时,必须将其挂载到系统中,只有这样Linux才能识别。 1、给虚拟机中centos7系统添加一块新的硬盘,添加以后必须重启centos7才能生效 2、在root…

    Linux 2023年5月27日
    0103
  • 【持久层框架】- SpringData-JPA

    SpringData – JPA 😄生命不息,写作不止🔥 继续踏上学习之路,学之分享笔记👊 总有一天我也能像各位大佬一样🏆 一个有梦有戏的人 @怒放吧德德🌝分享学习心得…

    Linux 2023年6月6日
    079
  • 源码安装apache脚本部署

    源码安装apache脚本部署 [root@localhost ~]# ls anaconda-ks.cfg httpd.tar.xz [root@localhost ~]# tar…

    Linux 2023年6月6日
    0110
  • redis服务器

    这一次主要讲下redis中服务器这个结构体相关代码,主要从是代码层面进行讲解 redis服务器 redis服务器结构体主要代码在 redis.h/redisServer,下面给出该…

    Linux 2023年6月13日
    097
  • MSSQL中UPDATE与 INNER JOIN联用的语法结构

    | 0.16分钟 | 267.2字符 | 1、引言&背景 2、解决方案 3、声明与参考资料 | SCscHero | 2022/4/30 PM9:36 | 系列 | 已完成…

    Linux 2023年6月14日
    080
  • WEB自动化-01-Cypress 介绍

    Cypress 介绍 1.1 Cypress 简介 Cypress是一款基于 JavaScript的下一代前端测试工具。可以对浏览器中运行的任何内容进行快速、简单和可靠的测试。Cy…

    Linux 2023年6月7日
    097
  • 三少玩Linux之ArchLinux 与win7 共存简单安装过程记录

    win7的安装过程就不说了, 还是先要安装win7或者别的windows操作系统; 再安装Archlinux系统, 这个是安装视频教程:https://www.bilibili.c…

    Linux 2023年6月14日
    097
  • Linux常用命令总结

    Linux常用命令总结 关机 & 重启&注销 常用命令 作用 shutdown -h now 即刻关机 shutdown -h 5 5分钟后关机 shutdown …

    Linux 2023年6月7日
    0104
  • 网易互联网笔试(3.27)

    网易互联网3.27日笔试,四道笔试题一道简答题,四道笔试题AK,简答题考察设计模式不会。 第一道题模拟使用单体技能和群体技能攻击怪物的场景、第二题字符串处理、第三题构造具有限制条件…

    Linux 2023年6月13日
    0102
  • JS 模块化- 01 模块化前传

    前端技术的发展不断融入了很多后端的思想,逐步形成前端的 “四个现代化”:工程化、模块化、规范化、流程化。这个主题介绍 模块化 ,主要内容包括模块化前传(早期…

    Linux 2023年6月6日
    0104
  • Java刷题笔记7.25

    一个类构造方法的作用是什么? 主要是完成对&am…

    Linux 2023年6月7日
    0117
  • Go语言中的零值坑记

    开箱即用 什么叫开箱即用呢?因为 Go语言的零值让程序变得更简单了,有些场景我们不需要显示初始化就可以直接用,举几个例子: 切片,他的零值是 nil,即使不用 make进行初始化也…

    Linux 2023年6月6日
    0122
  • MySQL的主从复制+双主模式

    部署环境: MySQL master 192.168.40.21 MySQL slave 192.168.40.22 思路: I/O线程是对主MySQL上二进制日志文件进行读取,读…

    Linux 2023年6月8日
    0109
  • 我懂得了什么

    站在24岁的这个档口,没有学业又没有工作的时刻,前不着村后不着店。我觉得应该要写一些总结,虽然年仅24的我相比老人家总结不出更深刻的道理,但是现在是互联网的时代,获取知识的途径已经…

    Linux 2023年6月6日
    0104
  • 搭建部署Docker

    Docker安装准备: 首先看下服务器是否有旧版本,如果有需要卸载并且安装依赖 然后下载docker仓库repo源: 安装完成后查看docker仓库版本信息: yum安装docke…

    Linux 2023年6月8日
    0109
  • Python的闭包是什么意思?

    闭包算是编程语言里一个比较常见的概念,但说实话,这个名词有点晦涩。在查看了半天网上的资料后,还是有点不明就里。 我疑惑的点主要是:这个东西是用来解决什么问题的?或者说,他的作用是什…

    Linux 2023年6月8日
    0106
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球