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

【数据库系统概论】函数依赖与范式

概述

在数据库设计中,范式(Normal Forms, NF)是用来规范化数据库表结构,以减少冗余数据和提高数据一致性与完整性的重要工具。

函数依赖

完全函数依赖与部分函数依赖

完全函数依赖

定义
完全函数依赖表示的是在一个关系中,若某个非主属性数据项依赖于全部关键字,则称这种依赖为完全函数依赖。换句话说,如果非主属性B函数依赖于构成某个候选关键字的一组主属性A,而且A的任何一个真子集不能被B函数依赖,则称B完全函数依赖于A。

举例
以成绩表为例,该表包含 (学号,课程号,成绩) (学号,课程号,成绩) (学号,课程号,成绩)三个属性。其中, (学号,课程号) (学号,课程号) (学号,课程号)是一个候选键,因为它们共同确定了一个唯一的成绩。

  • 完全函数依赖:在这个例子中, (学号,课程号) → 成绩 (学号,课程号)→ 成绩 (学号,课程号)成绩是一个完全函数依赖。因为成绩完全依赖于学号和课程号的组合,单独的学号或课程号都不能确定成绩。

部分函数依赖

定义
部分函数依赖是指在一个关系中,如果 X → Y X→Y XY,并且存在 X X X的一个真子集 X 0 X₀ X0,使得 X 0 → Y X₀→Y X0Y,则称 Y Y Y X X X部分函数依赖。这意味着 Y Y Y不仅依赖于 X X X的全部,还依赖于 X X X的某个真子集。

举例
以成绩表为例,假设该模式包含 (学号,课程号,成绩,年龄) (学号,课程号,成绩,年龄) (学号,课程号,成绩,年龄)四个属性。

  • 部分函数依赖:在这个例子中,如果 学号 学号 学号能单独确定 年龄 年龄 年龄,而 (学号,课程号) (学号,课程号) (学号,课程号)共同确定 成绩 成绩 成绩。那么, (学号,课程号) → 年龄 (学号,课程号)→ 年龄 (学号,课程号)年龄就是一个部分函数依赖,因为 年龄 年龄 年龄不仅依赖于 (学号,课程号) (学号,课程号) (学号,课程号)的组合,还依赖于 学号 学号 学号这个真子集。

归纳

  • 完全函数依赖强调的是非主属性对全部关键字的依赖,即不存在关键字的真子集能够确定非主属性
  • 部分函数依赖则允许非主属性对关键字的某个真子集也存在依赖关系

范式

第一范式(1NF - First Normal Form)

定义
1NF要求数据库表中的每个列(或称为属性、字段)都包含不可再分的原子数据,也就是说每个单元格中只包含一个值。不应该有多值属性或重复组。

要点

  1. 每个表中的每一列都必须包含不可再分的原子数据
  2. 表中的每一行必须具有唯一的标识符,通常是主键

举例

假设我们有一个表示图书信息的表,初始设计如下:

图书信息图书号书名作者出版社
示例123《编程基础》;《数据库原理》李四,王五清华大学出版社;机械工业出版社

这个表不满足1NF,因为“书名”和“作者”列包含了多个值(由分号分隔),它们是可以再分的。为了满足1NF,我们需要将这些列拆分为多个列,如下:

图书号书名1作者1出版社1书名2作者2出版社2
123《编程基础》李四清华大学出版社《数据库原理》王五机械工业出版社

但上述设计仍然不是最佳实践,因为它引入了不必要的冗余。更常见的方法是将每本书的信息分别存储在不同的行中,如下所示:

图书号书名作者出版社
123《编程基础》李四清华大学出版社
456《数据库原理》王五机械工业出版社

第二范式(2NF - Second Normal Form)

定义
2NF建立在1NF的基础上,要求关系模式中的所有非主属性都完全依赖于候选键(或称为主键),而不是仅依赖于候选键的一部分

要点

  1. 满足1NF。
  2. 非主属性必须完全依赖于候选键

举例

假设我们有一个表示学生选课信息的表,初始设计如下:

学号课程号成绩课程学分
N01C01903
N01C02854
N02C01883

在这个例子中, 学号( S N O ) 学号(SNO) 学号(SNO 课程号( C N O ) 课程号(CNO) 课程号(CNO的组合是主键(候选键)。然而, “课程学分” “课程学分” 课程学分这一非主属性仅依赖于课程号 ( C N O ) (CNO) CNO,而不是完全依赖于主键 ( S N O , C N O ) (SNO, CNO) SNO,CNO。这违反了2NF。

为了满足2NF,我们需要将“课程学分”这一属性移到一个新的表中,该表以课程号(CNO)为主键,如下所示:

表1:选课信息

学号课程号成绩
N01C0190
N01C0285
N02C0188

表2:课程信息

课程号课程学分
C013
C024

这样,我们就通过分解原始表来满足了2NF,减少了数据冗余并提高了数据一致性

第三范式(3NF - Third Normal Form)

定义
3NF建立在2NF的基础上,要求关系模式中的所有非主属性都不传递依赖于候选键

换句话说,如果非主属性 A A A依赖于另一个非主属性 B B B,而 B B B又依赖于候选键 C C C,那么 A A A不能直接依赖于 B B B,而必须直接依赖于 C C C

B → A , C → B (非3NF) B → A , C → B \tag{非3NF} BA,CB(3NF)

C → A , C → B (3NF) C → A , C → B \tag{3NF} CA,CB(3NF)

要点

  1. 满足2NF
  2. 消除传递依赖

举例

考虑一个表示学生信息的表,其中包含了学生、课程、成绩以及课程对应的教师信息。

原始设计可能如下:

学生ID学生姓名课程号课程名成绩教师ID教师姓名

在这个例子中,学生ID和课程号的组合是主键(候选键)。

然而,“教师姓名”这一非主属性仅依赖于“教师ID”,而“教师ID”又依赖于“课程号”

这构成了一个传递依赖,因为“教师姓名”间接地依赖于主键的一部分(即“课程号”),而不是直接依赖于整个主键(学生ID和课程号)。

为了满足3NF,我们需要将“教师”相关的信息移到一个新的表中,如下所示:

表1:学生选课信息

学生ID学生姓名课程号成绩

表2:课程信息

课程号课程名教师ID

表3:教师信息

教师ID教师姓名

Boyce-Codd范式(BCNF - Boyce-Codd Normal Form)

定义
BCNF是由Boyce和Codd提出的,它比3NF更为严格。BCNF要求关系模式中的所有属性(包括主属性)都不传递依赖于候选键

要点

  1. 所有非主属性对每一个候选键都是完全函数依赖
  2. 所有的主属性对每一个不包含它的候选键,也是完全函数依赖
  3. 没有任何属性完全函数依赖于非候选键的任何一组属性

解释
BCNF不仅要求非主属性不传递依赖于候选键,还要求主属性也不传递依赖于候选键。这意味着在BCNF中,任何属性都不能间接地依赖于候选键的任何一部分。这进一步减少了数据冗余和更新异常的可能性。

由于BCNF的定义较为复杂,通常在实际应用中,数据库设计者会首先尝试满足1NF、2NF和3NF,然后在必要时才考虑BCNF。这是因为满足BCNF的数据库模式可能更加复杂,不易于理解和维护。然而,在某些情况下,特别是在需要高度数据一致性和完整性的应用中,BCNF可能是一个有用的工具。

相关文章:

  • Jetpack架构组件_4. 数据绑定库页面传递数据
  • ChatGPT成知名度最高生成式AI产品,使用频率却不高
  • Java项目:94 springboot大学城水电管理系统
  • (7)svelte 教程: Props(属性)
  • 【Linux系统编程】冯诺依曼体系、操作系统、进程的认识
  • 视频汇聚EasyCVR视频监控云平台对接GA/T 1400视图库对象和对象集合XMLSchema描述
  • selenium中, quit 和close的区别
  • 前端作用域冲突之快照沙箱和代理沙箱
  • leetcode:最近的请求次数
  • Vue可视化表单设计 FcDesigner v3.1.0 发布,新增 12 个组件,支持事件配置等
  • Java项目:96 springboot精品在线试题库系统
  • preventDefault()与stopPropagation()有什么区别?
  • IGraph使用实例——线性代数计算(blas)
  • 强达电路营收下滑净利润急剧放缓:周转率骤降,2次因环保被罚
  • 初识SDN(二)
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • extjs4学习之配置
  • git 常用命令
  • iOS 系统授权开发
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • Netty源码解析1-Buffer
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • sessionStorage和localStorage
  • Spring声明式事务管理之一:五大属性分析
  • 深度学习中的信息论知识详解
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 小程序01:wepy框架整合iview webapp UI
  • 学习笔记TF060:图像语音结合,看图说话
  • 一份游戏开发学习路线
  • 最近的计划
  • 如何在招聘中考核.NET架构师
  • ​决定德拉瓦州地区版图的关键历史事件
  • ​虚拟化系列介绍(十)
  • # Java NIO(一)FileChannel
  • # Panda3d 碰撞检测系统介绍
  • $(this) 和 this 关键字在 jQuery 中有何不同?
  • (2024)docker-compose实战 (9)部署多项目环境(LAMP+react+vue+redis+mysql+nginx)
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (php伪随机数生成)[GWCTF 2019]枯燥的抽奖
  • (二)正点原子I.MX6ULL u-boot移植
  • (二开)Flink 修改源码拓展 SQL 语法
  • (附源码)计算机毕业设计高校学生选课系统
  • (接上一篇)前端弄一个变量实现点击次数在前端页面实时更新
  • (六)激光线扫描-三维重建
  • (转) Face-Resources
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .net core Swagger 过滤部分Api
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .NET 读取 JSON格式的数据
  • .NET/C# 使窗口永不获得焦点
  • .NetCore实践篇:分布式监控Zipkin持久化之殇
  • .NET框架设计—常被忽视的C#设计技巧
  • .net专家(高海东的专栏)