数据库范式与反范式化:如何权衡性能与数据一致性

目录

        • 1. 什么是数据库范式(Normalization)?
          • 第一范式(1NF)
          • 第二范式(2NF)
          • 第三范式(3NF)
        • 2. 什么是反范式化(Denormalization)?
        • 3. 反范式化的优缺点
        • 4. 反范式化的应用场景
        • 5. 范式化与反范式化结合设计
      • 总结

在数据库设计中,范式和反范式化(Denormalization)是两个至关重要的概念。范式化的目标是减少冗余、避免数据异常,而反范式化则侧重于优化查询性能。两者之间的取舍,往往需要根据具体的业务需求来决定。

1. 什么是数据库范式(Normalization)?

数据库范式化是通过遵循一系列规则,将数据分割成多个表格,从而消除冗余和异常。它不仅可以提高数据的一致性,还可以避免插入、更新、删除等操作中的数据异常。

第一范式(1NF)

定义:第一范式要求每列中的数据必须是原子值,不可再分。

示例
假设我们有一个学生信息表,其中包含学生所选课程的列表。

不符合1NF

CREATE TABLE Student (StudentID INT,StudentName VARCHAR(50),Courses VARCHAR(100)  -- 存储课程列表
);

符合1NF
我们将课程拆分到单独的表格,并确保每个值是原子性的:

CREATE TABLE Student (StudentID INT,StudentName VARCHAR(50)
);CREATE TABLE Enrollment (StudentID INT,Course VARCHAR(50),PRIMARY KEY (StudentID, Course),FOREIGN KEY (StudentID) REFERENCES Student(StudentID)
);
第二范式(2NF)

定义:第二范式要求,在满足第一范式的基础上,每一列都必须完全依赖于主键。

示例
假设一个表格中包含了学生成绩和课程信息,其中某些列的依赖性不完全来自于主键。

不符合2NF(部分依赖)

CREATE TABLE StudentGrades (StudentID INT,Course VARCHAR(50),InstructorName VARCHAR(50),Grade CHAR(1),PRIMARY KEY (StudentID, Course)
);

符合2NF
我们将与课程相关的信息拆分成独立的表格,消除部分依赖:

CREATE TABLE StudentGrades (StudentID INT,Course VARCHAR(50),Grade CHAR(1),PRIMARY KEY (StudentID, Course),FOREIGN KEY (StudentID) REFERENCES Student(StudentID)
);CREATE TABLE CourseInstructor (Course VARCHAR(50),InstructorName VARCHAR(50),PRIMARY KEY (Course)
);
第三范式(3NF)

定义:第三范式要求,在满足第二范式的基础上,每一列都必须直接依赖于主键,不能依赖于其他非主键列。

示例
在一个包含学生信息、课程及其所属系信息的表格中,存在传递依赖。

不符合3NF(传递依赖)

CREATE TABLE StudentCourse (StudentID INT,StudentName VARCHAR(50),Course VARCHAR(50),Department VARCHAR(50),PRIMARY KEY (StudentID, Course)
);

符合3NF
我们将部门信息拆分到独立的表格中,避免传递依赖:

CREATE TABLE StudentCourse (StudentID INT,Course VARCHAR(50),PRIMARY KEY (StudentID, Course),FOREIGN KEY (StudentID) REFERENCES Student(StudentID)
);CREATE TABLE Department (Course VARCHAR(50),Department VARCHAR(50),PRIMARY KEY (Course)
);
2. 什么是反范式化(Denormalization)?

反范式化是对范式化的逆操作,通常用于优化查询性能,尤其是在读操作频繁的场景下。通过冗余存储一些数据,可以减少多表连接的开销,从而提升查询速度。

反范式化的示例:

假设我们有两个表格:Product(产品)和 Order(订单),它们通过外键关联。

  • 范式化后的表格
CREATE TABLE Product (ProductID INT PRIMARY KEY,ProductName VARCHAR(50),Price DECIMAL(10, 2)
);CREATE TABLE Order (OrderID INT PRIMARY KEY,ProductID INT,Quantity INT,OrderDate DATE,FOREIGN KEY (ProductID) REFERENCES Product(ProductID)
);

为了查询一个订单的详细信息,我们需要进行多表连接。

  • 反范式化后的表格
    为了提高查询效率,我们将产品的名称和价格存储在 Order 表中,减少了联结操作的需求:
CREATE TABLE Order (OrderID INT PRIMARY KEY,ProductID INT,ProductName VARCHAR(50),Price DECIMAL(10, 2),Quantity INT,OrderDate DATE
);

这样,查询订单时无需再联结 Product 表,提升了查询效率。

3. 反范式化的优缺点

优点

  • 查询性能提升:减少了表连接,提高了查询速度。
  • 简化查询:查询更加直接和简便。

缺点

  • 数据冗余:数据被重复存储,可能导致存储浪费。
  • 维护困难:如果数据发生变化(如价格调整),需要在多个表中更新,增加了维护的复杂性。
  • 更新异常:可能导致一致性问题,尤其在数据修改时。
4. 反范式化的应用场景

反范式化最适合以下场景:

  • 数据仓库:在数据仓库中,查询性能比数据一致性更重要。
  • 高并发查询:例如电商系统,查询订单详情时通过反范式化减少多表连接,提升系统响应速度。
5. 范式化与反范式化结合设计

设计一个学校管理系统时,我们可以根据需求灵活结合范式化与反范式化:

  • 范式化:保证数据一致性,避免不必要的冗余。
  • 反范式化:在高查询频率的场景下,减少表连接,提升查询性能。

示例
范式化设计

CREATE TABLE Student (StudentID INT PRIMARY KEY,StudentName VARCHAR(50)
);CREATE TABLE Course (CourseID INT PRIMARY KEY,CourseName VARCHAR(50)
);CREATE TABLE Teacher (TeacherID INT PRIMARY KEY,TeacherName VARCHAR(50)
);CREATE TABLE Enrollment (StudentID INT,CourseID INT,TeacherID INT,Grade VARCHAR(2),PRIMARY KEY (StudentID, CourseID),FOREIGN KEY (StudentID) REFERENCES Student(StudentID),FOREIGN KEY (CourseID) REFERENCES Course(CourseID),FOREIGN KEY (TeacherID) REFERENCES Teacher(TeacherID)
);

反范式化设计
在查询订单信息时,减少多表连接的需要,提升查询效率:

CREATE TABLE Enrollment (StudentID INT,CourseID INT,TeacherID INT,CourseName VARCHAR(50),   -- 反范式化TeacherName VARCHAR(50),  -- 反范式化Grade VARCHAR(2),PRIMARY KEY (StudentID, CourseID),FOREIGN KEY (StudentID) REFERENCES Student(StudentID),FOREIGN KEY (TeacherID) REFERENCES Teacher(TeacherID)
);

总结

范式化和反范式化都是数据库设计中必不可少的工具。范式化确保了数据的规范性和一致性,适用于数据变更频繁且对一致性要求较高的场景;反范式化则通过牺牲一些规范性来优化查询性能,尤其适用于查询密集型的应用。


参考:
0voice · GitHub

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

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

相关文章

Nmap使用总结

0X00 背景 nmap是测试中常用的网络探测工具,但是这回简单的操作,一直了解不深入,现在深入的了解和学习一下。 在文章结构上,我把平时常用的内容提前了,以便再次查阅的时候,比较方便。 0X01 安装 nmap可…

【记录49】vue2 vue-office在线预览 docx、pdf、excel文档

vue2 在线预览 docx、pdf、excel文档 docx npm install vue-office/docx vue-demi0.14.6 指定版本 npm install vue-office/docx vue-demi <template><VueOfficeDocx :src"pdf" style"height: 100vh;" rendere"rendereHandler" error&…

MVC模式的理解和实践

在软件开发中&#xff0c;MVC&#xff08;Model-View-Controller&#xff09;模式是一种经典的设计模式&#xff0c;特别适用于构建用户界面复杂的Web应用程序。MVC通过将应用程序的业务逻辑、数据显示和用户交互分离&#xff0c;使代码结构更加清晰&#xff0c;易于维护和扩展…

[A-22]ARMv8/v9-SMMU多级页表架构

ver0.1 [看前序文章有惊喜,关注W\X\G=Z+H=“浩瀚架构师”,可以解锁全部文章] 前言 前文我们对SMMU的系统架构和基本功能做了简要的介绍,现在大家大致对SMMU在基于ARM体系的系统架构下的总线位置和产品形态有了基本的了解。这里我们还是简单做个前情回顾,从总线架构角度看…

【UE5 “RuntimeLoadFbx”插件】运行时加载FBX模型

前言 为了解决在Runtime时能够直接根据FBX模型路径直接加载FBX的问题&#xff0c;推荐一款名为“RuntimeLoadFBX”的插件。 用法 插件用法如下&#xff0c;只需要指定fbx的地址就可以在场景中生成Actor模型 通过指定输入参数“Cal Collision”来设置FBX模型的碰撞 还可以通过…

(11)(3.1) ESC接地和接线注意事项

文章目录 前言 1 归纳 2 电容式 3 电阻 前言 ESC 接地问题由 3 种形式的 ESC 信号/耦合问题组成&#xff0c;即电阻、电容和电感。在制造飞机时&#xff0c;应考虑这三个因素。 1 归纳 这是电流突然变化导致系统中出现大电压尖峰的趋势。电源系统中的电感主要是由 ESC 和…

精品基于Python实现的微信小程序校园导航系统-微信小程序

[含文档PPT源码等] [包运行成功永久免费答疑辅导] 《django微信小程序校园导航系统》该项目采用技术Python的django框架、mysql数据库 &#xff0c;项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、核心代码介绍视频等 软件开发环境及开发工具&#xf…

Rstudio-server的安装、配置、维护

一、安装Rstudio-server (1)安装R语言&#xff1a; sudo apt install r-base # 如果没有管理员权限无法操作 # 这样装上R默认在/usr/bin/R其实基本上的流程都可以参考posit的官网&#xff08;也就是Rstudio的官网&#xff09;&#xff1a; https://posit.co/download/rstudio…

Python序列的应用(八):元组、字典

前言&#xff1a;在Python编程语言中&#xff0c;序列是一种非常重要的数据结构&#xff0c;它允许我们存储和操作有序的数据集合。在前几期的内容中&#xff0c;我们已经探讨了列表&#xff08;List&#xff09;和集合&#xff08;Set&#xff09;这两种序列的应用&#xff0c…

OpenCV 功能函数介绍

一&#xff0c; 二值化函数 功能&#xff1a; 用于对图像进行二值化处理 参数&#xff1a; cv2.threshold(输入你的图像所对应的灰度图&#xff0c; 阈值&#xff1a;是浮点还是整数取决予图像的数据类型 最大值;高于阈值的像素值&#xff0c; 阈值类型&#xff1a;cv2.THR…

【Python】使用Selenium的find_element模块获取网页上的大段文字和表格的方法(建议收藏!)

发现了一个使用Selenium的find_element模块&#xff0c;快速获取文字和表格的方法&#xff0c;很实在&#xff0c;以后爬网的时候&#xff0c;就不用beautifulSoup 和 pandas的read_html 混起来用了&#xff01; 文字部分&#xff1a;实现网络节点下&#xff0c;某个节点下的其…

APP渗透测试记录(一、Android应用基本构造)

Android应用基本构造 雷电模拟机进入 adb shell# 如果不是root权限 su一下 su 1.了解APK文件 安卓应用的扩展名为.apk(Android Application Package),它是一个包含多个文件和文件夹的数据存档文件。 1.1 apk文件解压后的目录结构 AndroidManifest.xml:包含应用的大部分…

【AI知识】有监督学习之回归任务(附线性回归代码及可视化)

1. 回归的基本概念 在机器学习的有监督学习中&#xff0c;回归&#xff08;Regression&#xff09;是一种常见的任务&#xff0c;它的目标是通过观察数据来建立一个模型&#xff0c;用一个或多个自变量来预测因变量的值。 回归分析通常用于&#xff1a; a.预测&#xff0c;基于…

fastadmin批量压缩下载远程视频文件

后端代码 // 批量下载并压缩 public function downloadAll(){$ids input(ids);$row $this->model->where(id, in, $ids)->field(id,title,video_url)->select();if (!$row) {$this->error(记录不存在);}$arr [];$tempFiles []; // 用来存储临时下载的视频文…

边缘计算+人工智能:让设备更聪明的秘密

引言&#xff1a;日常生活中的“智能”设备 你是否发现&#xff0c;身边的设备正变得越来越“聪明”&#xff1f; 早上醒来时&#xff0c;智能音箱已经根据你的日程播放舒缓音乐&#xff1b;走进厨房&#xff0c;智能冰箱提醒你今天的食材库存&#xff1b;而在城市道路上&…

JVM 双亲委派模型以及垃圾回收机制

目录 1. JVM 内存区域划分 2. JVM 中类加载的过程 1) 类加载的基本流程 2) 双亲委派模型 3. JVM 中垃圾回收机制 1) 找到垃圾 a) 引用计数 b) 可达性分析 2) 释放垃圾 1. JVM 内存区域划分 一个运行起来的 Java 进程&#xff0c;其实就是一个 JVM 虚拟机。 而进程是…

ansible自动化运维(四)jinjia2模板

Jinjia2模板 前面说到playbook组成的时候&#xff0c;有介绍到template模块&#xff0c;而template模块对模板文件进行渲染时&#xff0c;使用的就是jinja2模板引擎&#xff0c;jinja2本身就是基于python的模板引擎&#xff0c;所以下面先来了解一下jinjia2模板的一些用法 基…

通过k-means对相似度较高的语句进行分类

本文介绍了如何使用K-Means算法对相似度较高的语句进行分类&#xff0c;并附上java案例代码 import java.util.ArrayList; import java.util.List; import java.util.Random;public class KMeansTextClustering {public static void main(String[] args) {// 初始化语句数据集…

Oracle 19c rac 补丁升级,从19.7 to19.22-集群

1. 补丁包概述 数据库环境 角色 数据库 IP地址 数据库版本 主机名 数据库名称 源端 RAC 172.30.21.166/167 19.7 hfcwdb66/hfcwdb67 hfdb 将以下补丁包上传到/soft下 上传到两个节点的soft目录下&#xff1a;p6880880_190000_Linux-x86-64.zip &#xff08;更新o…

Windows安装Jira

下载 Download Jira Data Center | Atlassian https://product-downloads.atlassian.com/software/jira/downloads/atlassian-jira-software-10.3.0-x64.exe 以管理员身份安装&#xff0c;否则弹出以下提醒 创建和配置MySQL数据库&#xff1a;参照 Connecting Jira applicat…