MySQL范式和反范式

范式

是用一组规则定义的数据库设计标准,旨在确保数据库结构合理,避免数据冗余和异常。

目的

  • 消除数据的重复,提高存储效率
  • 防止数据异常(插入、删除、更新异常)
  • 提高数据的完整性和一致性

第一范式

  • 定义
    • 所有列(字段)必须是原子性的(不可拆分的基本数据单位)
    • 表中的每个字段都应包含原子值,不能存储集合、数组等多值数据
  • 要求
    • 每个字段只存储单一值,无重复列
    • 每一行是唯一的(通常用主键)

举例:

  • 不符合1NF:一列存多个电话号码,用逗号分隔
    • 比如: 一个“电话号码”字段存着“13812345678,13987654321”两个号码(多个值在一列)
  • 符合1NF:用多个字段存放各个电话号码,或用一行存一个电话

第二范式

  • 定义
    • 在1NF基础上,消除表中的部分依赖(部分依赖是指非主键列依赖于主键的一部分)
  • 要求
    • 所有非主键列必须完全依赖于整个主键(对于复合主键)

举例:

  • 表:订单明细(order_id, product_id, product_name)
  • 关键点:
    • 如果主键是(order_id, product_id)
    • product_name 依赖product_id,不是整个主键 → 不符合2NF
    • 解决方案:将product_name单独放到产品表

第三范式

  • 定义
    • 在2NF基础上,消除非主键列之间的传递依赖
  • 要求
    • 所有非主键列都必须直接依赖于主键,不依赖于其他非主键列

举例:

  • 表:员工(员工ID,部门ID,部门名称)
    • 依赖关系:
      • 部门名称依赖于部门ID
      • 部门ID依赖于员工ID
      • 由于部门名称依赖于部门ID(非主键),这是传递依赖,不符合3NF
      • 解决方案:将部门信息单独拆分到新表

更高阶的范式

  • BCNF(Boyce-Codd Normal Form):比3NF更严格,要求每个决定因素都是超键
  • 4NF、5NF:更复杂,涉及多值依赖和连接依赖,较少在日常开发中应用

如何进行判断依赖和主键

判断依赖

    1. 依赖关系的基本概念
    • 依赖:某个字段(或多个字段)值的确定依赖于另一个字段(或多个字段)
  • 简述:
    • 如果字段B的值都是由字段A的值唯一决定的,称为“B依赖A”
    • 记作:A → B
    1. 如何识别依赖关系?
    • 分析业务逻辑:理解数据的实际关系
    • 观察数据的函数关系:
    • 比如:
      • 一个“订单ID”决定了“订单日期” → 订单ID → 订单日期
      • 某个“学生ID”决定“学生姓名” → 学生ID → 姓名
  • 借助示意图:
    • 可以画出依赖关系图(如:箭头指向依赖方)
订单ID订单日期客户ID客户名
  • 依赖关系:
    • 订单ID → 订单日期
    • 客户ID → 客户名
  • 推断:
    • 订单ID决定订单日期
    • 客户ID决定客户名

判断主键

  • 观察每一列(字段):
    • 哪个字段的值在整个表中是唯一的?(比如:身份证号、学号、订单编号)
  • 组合判断:
    • 如果单个字段不能唯一标识一条记录,就考虑多个字段结合
    • 比如:
    • “订单ID”唯一 → 订单ID就是主键
    • 但:
      • “订单ID + 商品ID”,这个组合也能唯一标识一条订单中的商品项
  • 实际操作:
    • 查看每个字段的值,识别唯一性
    • 使用数据库设计工具或SQL语句:
select count(distinct 某字段) from 表名;
  • 如果结果等于总记录数,说明该字段唯一。
  • 当单一字段不能唯一标识行时,用多个字段组合作为主键
    • 如:
    • 学生-课程关联表:学生ID + 课程ID
    • 判断依据:联合唯一性

总结

事项方法举例
依赖关系分析业务逻辑或观察数据中的“唯一决定关系”订单ID → 订单日期
确定主键查看哪些字段的值在表中唯一订单ID是唯一则单字段主键
组合主键多个字段合成唯一标识学生ID + 课程ID组成主键

示例

学生ID课程ID课程名教师名
1101数学老师A
2102语文老师B
1102语文老师B
  • 满足1NF:每个字段都是单一值

  • 是否满足2NF?

    • 主键可能是(学生ID + 课程ID)
    • 课程名和教师名只依赖课程ID,不是整个复合主键 → 不满足2NF。
    • 解决:拆两张表——
      • 学生选课表:学生ID,课程ID
      • 课程表:课程ID,课程名,教师名
  • 是否满足3NF?

    • 课程表只有课程相关信息,没有传递依赖。

示例2
在这里插入图片描述

在这里插入图片描述

反范式

:为了提高查询速度或简化复杂查询,有意将部分冗余数据引入设计,放宽或取消范式规范。

目的

  • 目标:
    • 减少多表连接(JOIN)操作
    • 提升读取性能,尤其在大数据量和高并发场景
    • 简化应用层的数据访问逻辑

何时采用反范式

  • 查询频繁涉及复杂多表JOIN,影响性能
  • 读操作远多于写操作(写入时维护冗余数据带来额外成本)
  • 实时性要求高,不能接受延迟
  • 业务场景对数据一致性要求相对较低(允许一定的冗余和同步)

例子:

  • 不反范式(正常化设计):
    • 查询订单和订单详情需要多表JOIN
    • 代码中拼接复杂SQL,逻辑繁琐
  • 采用反范式:
    • 将订单详情部分数据直接存储在订单表里
    • 查询只需访问一张表,逻辑简单,代码清晰

常见方式

  • 将关联的表合并成一张表,避免JOIN操作
  • 在主表中添加冗余字段,如冗余姓名、类别等
  • 复制部分数据到不同的表中,方便快速查询

风险与管理

  • 数据不一致:冗余数据不同步可能导致数据差异
    • 数据不一致主要是因为冗余数据在多个位置存储后,没有保持同步,导致各个副本或字段中的信息出现差异。

为什么会导致数据不一致?

    1. 缺少同步机制
    • 在反范式设计中,冗余数据通常存储在多个表或位置。
    • 如果没有有效的同步策略(如触发器、业务逻辑或应用程序控制同步),在数据变更时,某些冗余字段没有及时更新。
    1. 写操作不完整或遗漏
    • 更新、删除、插入操作中,某些地方的冗余数据没有一起更新。
    • 例如:更新订单状态时,只更改订单表中的状态字段,但未同步更新订单的详细视图或历史记录。
    1. 并发修改造成的冲突
    • 多个事务同时修改不同副本,可能导致不同步或出现“最后写入”覆盖的问题。
    1. 缺少约束或触发器
    • 没有设置约束(如触发器、外键关系)来保证冗余字段在数据变更时自动同步。
    1. 业务逻辑缺陷
    • 业务程序未考虑数据同步问题,导致不同的数据源或存储之间数据不同。
  • 维护成本增加:更新时需要同步多份数据

  • 设计复杂度:需要额外的代码逻辑保证数据一致性

因此,反范式应谨慎使用,只在确有性能瓶颈或特殊需求时采用

实际应用

  • 应用建议:
    • 在设计数据库时,遵循至少3NF,可以最大程度降低数据冗余和异常
    • 但也会带来更多的表,查询可能变复杂,性能可能降低
    • 常用过程中会在范式和性能之间做权衡(有时会适当范式反范,即反范式化)

总结

范式目的核心原则典型表现
1NF原子性每个字段只存基本值没有多值字段
2NF消除部分依赖非主键都依赖整个主键对复合主键特别重要
3NF消除传递依赖非主键不依赖于其他非主键避免冗余存储冗余数据
反范式动机典型做法潜在问题
反范式提升性能,简化查询添加冗余字段、合并表可能导致数据不一致
  • 范式是符合某一种级别的关系模式的集合。构造数据库必须遵循一定的规则。在关系数据库中,这种规则就是范式

    • 范式优点:减少了数据冗余,数据表更新操作快、占用存储空间少
    • 范式缺点:查询时通常需要多表关联查询,更难进行索引优化
  • 反范式的过程就是通过冗余数据来提高查询性能,但冗余数据会牺牲数据一致性

    • 反范式优点:所有的数据都在同一张表中,可以减少表关联,更好进行索引优化
    • 反范式缺点:存在大量冗余数据,数据维护成本更高

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

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

相关文章

编程技能:格式化打印04,sprintf

专栏导航 本节文章分别属于《Win32 学习笔记》和《MFC 学习笔记》两个专栏,故划分为两个专栏导航。读者可以自行选择前往哪个专栏。 (一)WIn32 专栏导航 上一篇:编程技能:格式化打印03,printf 回到目录…

JavaScript性能优化实战:深入探讨JavaScript性能瓶颈与优化技巧

引言:为什么JavaScript性能至关重要 在现代Web开发中,JavaScript已成为构建交互式应用程序的核心技术。随着单页应用(SPA)和复杂前端架构的普及,JavaScript代码的性能直接影响用户体验、转化率甚至搜索引擎排名。研究表明,页面加载时间每增加1秒,转化率可能下降7%,而性能…

Java数据结构——八大排序

排序 插⼊排序希尔排序直接选择排序堆排序冒泡排序快速排序归并排序计数排序 排序的概念 排序:就是将一串东西,按照要求进行排序,按照递增或递减排序起来 稳定性:就是比如排序中有两个相同的数,如果排序后&#xff0c…

WPF响应式UI的基础:INotifyPropertyChanged

INotifyPropertyChanged 1 实现基础接口2 CallerMemberName优化3 数据更新触发策略4 高级应用技巧4.1 表达式树优化4.2 性能优化模式4.3 跨平台兼容实现 5 常见错误排查 在WPF的MVVM架构中, INotifyPropertyChanged是实现数据驱动界面的核心机制。本章将深入解析属…

低空城市场景下的多无人机任务规划与动态协调!CoordField:无人机任务分配的智能协调场

作者:Tengchao Zhang 1 ^{1} 1 , Yonglin Tian 2 ^{2} 2 , Fei Lin 1 ^{1} 1, Jun Huang 1 ^{1} 1, Patrik P. Sli 3 ^{3} 3, Rui Qin 2 , 4 ^{2,4} 2,4, and Fei-Yue Wang 5 , 1 ^{5,1} 5,1单位: 1 ^{1} 1澳门科技大学创新工程学院工程科学系&#xff0…

解决Java项目NoProviderFoundException报错

前言 在Java开发中,jakarta.validation.NoProviderFoundException 是一个令人困惑的运行时错误,常因校验框架依赖缺失或版本冲突导致。 问题复现:用户注册校验失败 业务场景 开发一个用户注册功能,要求: 校验邮箱…

重构跨境收益互换价值链:新一代TRS平台的破局之道

当香港券商面对内地汹涌的结构化产品需求,一套智能化的TRS系统正成为打开万亿市场的金钥匙 在跨境金融的暗流涌动中,一家中资背景的香港券商正面临甜蜜的烦恼:内地高净值客户对港股、美股的杠杆交易需求激增,但传统TRS业务深陷操作…

实验设计如何拯救我的 CEI VSR 28G 设计

为了确定总体设计裕量,CEI 28G VSR/100 Gb 以太网设计需要分析 500 万种通道变化、收发器工艺和均衡设置的组合。蛮力模拟需要 278 天,这显然超出了可用的时间表。 相反,我们使用实验设计 (DOE) 和响应面建模 &#x…

【仿生机器人】刀剑神域——爱丽丝苏醒计划,需求文档

仿生机器人"爱丽丝"系统架构设计需求文档 一、硬件基础 已完成头部和颈部硬件搭建 25个舵机驱动表情系统 颈部旋转功能 眼部摄像头(视觉输入) 麦克风阵列(听觉输入) 颈部发声装置(语音输出&#xff09…

【Day44】

DAY 44 预训练模型 知识点回顾: 预训练的概念常见的分类预训练模型图像预训练模型的发展史预训练的策略预训练代码实战:resnet18 作业: 尝试在cifar10对比如下其他的预训练模型,观察差异,尽可能和他人选择的不同尝试通…

python打卡训练营打卡记录day44

知识点回顾: 预训练的概念常见的分类预训练模型图像预训练模型的发展史预训练的策略预训练代码实战:resnet18 作业: 尝试在cifar10对比如下其他的预训练模型,观察差异,尽可能和他人选择的不同尝试通过ctrl进入resnet的…

Vue跨层级通信

下面,我们来系统的梳理关于 Vue跨层级通信 的基本知识点: 一、跨层级通信核心概念 1.1 什么是跨层级通信 跨层级通信是指在组件树中,祖先组件与后代组件(非直接父子关系)之间的数据传递和交互方式。这种通信模式避免了通过中间组件层层传递 props 的繁琐过程。 1.2 适用…

webPack基本使用步骤

webPack基本使用步骤 关于webPackwebPack配置的几个概念entry(入口)output(输出)loader(输出)plugin(插件)mode(模式) 基本使用过程示例1.创建测试目录和代码…

龙虎榜——20250604

上证指数缩量收阳线,量能依然在5天线上,股价也在5天线上。 深证指数放量收阳线,量能站上5天均线,但仍受中期60天均线压制。 2025年6月4日龙虎榜行业方向分析 1. 黄金 代表标的:曼卡龙、菜百股份。 驱动逻辑&#…

Viggle:开启视频人物替换新纪元

Viggle 的出现,为视频人物替换带来了前所未有的变革,为创作者和爱好者们打开了一扇通往无限可能的大门。 一、Viggle 技术原理剖析 Viggle 是一款基于先进人工智能技术的创新平台,其核心在于能够精准实现静态图片与动态视频的融合转化。它…

【BUG解决】关于BigDecimal与0的比较问题

这是一个很细小的知识点,但是很容易被忽略掉,导致系统问题,因此记录下来 问题背景 明明逻辑上看a和b都不为0才会调用除法,但是系统会报错:java.lang.ArithmeticException异常: if (!a.equals(BigDecimal…

千年之后再出发,铜官窑驶入微短剧的数字航道

过去一年里,微短剧已经成为走向全民关注、平台扶持、政策引导的“内容新主流”。从市值百亿的爆款平台到走出国门的“短剧出海”,微短剧正在重塑中国数字文化的表达方式与产业结构,也成为各地竞相争夺的“新蓝海”。 就在这样的背景下&#…

数据库管理-第333期 Oracle 23ai:RAC打补丁完全不用停机(20250604)

数据库管理333期 2025-06-04 数据库管理-第333期 Oracle 23ai:RAC打补丁完全不用停机(20250604)1 概念2 要求3 操作流程4 转移失败处理总结 数据库管理-第333期 Oracle 23ai:RAC打补丁完全不用停机(20250604&#xff0…

Trae CN IDE自动生成注释功能测试与效率提升全解析

Trae CN IDE 的自动注释功能可以通过 AI 驱动的代码分析生成自然语言注释,以下是具体测试方法和优势总结: 一、Python 代码注释生成测试 1. 测试环境 IDE:Trae CN IDE(需确认支持 Python)代码示例: def …

软考 系统架构设计师系列知识点之杂项集萃(79)

接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(78) 第141题 软件测试一般分为两个大类:动态测试和静态测试。前者通过运行程序发现错误,包括()等方法;后者采用人工和计算机…