数据库表设计范式
华子目录
- 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
班级ID
和name
学生姓名两个字段作为联合主键。 - 之前的三个问题也不存在,如换班主任后只需要更改班级表,无需修改学生表中的学生信息;增加班级时,只需要在班级表中新增数据,也不会影响学生表。
- 原本的学生表则又被拆为了班级表、学生表两张,在学生表中只存储班级
-
小结:第三范式只要求非主键字段之间,不能存在依赖关系,但没要求联合主键中的字段不能存在依赖,因此第三范式并未考虑完善,巴斯-科德范式修正的就是这点,是对第三范式的补充及完善,修正了第三范式。
第四范式(4NF)
- 多值依赖:表中的字段之间存在一对多的关系,也就是一个字段的具体值会由多个字段来决定(一个表中至少需要有三个独立的字段才会出现多值依赖问题)
- 示例:
经典的业务,用户角色权限表,各字段含义:
user_name
字段 – 用户名
role
字段 – 角色信息:
USER
:普通用户角色。ADMIN
:管理员角色。ROOT
:超级管理员角色。
permission
字段 – 权限信息:
*
:超级管理员拥有的权限级别,*
表示所有。BACKSTAGE
:管理员拥有的权限级别,表示可以操作后台。LOGIN
:普通用户拥有的权限级别,表示可以登录访问平台。
-
此时假设我们需要新增一条数据,那表中的权限字段究竟填什么?这个值是需要依赖多个字段决定的,权限来自于角色,而角色则来自于用户。也就是说,一个用户可以拥有多个角色,同时一个角色可以拥有多个权限,所以此时咱们无法单独根据用户名去确定权限值,权限值必须依赖用户、角色两个字段来决定,这种一个字段的值取决于多个字段才能确定的情况,就被称为多值依赖。
-
因此第四范式的定义就是要消除表中的多值依赖关系,上述表格拆分为:
- 观察上述的五张表正是大名鼎鼎的权限五表,将原本的用户角色权限表,拆分成了用户表、角色表、权限表、用户角色关系表、角色权限关系表。
- 经过这次拆分之后,一方面用户表、角色表、权限表中都不会有数据冗余,第二方面无论是要删除亦或新增一个角色、权限时,都不会影响其他表。后面的两张关系表,主要是为了维护用户、角色、权限三者之间的关系。
第五范式(5NF)/完美范式
-
定义:建立在
4NF
的基础上,进一步消除表中的连接依赖,直到表中的连接依赖都是主键所蕴含的 -
第五范式解决的是无损连接问题,基本没有实际意义,了解即可,因为无损连接很少出现,而且难以察觉
第六范式(6NF)/域键范式
- 域键范式,也被称之为终极范式,但目前也仅有学术机构在研究,在生产环境中实际的用途也不大
反范式
-
概念:不遵循数据库范式设计的结构,就被称为反范式结构。
-
遵循数据库范式设计优点如下:
- 避免了大量的数据冗余
- 节省了大量存储空间
- 表整体结构更为优雅,能让
SQL
操作更加便捷且减少出错。
-
但随着范式的级别越高,设计出的结构会更加精细化,原本一张表的数据会被分摊到多张表中存储,表的数量随之越来越多。会存在一个致命问题,也就是当同时需要这些数据时,只能采用联表查询的形式检索数据,有时候甚至为了一个字段的数据,也需要做一次连表查询才能获得。这其中的开销无疑是花费巨大的,尤其是当连接的表不仅两三张而是很多张时,有可能还会造成索引失效,这种情况带来的资源、时间开销简直是一个噩梦,这会严重地影响整个业务系统的性能。
-
因此,也正是由于上述一些问题,在设计库表结构时,我们不一定要
100%
遵守范式准则。这种违反数据库范式的设计方法,就被称之为 反范式设计。 -
设计原则:无论那种范式只要能够对业务有利,那就可以称之为好的设计方案。在设计时千万不要拘泥于规则之内,一定要结合实际业务考虑,遵循业务优先的原则去设计结构。
-
注意:不是所有不遵循数据库范式的结构设计都被称为反范式,反范式设计是指自己知道会破坏范式,但对业务带来好处大于坏处时,刻意设计出破坏范式的结构。
数据库范式设计总结
- 经过一系列的阐述后,其实不难发现,越到后面的范式,越难令人理解,同时为了让表满足更高级别的范式,越往后付出代价也越大,而且拆分出的表数量也会越多
- 一般项目中仅需满足到第三范式或
BC
范式即可,因为这个度刚刚好,再往后就会因为过于精细化设计,导致整体性能反而下降。 - 控制到第三范式的级别,一方面数据不会有太多冗余,第二方面也不会对性能影响过大。同时,如若打破范式的设定能对业务更有利,那也可以违背范式原则去设计。
- 生产项目中库表结构设计的是否合理,区别如下:
- 不合理的结构设计会造成的问题:
- 数据冗余,会浪费一定程度上的存储空间
- 不便于常规
SQL
操作(例如插入、删除),甚至会出现异常
- 合理的结构设计带来的好处:
- 节省空间,
SQL
执行时能节省内存空间,数据存储时能节省磁盘空间 - 数据划分较为合理,
DB
性能整体较高,并且数据也非常完整 - 结构便于维护和进行常规
SQL
操作
- 节省空间,
- 不合理的结构设计会造成的问题:
- 各范式之间的递进关系图:
范式概念:
- 第一范式:原子性,每个字段的值不能再分。
- 第二范式:唯一性,表内每行数据必须描述同一业务属性的数据。
- 第三范式:独立性,表中每个非主键字段之间不能存在依赖性。
- 巴斯范式:主键字段独立性,联合主键字段之间不能存在依赖性。
- 第四范式:表中字段不能存在多值依赖关系。
- 第五范式:表中字段的数据之间不能存在连接依赖关系。
- 域键范式:试图研究出一个库表设计时的终极完美范式。
相关文章:

数据库表设计范式
华子目录 MYSQL库表设计:范式第一范式(1NF)第二范式(2NF)第三范式(3NF)三范式小结巴斯-科德范式(BCNF)第四范式(4NF)第五范式(5NF&…...
经济增长初步
1.人均产出 人均产出,通常指的是一个国家、地区或组织在一定时期内,每个劳动人口平均创造的生产总值。它是衡量一个地区或国家经济效率和劳动生产率的重要指标。具体来说,人均产出可以通过以下公式计算: 人均产出总产出/劳动人口…...

【架构】主流企业架构Zachman、ToGAF、FEA、DoDAF介绍
文章目录 前言一、Zachman架构二、ToGAF架构三、FEA架构四、DoDAF 前言 企业架构(Enterprise Architecture,EA)是指企业在信息技术和业务流程方面的整体设计和规划。 最近接触到“企业架构”这个概念,转念一想必定和我们软件架构…...

时间请求参数、响应
(7)时间请求参数 1.默认格式转换 控制器 RequestMapping("/commonDate") ResponseBody public String commonDate(Date date){System.out.println("默认格式时间参数 date > "date);return "{module : commonDate}"; }…...

PyTorch图像预处理:计算均值和方差以实现标准化
在深度学习中,图像数据的预处理是一个关键步骤,它直接影响模型的训练效果和收敛速度。PyTorch提供的transforms.Normalize()函数允许我们对图像数据进行标准化处理,即减去均值并除以方差。这一步骤对于提高模型性能至关重要。 为什么需要标准…...

slice介绍slice查看器
Android Jetpack架构组件(十)之Slices - 阅读清单 - 腾讯云开发者社区-腾讯云 slice 查看器apk 用adb intall 安装 Releases android/user-interface-samples GitHubMultiple samples showing the best practices in the user interface on Android. - Releases android/u…...

Android音频采集
在 Android 开发领域,音频采集是一项非常重要且有趣的功能。它为各种应用程序,如语音聊天、音频录制、多媒体内容创作等提供了基础支持。今天我们就来深入探讨一下 Android 音频采集的两大类型:Mic 音频采集和系统音频采集。 1. Mic音频采集…...

通过轻易云平台实现聚水潭数据高效集成到MySQL的技术方案
聚水潭数据集成到MySQL的技术案例分享 在本次技术案例中,我们将详细探讨如何通过轻易云数据集成平台,将聚水潭的数据高效、可靠地集成到MySQL数据库中。具体方案为“聚水谭-店铺查询单-->BI斯莱蒙-店铺表”。这一过程不仅需要处理大量数据的快速写入…...

类和对象( 中 【补充】)
目录 一 . 赋值运算符重载 1.1 运算符重载 1.2 赋值运算符重载 1.3 日期类实现 1.3.1 比较日期的大小 : 1.3.2 日期天数 : 1.3.3 日期 - 天数 : 1.3.4 前置/后置 1.3.5 日期 - 日期 1.3.6 流插入 << 和 流提取 >> 二 . 取地址运算符重载 2.1 const…...

如何使用gpio模拟mdio通信?
一、前言 实际项目开发中,由于设计原因,会将phy的mdio引脚连接到SoC的2个空闲gpio上, 这样就无法通过Gmac自有的架构实现修改phy, 因此只能通过GPIO模拟的方式实现MDIO, 好在Linux支持MDIO via GPIO功能。 该功能…...

C# 中的事件和委托:构建响应式应用程序
C#中的事件和委托。事件和委托是C#中用于实现观察者模式和异步回调的重要机制,它们在构建响应式和交互式应用程序中发挥着重要作用。以下是一篇关于C#中事件和委托的文章。 引言 事件和委托是C#语言中非常重要的特性,它们允许你实现观察者模式和异步回…...

科技赋能健康:多商户Java版商城系统引领亚健康服务数字化变革
在当今社会,随着生活节奏的加快和工作压力的增大,越来越多的人处于亚健康状态。据《The Lancet》期刊2023年的统计数据显示,全球亚健康状态的人群比例已高达82.8%,这一数字背后,隐藏着巨大的健康风险和社会成本。亚健康…...

区块链网络示意图;Aura共识和Grandpa共识(BFT共识)
目录 区块链网络示意图 Aura共识和Grandpa共识(BFT共识) Aura共识 Grandpa共识(BFT共识) Aura与Grandpa的结合 区块链网络示意图 CP Blockchain:这是中央处理区块链(或可能指某种特定的处理单元区块链)的缩写。它可能代表了该区块链网络的主要处理或存储单元。在这…...

Javaweb梳理18——JavaScript
今日目标 掌握 JavaScript 的基础语法掌握 JavaScript 的常用对象(Array、String)能根据需求灵活运用定时器及通过 js 代码进行页面跳转能通过DOM 对象对标签进行常规操作掌握常用的事件能独立完成表单校验案例 18.1 JavaScript简介 JavaScript 是一门跨…...

面向对象-接口的使用
1. 接口的概述 为什么有接口? 借口是一种规则,对于继承而言,部分子类之间有共同的方法,为了约束方法的使用,使用接口。 接口的应用: 接口不是一类事物,它是对行为的抽象。 2. 接口的定义和使…...

失落的Apache JDBM(Java Database Management)
简介 Apache JDBM(Java Database Management)是一个轻量级的、基于 Java 的嵌入式数据库管理系统。它主要用于在 Java 应用程序中存储和管理数据。这个项目已经过时了,只是发表一下以示纪念,现在已经大多数被SQLite和Derby代替。…...

Vue3+SpringBoot3+Sa-Token+Redis+mysql8通用权限系统
sa-token支持分布式token 前后端代码,地球号: bright12389...

MySQL 三大日志详解
在 MySQL 数据库中,binlog(二进制日志)、redo log(重做日志)和 undo log(回滚日志)起着至关重要的作用。它们共同保障了数据库的高可用性、数据一致性和事务的可靠性。下面将对这三大日志进行详…...

Java 岗面试八股文及答案整理(2024最新版)
春招,秋招,社招,我们 Java 程序员的面试之路,是挺难的,过了 HR,还得被技术面,小刀在去各个厂面试的时候,经常是通宵睡不着觉,头发都脱了一大把,还好最终侥幸能…...

Web3.0安全开发实践:Clarity最佳实践总结
在过去的一段时间里,CertiK团队对比特币生态系统及其发展进行了深入研究。同时,团队还审计了多个比特币项目以及基于不同编程语言的智能合约,包括OKX的BRC-20钱包和MVC DAO的sCrypt智能合约实现。 现在,我们的研究重点转向了Clar…...

基于Springboot+Vue动漫推荐平台管理系统(源码+lw+讲解部署+PPT)
前言 详细视频演示 论文参考 系统介绍 系统概述 核心功能 用户角色与功能 具体实现截图 1. 热门动漫功能 2. 文章专栏功能 3. 会员分享功能 4. 热门动漫管理功能(管理员端) 5. 动漫分类管理功能 技术栈 后端框架SpringBoot 前端框架Vue …...

秋意浓,森林披金装
秋意浓,森林披金装, 枫叶如火,漫山遍野狂。 松间轻风送寒意, 鸟鸣悠扬入云翔。 林间小径蜿蜒行, 落叶铺成金色毯。 溪水潺潺绕石转, 映出天边一抹霞。 野菊点缀在草间, 白云悠悠随意闲。…...

Chrome离线安装包下载
1、问Chrome的官网:https://www.google.cn/chrome/ 直接下载的是在线安装包,安装需要联网。 2、如果需要在无法联网的设备上安装Chrome,需要在上面的地址后面加上?standalone1。 Chrome离线安装包下载地址:https://www.google.c…...

安卓手机5G网络频繁掉4G 问题解决 手机5G网络优化方案
问题环境 在某个长期停留的位置(例如:躺平)使用手机时网络突然从5G跳到4G,偶尔跳来跳去导致网络体验很差,经过调整5G网络情况下网速及其他体验都要更好,基于这样的情况使用一种简单的操作,锁定5…...

使用LLaMA-Factory微调时的问题与解决方案记录
文章目录 如何指定微调使用的显卡如何解决显卡通信导致的报错模型微调的实际epoch和step如何计算如何实现多卡全量微调模型微调后的结果如何查看模型测试后的指标如何理解如何指定微调使用的显卡 启动网页时使用这种执行命令 CUDA_VISIBLE_DEVICES=5,6,7 llamafactory-cli we…...

Go语言switch语句
在Go语言中,switch,是一个高度灵活,其功能强大的控制结构,相比较Java中的switch,更受到语言重视。 目录 1.基础用法2.多值匹配3.不指定表达式的 switch4.使用 fallthrough 强制进入下一个分支5.使用类型断言的 switch…...

JavaScript DOM使用
DOM Document Object Model 简单而言,就是JavaScript将HTML文档的各个组成部分封装为对象。 封装的对象分别为: Document:整个HTML的文档对象 Element:元素对象(也就是HTML中的标签) Attribute:…...

人工智能|计算机视觉——微表情识别(Micro expression recognition)的研究现状
一、简述 微表情是一种特殊的面部表情,与普通的表情相比,微表情主要有以下特点: 持续时间短,通常只有1/25s~1/3s;动作强度低,难以察觉;在无意识状态下产生,通常难以掩饰或伪装;对微表情的分析通常需要在视频中,而普通表情在图像中就可以分析。由于微表情在无意识状态…...

耿恭坚守城池的方法
疏勒城之战中,耿恭坚守城池的方法主要有以下几点: 选择有利地势:耿恭深知疏勒城依山傍水、地势险要,易守难攻,于是果断放弃金满城,移师至疏勒城据守,为长期坚守创造了良好的地理条件.运用心理战…...

小兔鲜项目总结——项目亮点
目录 1、基于业务的逻辑组件拆分思想2、长页面吸顶交互的实现3、自定义图片懒加载指令并封装为插件4、画板插槽组件等业务通用组件封装5、通用逻辑函数的封装6、列表无限加载7、路由缓存问题的处理 小兔鲜项目其实在暑假之前就已经做完了,但是一直没有空做总结&…...