数据库表的设计——范式
目录
1. 设计数据表需要注意的点
2. 范式
2.1 范式简介
2.2 范式有哪些?
2.3 第一范式(1NF)
2.4 第二范式(2NF)
2.5 第三范式(3NF)
2.6 小结
1. 设计数据表需要注意的点
(1)首先要考虑设计这张表的用途,这张表都要存放什么数据;
(2)还要保证数据表中数据的正确性,在进行插入,删除,更新时应该做出哪些约束检查;
(3)要考虑如何降低数据表的数据冗余度,可以允许数据量变大,但要考虑数据量不会因为急速增长;
(4)在设计时还要考虑日后的数据维护问题,不能使表中的数据维护工作复杂;
2. 范式
2.1 范式简介
范式的英文名称位 Normal Form,简称NF。在关系型数据库中,关于数据表设计的基本原则,规则称之为范式。
可以简单的理解为,一张数据表的设计结构需要满足某种设计标准的级别,满足某种规则。
2.2 范式有哪些?
目前关系型数据库的范式一共有6种,按照范式的级别,从低到高分别是 第一范式(1NF),第二范式(2NF),第三范式(3NF),巴斯-科德范式(BCNF),第四范式(4NF),第五范式(5NF)。

范式的阶层越高,数据的冗余度越低,但要求也会越来越严格,高范式都是在低范式的基础上推导出来的,所以高范式一定满足低范式的规范要求。
但在绝大多数企业设计数据表的时候,一般遵循到3NF,有些更为严格的表会设计到BCNF,不仅如此,有些时候,我们还会根据业务需要破坏范式要求,适当增加表的冗余度来提高查询的性能,这就是理论和实践结合的使用。
2.3 第一范式(1NF)
第一范式主要是确保数据表中每个字段都具有原子性,每个字段都不可再进行拆分的最小单元,像下面这种情况就违背了第一范式,address 可以拆分为省和市,除非说你的业务中只会用到查询整个地址的业务,不会用到细粒度的地址查询功能,可以这样设计,但还是建议拆分成两个,如果有需要可以在代码层再进行拼接。

下面就是正确的表字段,将原来的 address 拆分为 province 和 city,每个字段都是最小字段,不可再拆分,满足了第一范式的要求。

2.4 第二范式(2NF)
第二范式要求,在满足第一范式的基础上,还要满足数据表中的每一条数据记录都是可唯一标识的。而且所有的非主键字段,都须完全依赖于主键,不能只依赖于主键的一部分。如果知道了主键的值,就能检索到任意一行的任意一个具体字段的值。
如下,sid 表示学生编号,cid 表示课程编号,grades 表示课程成绩;
在这个数据表中,想要查询到成绩,必须知道学生号和课程号才能查询的得到,一个学生会有多科成绩。

如果只知道学生号,将查询到多条数据;
如果只知道课程号,将查询到所有同学当前课程的成绩;
只有学生号和课程号都确定,才能查找到一条唯一的成绩记录;
所以 (学号,课程)——>成绩,学号和课程虽然是两个字段,但都是主键。
我们再来看一个反例
比赛表 player_game 中,包含球员id,比赛id,球员姓名,球员年龄,比赛时间,比赛地点,比赛分数,
但是细细分析会发现,name,age跟球员具有强关联;time,address跟比赛具有强关联;score 跟球员id和比赛id都有关联,但是现在放在了一张表中,是不合理的,所以这种表的设计都是垃圾表。

正确的做法是将上面的一张表拆分为3张表,分别是球员信息表,比赛信息表,球员得分表。
球员信息表,球员id为主键,通过球员id可以查询到详细的球员信息

比赛信息表,比赛id为主键,通过比赛id可以查询到比赛的具体信息

球员得分表,球员id和比赛id为联合主键,通过球员id和比赛id可以查询到某位球员在某场比赛的得分

2.5 第三范式(3NF)
第三范式是在第二范式的基础上,确保数据表中每一个非主键字段都和主键字段注解相关,所有的非主键字段不能依赖与其他的非主键,不能存在依赖传递。
比如说一张表现有三个字段 A,B,C,且A是主键,我要查询C,应当通过主键A直接就可以查询到C。不能先通过A查询B,再经过B才能查出C,如果是这样就出现了依赖传递,不符合第三范式的要求。
如下设计一张关于商品的数据库表,可以看到,通过非主键字段商品类别id category_id 可以确定商品类别名称,通过商品主键id 也可以确定商品类别名称,中间具有传递性,不满足第三范式的要求也,商品类别名称这个字段在这张表中属于冗余字段。

正确做法应该把商品类别id 和商品部类别名称单独放在另外一张表中

然后把商品类别id 作为商品表的一个外键,如果想要查询商品的分类名称,再通过外键去另一张表中查询即可。

2.6 小结
从上面对一二三范式的简单可以得出,第一范式确保每列的原子性,第二范式确保每列和主键完全依赖,第三范式确保每列和主键直接关联而非间接关联。
范式的优点:有助于消除数据库的数据冗余,第三范式通常认为在性能,扩展性,数据完整性方面达到了最好的平衡。
范式的缺点:降低了查询效率,其实同学们可以看出,范式的等级越高,拆分出来的表越多,而多表查询在数据库层面是一个比较耗时的操作,直接影响到了我们的业务吞吐能力,因此在实际设计数据表的时候,我们有时候会为了达到一种平衡违反第三范式来追求业务的性能,但第一范式和第二范式都是几乎会遵守的。
有些时候,我们会违反第三范式的要求,将一部分数据放在一张表中,虽然会有一定的冗余,但是能减少多表查询次数,提高了数据的查询效率,增大了业务吞吐能力,这就是我们常说的牺牲空间换时间。对于用户而言,最不喜欢的就是等待,只要能最快速度的响应用户请求,就是一个好的业务功能设计。
因此,在实际设计数据表的时候,我们需要根据业务需求而定,如果是一个查询加我而频繁的业务,可以适当违反范式要求,如果是一个增删改比较频繁的业务,可以适当增大范式规范,提高修改数据的效率。
相关文章:
数据库表的设计——范式
目录 1. 设计数据表需要注意的点 2. 范式 2.1 范式简介 2.2 范式有哪些? 2.3 第一范式(1NF) 2.4 第二范式(2NF) 2.5 第三范式(3NF) 2.6 小结 1. 设计数据表需要注意的点 (1)首先要考虑设计这张表的用途,这张表都要存放什…...
Brute Force
Brute Force "Brute Force"(暴力破解)指的是一种通过尝试所有可能的组合来获取访问、解密或破解信息的攻击方法。这种攻击方法通常是基于暴力和不断尝试的,不依赖漏洞或弱点。通常用于破解密码、破坏系统或获取未经授权的访问权限…...
HTML简单介绍
且视他人之疑目如盏盏鬼火,大胆地去你的夜路。 目录 1.网页 2.Web标准 3.HTML 3.1HTML结构 3.2HTML标签编辑 4.标签介绍 4.1排版标签 4.2文本格式化标签 4.3媒体标签 4.3.1图片标签 4.3.2 音频标签 4.3.3视频标签 5.相对路径 6.链接标签 6.1target属…...
【Java笔试强训】Day10(CM62 井字棋、HJ87 密码强度等级)
CM62 井字棋 链接:井字棋 题目: 给定一个二维数组board,代表棋盘,其中元素为1的代表是当前玩家的棋子,0表示没有棋子,-1代表是对方玩家的棋子。当一方棋子在横竖斜方向上有连成排的及获胜(及…...
C语言求数组中出现次数最多的元素
一、前言 遇到一个需求,需要求数组中出现次数最多的元素,查找了一些资料,结合自己的思路,编写了程序并验证。 只考虑元素为非负整数的数组,如果有出现次数相同的元素,则返回较小元素。 二、编程思路 以数…...
【Python Opencv】Opencv画图形
文章目录 前言一、画图形1.1 画线1.2 画矩形1.3 画圆1.4 画椭圆1.5 添加文本 总结 前言 在计算机视觉和图像处理中,OpenCV不仅可以处理图像和视频,还提供了一组功能强大的工具,用于在图像上绘制各种形状和图形。这些功能使得我们能够在图像上…...
了解防抖和节流:提升前端交互体验的实用策略
了解防抖和节流:提升前端交互体验的实用策略 前言什么是防抖?什么是节流?应用实例防抖实例节流实例 前言 本文将重点介绍前端性能优化方法之一的防抖和节流。首先解释了它们的概念和原理,然后探讨了它们在前端开发中的应用场景&a…...
SQL学习之增删改查
文章目录 数据库数据类型建表create table插入数据insert into查询数据select from修改数据update set删除数据delete from备份ctas结果插入iis截断表 truncate table修改表结构alter table添加注释 注:本文的SQL语法是基于Oracle数据库操作的,但是基本的…...
Ansible角色定制实例
目录 角色定制:roles 角色定制实例:利用角色部署wordpress 1.在roles目录下生成对应的目录结构 2.定义配置文件 ①nginx ②php ③mysql ④定义剧本文件 ⑤启动服务 角色定制:roles 对于普通的剧本(playbook)有…...
ElastaticSearch--- es多字段聚合
在使用es时,我们经常会用到聚合查询。 简单的聚合查询,已经在前面介绍过,详情见: https://www.cnblogs.com/expiator/p/13843969.html 有时,也会用到多字段聚合查询。类似于Mysql的Group By多个字段。 比如…...
本周Github有趣开源项目:Rspress等6个
Github有趣的项目、工具和库: 1、sshx 一个基于 Web 的安全协作终端。通过网络进行快速、协作的实时终端共享 特征: 运行一个命令即可与任何人共享您的终端。 在无限画布上调整大小、移动窗口以及自由缩放和平移。 查看其他人的光标实时移动。 连接到…...
【华为OD题库-016】字符串摘要-Java
题目 给定一个字符串的摘要算法,请输出给定字符串的摘要值 1、去除字符串中非字母的符号 2、如果出现连续字符(不区分大小写),则输出:该字符(小)+连续出现的次数 3、如果是非连续的宁符(不区分大小写),则输出:该字符(小写)该字母之…...
生成式AI - Knowledge Graph Prompting:一种基于大模型的多文档问答方法
大型语言模型(LLM)已经彻底改变了自然语言处理(NLP)任务。它们改变了我们与文本数据交互和处理的方式。这些强大的AI模型,如OpenAI的GPT-4,改变了理解、生成人类类似文本的方式,导致各种行业出现…...
深度学习AIR-PolSAR-Seg图像数据预处理
文章目录 深度学习sar图像数据预处理一.图片预处理操作1.log(1x)处理2.sqrt平方化处理 二.原网络训练效果展示原始数据训练效果展示: 三.对比实验1.采用原始数据2.采用取log(1x)后的数据3.采用取平方后归一化处理: 四.总结:五.思考 深度学习s…...
求最大公约数math.gcd()
【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 求最大公约数 math.gcd() [太阳]选择题 下列代码执行输出的结果是? import math print("【执行】print(math.gcd(6, 8))") print(math.gcd(6, 8)) print(&quo…...
数据结构之队列
目录 引言 队列的概念与结构 队列的实现 定义 初始化 销毁 入队 判断队列是否为空 出队 获取队头元素 获取队尾元素 检测队列中有效元素个数 元素访问 源代码 queue.h queue.c test.c 引言 数据结构之路经过栈后,就来到了与栈联系紧密的兄弟—…...
MySQL数据库——存储过程-循环(while、repeat、loop)
目录 while 介绍 案例 repeat 介绍 案例 loop 介绍 案例一 案例二 while 介绍 while 循环是有条件的循环控制语句。满足条件后,再执行循环体中的SQL语句。具体语法为: -- 先判定条件,如果条件为true,则执行逻辑&#…...
Django路由
路由系统 1.Django1中的路由1.1 普通形式1.2 分组1.2.1 无名分组1.2.2 有名分组 2. Django2版本2.1 传统的路由2.2 正则表达式路由 3. 路由分发3.1 include(一般使用此方式做路由分发)3.2 手动分发 4. name别名及使用name的反向URL生成4.1 一般情况下的别名使用及反向生成4.2 分…...
头歌实践平台-数据结构-二叉树及其应用
第1关:实现二叉树的创建 #include "binary_tree.h"BiTreeNode* CreatBiTree(char* s, int &i, int len) // 利用先序遍历创建二叉树 // 参数:先序遍历字符串s,字符串初始下标i0,字符串长度len。 // 返回࿱…...
2023.11.11通过html内置“required-star“添加一个红色的星号来表示必填项
2023.11.11通过html内置"required-star"添加一个红色的星号来表示必填项 在HTML中,可以使用标签来为元素添加说明。同时可以通过添加一个红色的星号来表示必填项。 <!DOCTYPE html> <html lang"en"> <head><meta charse…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
