当前位置: 首页 > news >正文

数据库表的设计——范式

目录

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多个字段。 比如&#xf…...

本周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。 // 返回&#xff1…...

2023.11.11通过html内置“required-star“添加一个红色的星号来表示必填项

2023.11.11通过html内置"required-star"添加一个红色的星号来表示必填项 在HTML中&#xff0c;可以使用标签来为元素添加说明。同时可以通过添加一个红色的星号来表示必填项。 <!DOCTYPE html> <html lang"en"> <head><meta charse…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

GitHub 趋势日报 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

【SpringBoot自动化部署】

SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一&#xff0c;能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时&#xff0c;需要添加Git仓库地址和凭证&#xff0c;设置构建触发器&#xff08;如GitHub…...

微服务通信安全:深入解析mTLS的原理与实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言&#xff1a;微服务时代的通信安全挑战 随着云原生和微服务架构的普及&#xff0c;服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...