数据库范式(详细介绍)

目录

第一范式(原子性)

第二范式(主键唯一性)

第三范式(原子性+主键唯一性)

BC范式(3NFplus)


第一范式(原子性

确保每列保证原子性,保证这个属性(字段)不能在被分割。

不符合第一范式:

订单
--------------------------------------------------------------
| 订单编号 | 产品名称       | 产品价格          |
--------------------------------------------------------------
| 1      | 手机, 电脑, 鼠标 | 3000, 6000, 100    |
| 2      | 相机, 耳机       | 2000, 300          |
--------------------------------------------------------------
 

在这个例子中,"产品名称"和"产品价格"字段都包含了多个值,使用逗号分隔。这样的设计违反了第一范式(1NF),因为一个字段应该只包含一个值。

为了符合第一范式(1NF),我们可以将每个产品拆分成单独的行,如下所示:

订单
-----------------------------------
| 订单编号 | 产品名称 | 产品价格 |
-----------------------------------
| 1      | 手机   | 3000    |
| 1      | 电脑   | 6000    |
| 1      | 鼠标   | 100     |
| 2      | 相机   | 2000    |
| 2      | 耳机   | 300     |
-----------------------------------
在上述例子中,每个产品都被拆分成了单独的行,每行分别包含一个产品名称和对应的产品价格。这样就符合了第一范式(1NF),每个字段都是原子性的,不可再分。

第二范式(主键唯一性

第二范式在第一范式的基础上,消除了非主属性对于码的部分函数依赖。且增加了一列,这一列为主键列,非主属性都依赖主键列。且没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分,也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

例子:一个不符合第二范式可以是一个包含重复数据的数据库表。举个简单的例子,假设我们有一个存储订单信息的数据库表,其中包含订单号、顾客姓名和顾客地址等字段:

OrderDetails
-----------------------------------
| OrderID   | CustomerName | CustomerAddress |
-----------------------------------
| 1         | Alice        | 123 Main St     |
| 2         | Bob          | 456 Park Ave  |
| 3         | Alice        | 123 Main St     |
-----------------------------------

在这个例子中,可以看到同一个顾客的姓名和地址信息出现了多次。这种情况下,就不符合第二范式(2NF),因为有部分字段依赖于订单号,而另一部分字段依赖于顾客姓名。这样的表结构存在以下问题:

  1. 数据冗余:同一个顾客的姓名和地址信息重复出现,会导致数据冗余,增加了存储空间的消耗。

  2. 更新异常:如果需要更新顾客的地址,那么就需要同时更新多条记录,容易出现更新异常,导致数据不一致。

第三范式(原子性+主键唯一性

第三范式在第二范式的基础之上,消除了非主属性对于码的传递函数依赖。就是说任何非主属性不依赖于其它非主属性。

一个不符合第三范式(3NF)的例子可以是一个存储产品信息的数据库表,其中包含了产品编号、产品名称、供应商编号、供应商名称和供应商地址等字段:

Products
-------------------------------------------------
| ProductID   | ProductName  | SupplierID | SupplierName | SupplierAddress |
-------------------------------------------------
| 1           | Laptop       | 101        | ABC Inc      | 123 Main St     |
| 2           | Smartphone   | 102        | XYZ Ltd      | 456 Park Ave    |
| 3           | Tablet       | 101        | ABC Inc      | 123 Main St     |
-------------------------------------------------

在这个例子中,可以看到存在以下问题:

  1. 数据冗余:同一个供应商的名称和地址信息重复出现,会导致数据冗余,增加了存储空间的消耗。

  2. 更新异常:如果需要更新某个供应商的地址,那么就需要同时更新多条记录,容易出现更新异常,导致数据不一致。

为了符合第三范式,我们可以将上述表拆分成两个表:

Products
---------------------------------
| ProductID   | ProductName  |
---------------------------------
| 1           | Laptop       |
| 2           | Smartphone   |
| 3           | Tablet       |
---------------------------------

Suppliers
---------------------------------
| SupplierID | SupplierName | SupplierAddress |
---------------------------------
| 101        | ABC Inc      | 123 Main St     |
| 102        | XYZ Ltd      | 456 Park Ave    |
---------------------------------
这样就将产品信息和供应商信息分离开来,避免了数据冗余和更新异常,使得数据库表符合第三范式

BC范式(3NFplus)

BC范式(Boyce-Codd Normal Form)是关系数据库设计中的一种标准化范式。它建立在第三范式(3NF)的基础上,通过进一步消除非主属性对候选键的部分依赖来减少数据冗余。

简单来说,BC范式要求:

  1. 每个非主属性都完全依赖于候选键。也就是说,如果一个属性只依赖于候选键的一部分而不是全部,那么它就不符合BC范式。

  2. 所有的函数依赖都应该是候选键的超键。也就是说,任何非候选键的属性都不应该决定其他非候选键的属性。

BC范式的目标是消除数据冗余,并且确保数据的一致性和完整性。通过将关系数据库设计满足BC范式,可以提高数据库的性能和可维护性。

需要注意的是,BC范式是对关系数据库设计的理论指导,并不是必须遵守的绝对规则。在某些情况下,根据实际需求和性能考虑,可能需要在范式化和反范式化之间做出权衡。

举个例子:假设我们有一个关系数据库用于存储员工信息,包含以下字段:员工编号、姓名、部门、工资。

  1. 员工编号是主键(候选键),每个员工的编号唯一标识其身份。

  2. 姓名、部门和工资都完全依赖于员工编号。

在第三范式(3NF)下,我们可以将数据设计如下:

员工表
------------------------------------------------
| 员工编号 | 姓名     | 部门      | 工资      |
------------------------------------------------
| 001    | 张三   | 技术部   | 5000    |
| 002    | 李四   | 销售部   | 6000    |
| 003    | 王五   | 财务部   | 7000    |
------------------------------------------------

这个设计符合第三范式(3NF),因为每个非主属性(姓名、部门、工资)都完全依赖于候选键(员工编号),没有冗余数据

然而,如果我们进一步考虑BC范式,我们可能会发现在这个设计中存在一些函数依赖问题。假设每个部门都有一个负责人,那么我们可以将负责人作为一个新的实体来设计:

员工表
------------------------------------------------
| 员工编号 | 姓名     | 部门编号  | 工资      |
------------------------------------------------
| 001    | 张三   | 001      | 5000    |
| 002    | 李四   | 002      | 6000    |
| 003    | 王五   | 003      | 7000    |
------------------------------------------------

部门表
---------------------------------
| 部门编号 | 部门名称 | 负责人    |
---------------------------------
| 001    | 技术部   | 张三    |
| 002    | 销售部   | 李四    |
| 003    | 财务部   | 王五    |
---------------------------------
 

通过这种设计,我们将部门信息从员工表中分离出来,避免了部门信息的冗余。在部门表中,负责人属性只取决于部门编号,符合BC范式的要求。

这样的设计提高了数据的一致性和完整性,并且减少了冗余数据。根据实际需求和性能要求,我们可以在范式化和反范式化之间做出权衡,选择适合的数据库设计。

总结:

符合三大范式的数据库设计有助于保证数据的一致性、完整性和可维护性,提高查询效率,并节省数据存储空间。然而,在实际应用中,我们需要根据具体的业务需求和性能要求进行权衡,有时也需要适度地进行反范式化设计。

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

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

相关文章

SpringBoot AOP切面实现对自定义注解的属性动态修改

文章目录 需求问题解决方案示例代码 需求 项目中共用了一个redis,而项目中部分代码使用了JetCache的Cached注解。所以需要给Cached动态配置area属性值,用来区分dev和test环境。 问题 自定义注解的属性值需要常量值,即static final修饰&…

升级jdk1.8u391后,加解密部分报错解决

因为修复漏洞,把原来服务器上的jdk1.8进行版本升级,升级后相关的RSA加解密部分报错如下: java.lang.Exception: JCE cannot authenticate the provider BC 修复: 去下载对应jar包 https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk18o…

学习-面试java基础-(集合)

String 为什么不可变? 1线程安全 2支持hash映射和缓存。因为String的hash值经常会使用到,比如作为 Map 的键,不可变的特性使得 hash 值也不会变,不需要重新计算。 3出于安全考虑。网络地址URL、文件路径path、密码通常情况下都是以…

IDEA版SSM入门到实战(Maven+MyBatis+Spring+SpringMVC) -Spring依赖注入数值问题

第一章 Spring依赖注入数值问题 1.1 字面量数值 数据类型&#xff1a;基本数据类型及包装类、String语法&#xff1a;value属性或value标签 1.2 CDATA区 语法&#xff1a;<![CDATA[]]>作用&#xff1a;在xml中定义特殊字符时&#xff0c;使用CDATA区 1.3 外部已声明…

Python之Requests库使用总结

概述 Requests是python中一个很Pythonic的HTTP库&#xff0c;用于构建HTTP请求与解析响应 Requests开发哲学 Beautiful is better than ugly.(美丽优于丑陋) Explicit is better than implicit.(直白优于含蓄) Simple is better than complex.(简单优于复杂) Complex is bett…

Pytorch当中nn.Identity()层的作用

在深度学习中&#xff0c;nn.Identity() 是 PyTorch 中的一个层&#xff08;layer&#xff09;。它实际上是一个恒等映射&#xff0c;不对输入进行任何变换或操作&#xff0c;只是简单地将输入返回作为输出。 通常在神经网络中&#xff0c;各种层&#xff08;比如全连接层、卷…

Javascript的基本语法(规范)

JS的基本语法规范 1.JS中严格区分大小写 2.JS中每一个指令被称为一个语句&#xff0c;每一个语句都应该以分号结尾 - 在JS中有自动的添加分号的机制&#xff0c;如果不写分号浏览器会自动为你添加 - 有些情况下&#xff0c;浏览器可能会给你加错了&#xff08;几率低&#…

回顾【数学基础】找出断层,继续前进, 使用chatGPT学习并解决实际问题:微积分

已经学过的算术、代数、几何。跳过。 从微积分开始 想象一下&#xff0c;你在画一条曲线&#xff0c;或者在一个大草地上奔跑。微积分就是一种数学工具&#xff0c;帮助我们了解这条曲线的形状&#xff0c;或者你奔跑的方式。 微分&#xff08;就像研究曲线上的每一小点&…

FFmpeg的AVIOPROBE

文章目录 定义 可能你一直有疑问&#xff0c;ffmpeg的avformat是怎么提前知道码流是编码格式或者容器&#xff1f;恭喜你&#xff0c;看到这里&#xff0c;你找到答案了&#xff0c;在这里&#xff0c;ffmpeg通过这些probe函数来提前获取码流的编码格式。 看到下面的avs2_prob…

YOLOv8算法改进【NO.86】将主干特征网络替换为2023年顶会CVPR的EfficientViT,助力SCI论文发表

前 言 YOLO算法改进系列出到这,很多朋友问改进如何选择是最佳的,下面我就根据个人多年的写作发文章以及指导发文章的经验来看,按照优先顺序进行排序讲解YOLO算法改进方法的顺序选择。具有有需求可以私信我沟通: 第一,创新主干特征提取网络,将整个Backbone改进为其…

C++1114新标准——统一初始化(Uniform Initialization)、Initializer_list(初始化列表)

系列文章目录 C11&14新标准——Variadic templates&#xff08;数量不定的模板参数&#xff09; C11&14新标准——Uniform Initialization&#xff08;统一初始化&#xff09;、Initializer_list&#xff08;初始化列表&#xff09; 文章目录 系列文章目录1. 定义2. I…

装饰者模式(Decorator Pattern)

1 什么是装饰者模式&#xff1f; 1.1 Head First Design Pattern 定义 装饰者模式动态地将责任附加到对象上。若要扩展功能&#xff0c;装饰者提供了比继承更有弹性的替代方案。 1.2 大佬博客 设计模式是什么鬼&#xff08;装饰&#xff09; 2 装饰者模式 2.1 基本介绍 …

react Hooks之useEffect

一&#xff1a;作用&#xff1a; 处理副作用操作&#xff1a;通过在 useEffect 的回调函数中执行副作用操作&#xff0c;例如发送网络请求、订阅事件、手动管理组件的生命周期等。依赖管理&#xff1a;可以根据传入的依赖数组&#xff0c;在特定的依赖变化时触发 useEffect 的…

Goby 漏洞发布| 亿赛通电子文档安全管理系统 LinkFilterService 接口权限绕过漏洞

漏洞名称&#xff1a;亿赛通电子文档安全管理系统 LinkFilterService 接口权限绕过漏洞 English Name&#xff1a;Esafenet Electronic Document Security Management System LinkFilterService API Permission Bypass Vulnerability CVSS core: 9.3 影响资产数&#xff1a;…

MySQL BinLog 数据还原恢复

博文目录 文章目录 查看状态查看 binlog 开关及存储路径查看 binlog 配置 如 存储格式 binlog_format查看当前还存在的日志查看当前正在使用的日志 切换日志确定日志确定日志文件日志格式改写日志简要说明确定日志位置以事件为单位查看日志分析日志 还原数据 查看状态 查看 b…

智能优化算法应用:基于花授粉算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于花授粉算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于花授粉算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.花授粉算法4.实验参数设定5.算法结果6.参考文…

Java:MyBatis-Plus特殊字段desc导致sql查询报错的问题

有如下的实体对象 public class BookEntity {private String desc; }查询操作的时候会报错SQL错误 解决方法 在字段属性上加注解&#xff0c;用反引号包裹属性值 public class BookEntity {TableField("desc")private String desc; }参考 解决MySQL 中使用index…

设计模式(2)--对象创建(1)--抽象工厂

1. 意图 提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无需指定它们具体的类。 2. 四种角色 抽象产品(Product)、具体产品(Concrete Product)、抽象工厂(Abstract Factory)、具体工厂(Concrete Factory)。 3. 优点 3.1 分离了具体的类。Client只需使用抽象工厂类…

解析代理IP在跨境电商和社媒营销中的关键作用

跨境电商和社媒营销领域的从业者深知&#xff0c;代理IP的价值愈发凸显。在推广营销的过程中&#xff0c;频繁遇到因IP关联而封禁账号的情况&#xff0c;或因使用不安全IP而导致异常问题。 这些问题促使人们开始高度重视代理IP的作用。但实际上&#xff0c;代理IP究竟是何物&a…

(数据结构)单链表的定义

#include<stdio.h> typedef struct LNode {int data;struct LNode* next; }LNode,*LinkList; //LNode为结构体类型&#xff0c;LinkList为指向单链表的指针 //初始化一个空的单链表 void InitList(LinkList L) {L NULL; //空表&#xff0c;暂时没有任何节点 } //判断单…