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

【MySQL数据库专项 一】一个例子讲清楚数据库三范式

好的,让我们以学校数据库中的一个表为例来说明第一范式(1NF)、第二范式(2NF)和第三范式(3NF)的概念。

什么是数据库三范式

数据库的范式(Normalization)是一组关于数据库设计的规则,目的是减少数据冗余和改善数据完整性。数据库设计通常遵循三个基本的范式,它们分别是:

  1. 第一范式(1NF)

    • 原子性:表的每一列都是不可分割的基本数据项,即表中的所有字段值都是不可再分的原子值。
    • 唯一性:表的每一行都是唯一的,可以通过一个主键(Primary Key)来区分。
  2. 第二范式(2NF)

    • 在1NF的基础上,消除非主属性对于码的部分函数依赖。
    • 部分函数依赖是指表中的非主属性只依赖于候选键的一部分,而不是整个候选键。
    • 为了达到2NF,通常需要把表分解成两个或多个表,以确保每个表中的非主属性只依赖于该表的主键。
  3. 第三范式(3NF)

    • 在2NF的基础上,消除非主属性对于码的传递函数依赖。
    • 传递函数依赖是指表中的非主属性依赖于另外一个非主属性,这个非主属性依赖于候选键。
    • 达到3NF需要进一步分解表,以确保每个表中的非主属性只依赖于该表的主键,并且没有非主属性依赖于其他非主属性。

这些范式的目标是减少数据冗余(即重复数据),避免更新异常,增强数据的一致性。通常,在实际应用中,设计到第三范式就足够了,但有时候也可能会用到更高级的范式,如BCNF(Boyce-Codd Normal Form)。设计数据库时,需要在规范化和性能之间做出权衡,因为过度规范化可能会导致查询性能下降。

一个例子讲清三范式

从一个未优化的例子逐步拆表

原始表格(未规范化):

假设我们有一个记录学生信息和他们选修课程成绩的表格,如下所示:

学生ID学生姓名选修课程成绩导师姓名导师电话
001张三数学, 物理85, 90李教授1234567890
002李四化学78王教授0987654321

这个表有多个问题:选修课程和成绩字段包含了多个值,违反了1NF;导师姓名和电话是依赖于学生ID的非主属性,违反了2NF;导师电话依赖于导师姓名,而不是学生ID,违反了3NF。

第一范式(1NF):

要满足1NF,表中的每个字段都必须只有单一的(不可分割的)值,不可以有重复的列

学生ID学生姓名选修课程成绩导师姓名导师电话
001张三数学85李教授1234567890
001张三物理90李教授1234567890
002李四化学78王教授0987654321

现在每个字段都只包含单一值,满足了1NF。

第二范式(2NF):

为了达到2NF,我们需要确保表中的所有非主属性完全依赖于主键(而不是部分依赖于复合主键的一部分)。首先,我们确定主键是学生ID和选修课程的组合。然后,我们将导师信息移到一个单独的表中,因为导师信息依赖于学生ID而不是选修课程。

学生课程表:

学生ID选修课程成绩
001数学85
001物理90
002化学78

导师信息表:

学生ID导师姓名导师电话
001李教授1234567890
002王教授0987654321

现在,学生课程表满足2NF,因为所有非主属性(成绩)都完全依赖于整个主键。

第三范式(3NF):

为了满足3NF,我们需要确保表中的所有非主属性只依赖于主键,不存在传递依赖。我们发现,导师电话依赖于导师姓名,而不是学生ID。为了消除传递依赖,我们将导师信息再次分离成独立的表。

学生课程表(保持不变):

学生ID选修课程成绩
001数学85
001物理90
002化学78

学生导师关系表:

学生ID导师姓名
001李教授
002王教授

导师信息表:

导师姓名导师电话
李教授1234567890
王教授0987654321

现在,每个表都满足3NF,因为所有的非主属性都直接依赖于主键,不存在非主属性对主键之外的其他非主属性的依赖。通过这些步骤,我们实现了数据的规范化,减少了数据冗余,并提高了数据的完整性。

http://www.lryc.cn/news/284686.html

相关文章:

  • 【笔记】关于期刊
  • SpringMVC-.xml的配置
  • Java找二叉树的公共祖先
  • 《Linux高性能服务器编程》笔记03
  • Java毕业设计-基于ssm的网上求职招聘管理系统-第85期
  • UDP和TCP
  • 【C++】vector容器接口要点的补充
  • electron-vite中的ipc通信
  • 探秘网络爬虫的基本原理与实例应用
  • 音视频编解码学习记录
  • 零基础小白刚刚入门Python的注意点总结~
  • 从 Context 看 Go 设计模式:接口、封装和并发控制
  • 微信小程序字体大小
  • L1-062 幸运彩票(Java)
  • 【计算机网络】2、传输介质、通信方向、通信方式、交换方式、IP地址表示、子网划分
  • 【Linux 内核源码分析】堆内存管理
  • Qt 5.15.2 (MSVC 2019)编译 QWT 6.2.0 : 编译MingW或MSVC遇到的坑
  • 模具制造企业ERP系统有哪些?企业怎么选型适配的软件
  • 管理信息系统知识点复习
  • 【Bug】.net6 cap总线+rabbitmq延时消息收不到
  • 在 Python 中检查一个数字是否是同构数
  • 【 Qt 快速上手】-①- Qt 背景介绍与发展前景
  • Kafka-消费者-KafkaConsumer分析-PartitionAssignor
  • 【办公软件篇】软件启动器Lucy打造自己的工具箱
  • C#MQTT编程08--MQTT服务器和客户端(cmd版)
  • 【高等数学之牛莱公式】
  • 基于HFSS的微带线特性阻抗仿真-与基于FDTD的计算电磁学方法对比(Matlab)
  • 【SQL】SQL语法小结
  • Open CASCADE学习|显示模型
  • 【C++】string的基本使用