数据库表设计范式

华子目录

  • MYSQL库表设计:范式
    • 第一范式(1NF)
    • 第二范式(2NF)
    • 第三范式(3NF)
    • 三范式小结
    • 巴斯-科德范式(BCNF)
    • 第四范式(4NF)
    • 第五范式(5NF)/完美范式
    • 第六范式(6NF)/域键范式
    • 反范式
    • 数据库范式设计总结

MYSQL库表设计:范式

在这里插入图片描述

  • MySQL的库表设计,在很多时候我们都是率性而为,往往在前期的设计中考虑并不全面,同时对于库表结构的划分也并不明确,所以很多时候在开发过程中,代码敲着敲着会去重构某张表结构,甚至大面积重构多张表结构,这种随心所欲的设计方式,无疑给开发造成了很大困扰。

  • 范式(Normal Form)是指设计数据库时要遵守的一些原则

  • 在设计DB库表结构时,需要遵守该规范,可以让在项目之初,设计的库表结构更为合理且优雅。数据库范式中,声名远扬的有三大范式,但除此之外也有一些其他设计规范,如:

    • 数据库三大范式(1NF、2NF、3NF
    • 第四范式(4NF)和第五范式:完美范式(5NF
    • 巴斯-科德范式(BCNF
    • 域键范式
    • 反范式设计
  • 小结:三大范式之间,是递进的关系,后续的范式都基于前一个范式的基础上推行,比如:今天我要先炒菜,然后吃饭,最后洗碗,这三者属于递进关系,后者都建立在前者之上,其顺序不能颠倒,比如先吃饭再炒菜,这必然是行不通的。数据库的三大范式也一样,第二范式必须建立在第一范式的基础之上,如若设计的库表第一范式都不满足,那定然是无法满足第二范式的。

第一范式(1NF)

  • 原则:库表设计时为了确保原子性,其存储数据具备不可再分性,,例:

在这里插入图片描述

  • 在上述的学生表中,其中有一个student学生列,这一列存储的数据原则明显不符合第一范式:原子性的规定,因为这一列的数据还可以再拆分为姓名、性别、身高三项数据,因此为了符合第一范式,应该将表结构更改为:

在这里插入图片描述

  • 如果不去拆分列满足第一范式,会造成什么影响?
    • 客户端语言和表之间无法很好的生成映射关系。
    • 查询到数据后,需要处理数据时,还需要对student字段进行额外拆分。
    • 插入数据时,对于第一个字段的值还需要先拼装后才能进行写入。

第二范式(2NF)

  • 原则:表中的所有列,其数据都必须依赖于主键,也就是一张表只存储同一类型的数据,不能有任何一列数据与主键没有关系,例:

在这里插入图片描述

  • 虽然此时已经满足了数据库的第一范式,但此刻观察course课程、score分数这两列数据,跟前面的几列数据实际上依赖关系并不大,同时也由于这样的结构,导致前面几列的数据出现了大量冗余,所以此时可以再次拆分一下表结构:

在这里插入图片描述

  • 经过上述结构优化后,之前的一张表被拆分成学生表、课程表、成绩表三张,每张表中的id字段作为主键,其他字段都依赖这个主键。无论在那张表中,都可以通过id主键确定其他字段的信息,每张表的业务属性都具备“唯一性”,也就是每张表都只会描述了“一件事情”,不会存在一张表中会出现两个业务属性。

第三范式(3NF)

  • 原则:表中每一列数据不能与主键之外的字段有直接关系,例:

在这里插入图片描述

  • 比如这张学生表,目前即符合第一范式,也符合第二范式,但看最后的两个字段,department表示当前学生所属的院校,dean则表示这个院系的院长是谁。一般来说,一个学生的院长是谁,首先是取决于学生所在的院系的,因此最后的dean字段明显与department字段存在依赖关系,因此需要进一步调整表结构:

在这里插入图片描述

  • 经过进一步的结构优化后,又将原本的学生表拆为了院系表、学生表两张,学生表中则是只存储一个院系ID,由院系表存储院系相关的所有数据。至此,学生表中的每个非主键字段与其他非主键字段之间,都是相互独立的,之间不会再存在任何依赖性,所有的字段都依赖于主键。
  • 为什么要这样调整?不调整会发生什么问题:
    • 当一个院系的院长换人后,需要同时修改学生表中的多条数据。
    • 当一个院长离职后,需要删除该院长的记录,会同时删除多条学生信息。
    • 如果设计的表结构,无法满足第三范式,在操作表时就会出现异常,使得整个表较难维护。

三范式小结

  • 范式小结
    • 1NF:确保原子性,表中每一个列数据都必须是不可再分的字段。
    • 2NF:确保唯一性,每张表都只描述一种业务属性,一张表只描述一件事。
    • 3NF:确保独立性,表中除主键外,每个字段之间不存在任何依赖,都是独立的。
  • 没有按照范式设计表时,会存在几个问题
    • 整张表数据比较冗余,同一个学生信息会出现多条。
    • 表结构特别臃肿,不易于操作,要新增一个学生信息时,需添加大量数据。
    • 需要更新其他业务属性的数据时,比如院系院长换人了,需要修改所有学生的记录。
  • 经过三范式的设计优化后,整个库中的所有表结构,会显得更为优雅,灵活性也会更强。

巴斯-科德范式(BCNF)

  • 概念:
    • 前题:一般在一张表中,可以用于区分每行数据的一个列,通常会被咱们设为主键,例如常用的ID字段就是如此,这类主键通常被称为单一主键,即一个列组成的主键。但除此之外,还有一个联合主键的概念,也就是由多个列组成的主键
    • 巴斯-科德范式也被称为3.5NF,是第三范式的补充版
    • 第三范式的要求是:任何非主键字段不能与其他非主键字段间存在依赖关系,也就是要求每个非主键字段之间要具备独立性。而巴斯-科德范式在第三范式的基础上,进一步要求:任何主属性不能对其他主键子集存在依赖
    • 大白话:规定了联合主键中的某列值,不能与联合主键中的其他列存在依赖关系
  • 例:

在这里插入图片描述

  • 分析
    • 这张学生表,此时假设以classes班级字段、class_adviser班主任字段、name学生姓名字段,组合成一个联合主键,在这里我们可以通过联合主键,确定学生表中任何一个学生的信息,比如:熊竹老师管的计算机-2201班,哪个竹子同学有多高啊?可以通过上述的联合主键精准定位到表中第一条数据,并且最终能够给出答案为185cm
    • 出现问题:在这张表中,一条学生信息中的班主任,取决于学生所在的班级,比如「竹子同学、子竹同学」在「计算机-2201班」,所以它们的班主任都是「熊竹老师」,因此班主任字段其实也依赖于班级字段。那会造成什么问题呢?
      • 当一个班级的班主任老师换人后,需要同时修改学生表中的多条数据。
      • 当一个班主任老师离职后,需要删除该老师的记录,会同时删除多条学生信息。
      • 想要增加一个班级时,同时必须添加学生姓名数据,因为主键不允许为空。
  • 通过上述分析可以明显得知,如果联合主键中的一个字段依赖于另一个字段,同样也会造成不小的问题,使得整张表的维护性变差,因此这里需要进一步调整结构:

在这里插入图片描述

  • 经过结构调整后:

    • 原本的学生表则又被拆为了班级表、学生表两张,在学生表中只存储班级ID,然后使用classes_id班级IDname学生姓名两个字段作为联合主键。
    • 之前的三个问题也不存在,如换班主任后只需要更改班级表,无需修改学生表中的学生信息;增加班级时,只需要在班级表中新增数据,也不会影响学生表。
  • 小结:第三范式只要求非主键字段之间,不能存在依赖关系,但没要求联合主键中的字段不能存在依赖,因此第三范式并未考虑完善,巴斯-科德范式修正的就是这点,是对第三范式的补充及完善,修正了第三范式。

第四范式(4NF)

  • 多值依赖:表中的字段之间存在一对多的关系,也就是一个字段的具体值会由多个字段来决定(一个表中至少需要有三个独立的字段才会出现多值依赖问题)
  • 示例:

在这里插入图片描述

经典的业务,用户角色权限表,各字段含义:

  • user_name字段 – 用户名

  • role字段 – 角色信息:

    • USER:普通用户角色。
    • ADMIN:管理员角色。
    • ROOT:超级管理员角色。
  • permission字段 – 权限信息:

    • *:超级管理员拥有的权限级别,*表示所有。
    • BACKSTAGE:管理员拥有的权限级别,表示可以操作后台。
    • LOGIN:普通用户拥有的权限级别,表示可以登录访问平台。
  • 此时假设我们需要新增一条数据,那表中的权限字段究竟填什么?这个值是需要依赖多个字段决定的,权限来自于角色,而角色则来自于用户。也就是说,一个用户可以拥有多个角色,同时一个角色可以拥有多个权限,所以此时咱们无法单独根据用户名去确定权限值,权限值必须依赖用户、角色两个字段来决定,这种一个字段的值取决于多个字段才能确定的情况,就被称为多值依赖。

  • 因此第四范式的定义就是要消除表中的多值依赖关系,上述表格拆分为:

在这里插入图片描述
在这里插入图片描述

  • 观察上述的五张表正是大名鼎鼎的权限五表,将原本的用户角色权限表,拆分成了用户表、角色表、权限表、用户角色关系表、角色权限关系表。
  • 经过这次拆分之后,一方面用户表、角色表、权限表中都不会有数据冗余,第二方面无论是要删除亦或新增一个角色、权限时,都不会影响其他表。后面的两张关系表,主要是为了维护用户、角色、权限三者之间的关系。

第五范式(5NF)/完美范式

  • 定义:建立在4NF的基础上,进一步消除表中的连接依赖,直到表中的连接依赖都是主键所蕴含的

  • 第五范式解决的是无损连接问题,基本没有实际意义,了解即可,因为无损连接很少出现,而且难以察觉

第六范式(6NF)/域键范式

  • 域键范式,也被称之为终极范式,但目前也仅有学术机构在研究,在生产环境中实际的用途也不大

反范式

  • 概念:不遵循数据库范式设计的结构,就被称为反范式结构。

  • 遵循数据库范式设计优点如下:

    • 避免了大量的数据冗余
    • 节省了大量存储空间
    • 表整体结构更为优雅,能让SQL操作更加便捷且减少出错。
  • 但随着范式的级别越高,设计出的结构会更加精细化,原本一张表的数据会被分摊到多张表中存储,表的数量随之越来越多。会存在一个致命问题,也就是当同时需要这些数据时,只能采用联表查询的形式检索数据,有时候甚至为了一个字段的数据,也需要做一次连表查询才能获得。这其中的开销无疑是花费巨大的,尤其是当连接的表不仅两三张而是很多张时,有可能还会造成索引失效,这种情况带来的资源、时间开销简直是一个噩梦,这会严重地影响整个业务系统的性能。

  • 因此,也正是由于上述一些问题,在设计库表结构时,我们不一定要100%遵守范式准则。这种违反数据库范式的设计方法,就被称之为 反范式设计

  • 设计原则:无论那种范式只要能够对业务有利,那就可以称之为好的设计方案。在设计时千万不要拘泥于规则之内,一定要结合实际业务考虑,遵循业务优先的原则去设计结构。

  • 注意:不是所有不遵循数据库范式的结构设计都被称为反范式,反范式设计是指自己知道会破坏范式,但对业务带来好处大于坏处时,刻意设计出破坏范式的结构。

数据库范式设计总结

  • 经过一系列的阐述后,其实不难发现,越到后面的范式,越难令人理解,同时为了让表满足更高级别的范式,越往后付出代价也越大,而且拆分出的表数量也会越多
  • 一般项目中仅需满足到第三范式或BC范式即可,因为这个度刚刚好,再往后就会因为过于精细化设计,导致整体性能反而下降。
  • 控制到第三范式的级别,一方面数据不会有太多冗余,第二方面也不会对性能影响过大。同时,如若打破范式的设定能对业务更有利,那也可以违背范式原则去设计。
  • 生产项目中库表结构设计的是否合理,区别如下:
    • 不合理的结构设计会造成的问题:
      • 数据冗余,会浪费一定程度上的存储空间
      • 不便于常规SQL操作(例如插入、删除),甚至会出现异常
    • 合理的结构设计带来的好处:
      • 节省空间,SQL执行时能节省内存空间,数据存储时能节省磁盘空间
      • 数据划分较为合理,DB性能整体较高,并且数据也非常完整
      • 结构便于维护和进行常规SQL操作
  • 各范式之间的递进关系图:

在这里插入图片描述
范式概念:

  • 第一范式:原子性,每个字段的值不能再分。
  • 第二范式:唯一性,表内每行数据必须描述同一业务属性的数据。
  • 第三范式:独立性,表中每个非主键字段之间不能存在依赖性。
  • 巴斯范式:主键字段独立性,联合主键字段之间不能存在依赖性。
  • 第四范式:表中字段不能存在多值依赖关系。
  • 第五范式:表中字段的数据之间不能存在连接依赖关系。
  • 域键范式:试图研究出一个库表设计时的终极完美范式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/476640.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣刷题--21.合并两个有序链表

I am the best !!! 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4] 示例 2…

【java-Neo4j 5开发入门篇】-最新Java开发Neo4j

系列文章目录 前言 上一篇文章讲解了Neo4j的基本使用,本篇文章对Java操作Neo4j进行入门级别的阐述,方便读者快速上手对Neo4j的开发。 一、开发环境与代码 1.docker 部署Neo4j #这里使用docker部署Neo4j,需要镜像加速的需要自行配置 docker run --name…

三层交换机静态路由实验

1、前置知识 2、实验目的 3、实验器材: 3560-23PS交换机2台、主机4台、交叉线1根和直通网线4根。 4、实验规划及拓扑 实验要求: (1)在交换机A和交换机B上分别划分基于端口的VLAN: 交换机 VLAN 端口成员 交换机…

基于Java Springboot付费自习室管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…

深度学习笔记24_天气预测

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 一、我的环境 1.语言环境:Python 3.9 2.编译器:Pycharm 3.深度学习环境:TensorFlow 2.10.0 二、GPU设置…

node报错:Error: Cannot find module ‘express‘

报错信息: Error: Cannot find module express 分析原因: 项目中需要express工具,但是import引入不进来,说明在这个项目中我们本没有对express工具包进行install,从我们项目中的package.json也可以看到(并…

【课堂笔记】隐私计算实训营第四期:“隐语”可信隐私计算开源框架

“隐语”可信隐私计算开源框架 隐语架构一览隐语架构拆解产品层算法层PSI/PIR数据分析(Data Analysis)联邦学习(Federated Learning) 计算层混合编译调度——RayFedSPUHEUTEEUYACL 资源层KUSCIA 互联互通跨域管控 隐语架构一览 隐…

Halo 正式开源: 使用可穿戴设备进行开源健康追踪

在飞速发展的可穿戴技术领域,我们正处于一个十字路口——市场上充斥着各式时尚、功能丰富的设备,声称能够彻底改变我们对健康和健身的方式。 然而,在这些光鲜的外观和营销宣传背后,隐藏着一个令人担忧的现实:大多数这些…

Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在数字化时代,…

嵌入式中利用QT实现服务器与客户端方法

大家好,今天主要给大家分享一下,如何使用QT中TCP协议进行传输控制,它是一种面向连接的,可靠的基于字节流的传输层控制协议。 第一:Linux中网络通信简介 TCP通信必须建立TCP连接,通信端分为客户端和服务端。服务端通过监听某个端口来监听是否有客户端连接进来,如果有连接…

网络安全,文明上网(6)网安相关法律

列举 1. 《中华人民共和国网络安全法》: - 这是中国网络安全的基本法律,于2017年6月1日开始实施。该法律明确了网络运营者的安全保护义务,包括采取数据分类、重要数据备份和加密等措施。 2. 《中华人民共和国数据安全法》: …

Vscode写markdown快速插入python代码

如图当我按下快捷键CRTLSHIFTK 自动出现python代码片段 配置方法shortcuts’ 打开这个json文件 输入 {"key": "ctrlshiftk","command": "editor.action.insertSnippet","when": "editorTextFocus","args&…

【前端】第12节:Vue3新特性

引入 说起 vue3 的新特性,就会不由自主想到 vue3 和 vue2 之间的差异,例如:双向绑定、根节点数量、生命周期、this 等等,详细可以见这篇文章(参考)—— vue2和vue3的差异整理(轻松过度到vue3&a…

Linux 进程概念与进程状态

目录 1. 冯诺依曼体系结构2. 操作系统(Operator System)2.1 概念2.2 设计OS的目的2.3 系统调用和库函数概念 3. 进程概念3.1 描述进程 - PCB3.2 task_struct3.3 查看进程3.4 通过系统调用获取进程标识符PID, PPID3.5 通过系统调用创建fork 4.…

滑动窗口篇——如行云流水般的高效解法与智能之道(1)

前言: 上篇我们介绍了双指针算法,并结合具体题目进行了详细的运用讲解。本篇我们将会了解滑动窗口。滑动窗口是一种常用的算法技巧,主要用于处理子数组、子串等具有“窗口”特性的题目。柳暗花明,乃巧解复杂问题的高效之道。 一. …

网络安全-企业环境渗透2-wordpress任意文件读FFmpeg任意文件读

一、 实验名称 企业环境渗透2 二、 实验目的 【实验描述】 操作机的操作系统是kali 进入系统后默认是命令行界面 输入startx命令即可打开图形界面。 所有需要用到的信息和工具都放在了/home/Hack 目录下。 本实验的任务是通过外网的两个主机通过代理渗透到内网的两个主机。…

DB-GPT V0.6.2 版本更新:牵手libro社区、GraphRAG图谱构建能力增强等

DB-GPT V0.6.2版本现已上线,快速预览新特性: 新特性 1、DB-GPT 社区和 libro 社区共同发布 AWEL Notebook 功能 libro:灵活定制、轻松集成的 Notebook 产品方案。 社区地址:https://github.com/difizen/libro 使用教程&#xf…

GPT1.0 和 GPT2.0 的联系与区别

随着自然语言处理技术的飞速发展,OpenAI 提出的 GPT 系列模型成为了生成式预训练模型的代表。作为 GPT 系列的两代代表,GPT-1 和 GPT-2 虽然在架构上有着继承关系,但在设计理念和性能上有显著的改进。本文将从模型架构、参数规模、训练数据和…

本地部署与外部部署有何不同?

什么是本地部署? 本地部署(通常缩写为“on-prem”)是指在公司自己的设施或数据中心内托管的软件和基础设施。与基于云的解决方案不同,本地部署系统让企业对其数据、硬件和软件配置拥有完全的控制权。这种设置非常适合那些优先考虑…

游戏引擎学习第20天

解释 off-by-one 错误 从演讲者的视角:对代码问题的剖析与修复过程 问题的起因 演讲者提到,他可能无意中在代码中造成了一个错误,这与“调试时间标记索引”有关。他发现了一个逻辑问题,即在检查数组边界时,使用了“调试…