数据库范式判断:函数依赖与候选码如何决定表设计成败

发布时间:2026/10/14 6:33:38
数据库范式判断:函数依赖与候选码如何决定表设计成败 简介《数据库系统概论(第五版)》第6章配套PPT课件聚焦关系数据理论这一关系型数据库设计的基础理论。资源面向数据库原理学习者、期末备考学生及考研复试人群也可为讲授数据库课程的教师提供授课参考。课件从“问题的提出”切入系统讲解关系模式的基本表示、数据依赖与函数依赖、多值依赖、码与范式递进并深入数据依赖的公理系统和模式分解方法。课程借助教务数据库案例针对学生、系、系主任、课程、成绩等属性展示如何从原始关系中发现数据冗余及插入、删除、更新异常进而通过S(Sno,Sdept)、SC(Sno,Cno,Grade)、DEPT(Sdept,Mname)等分解消除不良依赖完整呈现规范化设计的思考过程。资源共1个PPT文件压缩包大小911KB结构紧凑、层次分明适合直接用于课堂展示或自学复盘。该资源已有60人学习浏览是数据库课程中高频使用的教学资料。1. 数据库系统概论第6章课件为什么范式判断才是建表的第一道坎这套《数据库系统概论第五版》第6章课件核心内容不是 SQL 写法也不是索引调优而是关系数据理论函数依赖、候选码、范式判断、模式分解。一句话概括它的作用告诉你一张表到底该不该拆、为什么拆、拆完怎么保证不拆坏。计算机专业本科生会被这一章折磨毕业后做数据建模、业务表设计时又会回头补这一章。适合三类人正在准备期末或考研的人、被范式题目绕晕的初学者、想真正理解规范化背后逻辑的从业者。我拆完这套课件最大的感受是它把抽象定义和例题排在一起复习节奏比单啃教材紧凑但前提是你要知道每一节到底在解决什么问题。2. 函数依赖与候选码先回答“这张表为什么必须拆”2.1 一张“看上去挺正常”的学生选课表藏着四个异常课件开篇通常会放一张非常“正常”的选课表字段大概是这样学号姓名系系主任课程号课程名成绩001张三计算机李四C01数据库90001张三计算机李四C02操作系统85002王五数学赵六C01数据库78这张表从功能上看完全能满足日常记录但它在设计上是有问题的。候选码是学号课程号而里面还藏着学号→姓名、学号→系、系→系主任这些额外的函数依赖。把这些字段硬塞进同一张表就会产生四类经典异常数据冗余同一学生的系、系主任会出现在他选的每一门课里。更新异常系主任换了要改很多行漏改一处就造成数据不一致。插入异常新建一个系还没有学生选课系主任的信息根本插不进去。删除异常某个学生退掉最后一门课整行被删系和系主任信息也一起消失。这个例子不是理论摆设在实际业务中我见过不少刚起步的系统就是这么建表的。所有字段放到一起先用起来再说等数据量上来、要改一个部门名称时才发现要批量更新几千行。课件这一节的真正价值是先把“问题表”摆在你面前后面所有定义都是围绕修复这张表展开的。2.2 函数依赖 X→Y抓准部分依赖与传递依赖函数依赖的定义很简短若在关系 R 中属性集合 X 的每一个取值都唯一对应属性集合 Y 的一个取值就说 X 函数决定 Y记作 X→Y。放到工程里理解就是给定 X 的值你能确定 Y 的值。比如学号→姓名知道学号就能确定姓名但姓名→学号不成立因为可能重名。只记住定义还不够范式判断真正用到的是三种衍生关系完全函数依赖X→Y且 X 的任何一个真子集都不能决定 Y。例如学号课程号→成绩少一个属性就推不出成绩。部分函数依赖X→Y但 X 的某个真子集也能决定 Y。例如学号课程号→姓名因为学号单独就能决定姓名。传递函数依赖X→YY→Z且 Y 不决定 X则 Z 传递依赖于 X。例如学号→系系→系主任所以系主任传递依赖于学号。判断范式时很多同学直接把“2NF 消除部分依赖3NF 消除传递依赖”背下来然后去做题结果一碰到复合候选码就翻车。这是因为背的是结论没有理解判断依赖关系的顺序。看到一条依赖先问左侧是否包含候选码的真子集再问中间是否存在一条依赖链这样才不会漏判。课件里大多会把完全、部分、传递三种依赖画成箭头图复习时最好自己也在草稿纸上画一遍。这个动作很关键因为后面判断 2NF 和 3NF 时你就是在找这两类依赖是否存在。2.3 候选码怎么求闭包计算的四个步骤与一道例题函数依赖解决的是“能不能推出来”的问题候选码解决的是“谁能代表整行”的问题。求候选码的标准工具是属性集的闭包。给定一个属性集 X 和函数依赖集 FX 的闭包记作 X表示从 X 出发用 F 里的依赖不断推导最终能得到的全部属性集合。计算过程四步走初始化闭包集合为 X 本身。扫描 F 中的每一条依赖 α→β若闭包已经包含 α就把 β 并入闭包。重复第 2 步直到闭包不再变化。若闭包等于全部属性 U则 X 是超码进一步检查 X 是否存在真子集也是超码若没有则 X 是候选码。拿课件里最常见的一道例题来走一遍。设关系模式 R(U, F)U{A, B, C, D, E}F{AB→C, C→D, D→E}求 AB 是否为候选码。先求 AB 的闭包轮次可触发的依赖闭包变化初始-{A, B}第 1 轮AB→C{A, B, C}第 2 轮C→D{A, B, C, D}第 3 轮D→E{A, B, C, D, E}闭包到达全集 U所以 AB 是超码。再验证 A 的闭包只有 {A}B 的闭包只有 {B}都不等于 U所以 AB 是候选码。再看快速判断候选码的属性分类法这是课件例题之外很实用的补充。把 F 中所有属性分成四类L 类只出现在依赖左侧必须选入候选码。R 类只出现在依赖右侧不可能进入候选码。LR 类两侧都出现需要逐个试探。N 类两侧都不出现必须选入候选码。上例中 A、B 是 L 类E 是 R 类C、D 是 LR 类。候选码必须包含 A、B因为这两者不能由其他属性推导出来。计算 AB 的闭包已经等于全集就不用再试探 LR 类组合了。如果闭包不等于全集就要依次尝试 AC、AD、BC、BD 等组合直到找到能覆盖全集的属性组。提示求候选码是整章的地基。范式判断、模式分解都依赖这一步闭包算错后面全盘皆错。3. 范式判断从 1NF 到 BCNF 的快速判定顺序3.1 四条范式的定义背下来不如合用课件给出的范式定义是这样的范式核心条件1NF每个分量都是不可再分的数据项表中不能套表单元格不能存多值2NF满足 1NF且每一个非主属性完全函数依赖于候选码3NF满足 2NF且每一个非主属性不传递依赖于候选码BCNF满足 3NF且每一个函数依赖的左侧都包含候选码很多人的误区是把这四行当成口诀背熟然后去做题结果发现课本例题能看懂换一道题就卡住。原因在于定义描述的是“结果状态”而题目给的是“函数依赖集合”你需要在两者之间搭一座桥。桥上走的顺序就是下面要说的判定步骤。3.2 面对一个关系模式我的判定顺序是固定的我拆完这套课件后给自己总结了一套固定动作每个判断题都按这个顺序走基本不会漏判先求候选码。用闭包把所有候选码找出来标记主属性和非主属性。再检查 1NF。看是否存在组合属性、多值属性一般题目默认满足但最好扫一眼。然后检查 2NF。看是否存在非主属性对候选码的部分依赖。这里有一个容易忽略的细节只要非主属性对“任何一个候选码”存在部分依赖就不满足 2NF。如果题目给的是复合候选码例如学号课程号同时有学号→姓名那姓名就是部分依赖范式等级直接被压到 1NF。再检查 3NF。看是否存在非主属性对候选码的传递依赖。例如学号→系系→系主任系主任就是传递依赖范式等级最高到 2NF。最后检查 BCNF。如果已经确认是 3NF把 F 中每一条依赖的左侧与全部候选码逐个对比。只要有左侧不是超码就不满足 BCNF。这个顺序的精髓是倒推先拿最宽松的条件去卡卡不过就往低范式归卡过了再往上走。直接照着定义去“感觉”很容易被一个复合候选码带偏。3.3 一道综合题从 1NF 一路推到 BCNF课件里通常会给几道综合题来演示这个过程。我挑一道典型的展开。关系模式 R(U, F)U{学号系系主任课程号成绩}F{学号→系系→系主任(学号, 课程号)→成绩}。问 R 最高属于第几范式。先求候选码。L 类属性是学号、课程号因为这两个属性只出现在依赖左侧。求学号课程号的闭包学号→系系→系主任(学号, 课程号)→成绩最终得到全部属性所以候选码是学号课程号。然后看 2NF。学号→系系是属性而学号是候选码的真子集所以系对候选码存在部分依赖。非主属性中的姓名、系、系主任都存在部分依赖问题因此 R 不满足 2NF最高只能是 1NF。实际修复方法是把学号相关的属性拆出去形成学生表学号姓名系系主任和选课表学号课程号成绩。再看另一个例子。R(U, F)U{学号系系主任}F{学号→系系→系主任}。候选码是学号没有部分依赖所以满足 2NF但存在学号→系→系主任的传递链不满足 3NF最高是 2NF。拆成学号系和系系主任后两个子关系都达到 BCNF。这道题的演进过程其实就是课件后面要讲到的模式分解的动机。每次提升范式本质都是拆表。3.4 3NF 和 BCNF 之间那条线是主属性的依赖3NF 修掉了非主属性对候选码的部分依赖和传递依赖但有一个盲区主属性之间仍然可能存在不合理的依赖关系。BCNF 就是来补这个洞的。教材里有个经典例子仓库管理关系仓库管理员物品。业务规则是每个仓库有多名管理员每名管理员只在一个仓库工作每种物品存放在一个仓库且由一名管理员统一负责。函数依赖是管理员→仓库(仓库, 物品)→管理员。候选码有两个仓库物品和管理员物品。这个关系里没有非主属性所以它一定满足 3NF。但它不满足 BCNF因为函数依赖“管理员→仓库”的左侧是管理员而管理员不是候选码。这个例子是整章最容易踩晕的地方。很多同学看到“没有非主属性”就松了口气直接判定 BCNF结果被人问“管理员→仓库的左侧是超码吗”就答不上来。要记住BCNF 要求的是 F 中每一条依赖的左侧都包含候选码哪怕依赖涉及的是主属性也必须遵守。从工程选型角度看3NF 和 BCNF 是两种可用的设计风格。3NF 保证依赖不丢失查询时可能需要更多连接BCNF 结构更干净但某些依赖可能守不住。课件在讲完这个区别后就会自然过渡到模式分解算法让这两种范式都能落地。4. 模式分解无损连接与保持函数依赖怎么兼得4.1 先搞懂两个验收指标拆表谁都会拆完怎么验收才是这一章的硬核部分。模式分解有两个基本指标期末考试必考实际设计中也绕不开。无损连接性把分解后的子表做自然连接结果必须与原表完全一致既不能少元组也不能多出没有依据的元组。多出来的元组是原表里不存在的假数据常见原因就是拆表时把不该拆的属性拆散了最后连接时产生笛卡尔积的碎片。保持函数依赖原函数依赖集 F 中每一条依赖在分解后的子模式中要么完整存在要么能被子模式的依赖集推导出来。否则数据库在维护完整性约束时会失效可能出现违反原规则的更新。两者不是一回事。无损连接管数据是否还原保持依赖管约束是否能继续执行。课件里给出的结论很重要3NF 分解算法能同时满足这两个指标BCNF 分解算法只保证无损连接不保证保持函数依赖。后者不是算法缺陷而是 BCNF 本身的约束太强某些依赖就是放不进任何子模式。提示做题时如果题干说“要求无损连接且保持函数依赖”默认答案得走 3NF 合成算法说“只要无损连接”才能放心用 BCNF 分解。4.2 3NF 和 BCNF 的分解算法按步骤抄就行3NF 合成算法的步骤课件里一般分成三步求 F 的最小函数依赖集 Fm。先把每个依赖右侧拆成单属性再删掉冗余的依赖最后去掉依赖左侧的冗余属性。把 Fm 中左侧相同的依赖合并每个分组生成一个关系模式属性集合是左侧和右侧的并集。检查生成的所有关系模式中是否存在一个包含原关系的任一候选码。如果没有额外增加一个以候选码为属性的关系模式。用一道例题走一遍。设 R(A, B, C, D)F{AB→C, C→D, D→A}。先求最小依赖集每条依赖的右侧已经是单属性也不能删掉任何依赖所以 FmF。按左侧分组AB→C 得到 R1(A, B, C)C→D 得到 R2(C, D)D→A 得到 R3(D, A)。再检查候选码。AB 的闭包是 {A, B, C, D}AB 是候选码R1 包含 AB满足第三步的条件不需要额外增加候选码关系。最终分解结果是 R1、R2、R3F 中每条依赖都能在对应子关系里直接找到保持依赖成立。BCNF 分解算法的思路是递归拆找一个违反 BCNF 的依赖 X→Y条件是 X 的闭包不是全集。把原关系拆成两个子关系R1 X∪YR2 R - Y。对 R1、R2 继续执行上述检查直到所有子关系都满足 BCNF。用前面仓库那个例子说明。R(仓库管理员物品)依赖为管理员→仓库(仓库, 物品)→管理员。违反 BCNF 的依赖是管理员→仓库拆成 R1(管理员仓库) 和 R2(管理员物品)。R1 满足 BCNFR2 也满足 BCNF。但原依赖 (仓库, 物品)→管理员 在 R2 中只剩管理员物品缺少仓库属性无法被验证所以依赖丢失了。这就是为什么 BCNF 分解被允许不保持函数依赖。实际做设计时我一般倾向先用 3NF 合成算法拿出一个无损且保持依赖的方案再评估是否需要进一步拆成 BCNF。如果业务对冗余很敏感且不介意少量依赖丢失再切到 BCNF。4.3 多值依赖与 4NF容易跳但别完全不看课件讲到 4NF 时篇幅明显变少很多复习的人会跳过但考研真题偶尔会出一道概念题期末也可能以选择题出现所以至少要理解它的存在。多值依赖记作 X→→Y含义是给定 X 的值Y 有一组值与 X 对应且这组值与关系中其他属性无关。函数依赖是“一对一”多值依赖是“一对多且互相独立”。经典例子是课程、教师、参考书三者的关系。一门课程有多个教师一门课程有多本参考书教师和参考书之间没有关联。关系 R(C, T, B) 中候选码是全码C, T, B没有函数依赖违反 BCNF所以它满足 BCNF。但存在多值依赖 C→→T 和 C→→B而 C 不是候选码因此不满足 4NF。4NF 的定义是对于关系中每一个非平凡多值依赖 X→→YX 必须包含候选码。修复方式是把 R 拆成 R1(C, T) 和 R2(C, B)让每个子表只保留一组多值属性。多值依赖的判断比函数依赖抽象不少做题时可以把它理解成“属性之间是否存在两组独立变化的值”不必过度深挖。5. 避坑范式题和分解题的五处翻车现场5.1 闭包永远算不全总在第一步就停下来现象给定 F{A→B, B→C, C→D}求 A很多人在得到 {A, B, C} 后就停手漏掉 D导致候选码判断出错。原因闭包计算是一个循环扩展过程新加入的属性可能触发下一步依赖但初学者往往只扫描一遍依赖就收工。解决每完成一轮合并就重新扫描全部函数依赖直到连续一轮没有任何新增属性为止。我习惯在草稿上记录每一轮新增的属性最后一步能清晰地看到闭包收敛过程。5.2 候选码找错后面全白做现象题目属性较多时候选码要么漏掉 LR 类属性组合要么把 R 类属性选进去。原因只靠“凭感觉看哪个字段像主键”来做题没有套用 L、R、LR、N 属性分类法。解决先按分类法标注每个属性L 类和 N 类强制进入候选码集合R 类排除。用 LN 集合求闭包如果覆盖不了全集再逐个尝试并入 LR 属性直到找到闭包等于全集的组合。这一步骤是我做所有范式题的第一动作。5.3 拿“没有非主属性”当 BCNF 的挡箭牌现象关系 R(仓库管理员物品)没有非主属性被直接判成 BCNF。原因BCNF 的定义不仅要求无部分依赖、无传递依赖还要求 F 中每个依赖左侧都含候选码。主属性之间的依赖同样需要检查。解决判断 3NF 之后再增加一步把 F 中每个依赖左侧与候选码列表逐条对照。管理员→仓库 的左侧是管理员而候选码是仓库物品和管理员物品管理员不是超码所以只能停在 3NF。5.4 Chase 表格法把行填混扫描一次就放弃现象做无损连接验证时初始表填错或者依赖扫描只跑一轮就下结论导致明明无损被判定为有损或者反过来。原因无损连接的表格法需要反复扫描依赖直到表格不再变化。很多同学把它当成普通的填表题扫完一遍就收手。解决初始表的第一行到第 n 行先按“该属性是否属于当前子模式”机械地填好 a 或 b再逐一扫描依赖。扫描过程中只要某行左侧属性全变成 a就要把右侧同步更新为另一行对应位置的 a。全部依赖扫描完一轮后如果表格还有变化就再来一轮直到无变化为止。最后查看是否有一行全部为 a。5.5 分解完丢了函数依赖拆得爽验得少现象用 3NF 合成算法做完分解重新核对时发现某条依赖右侧属性分散在不同子表里无法被检查。原因合并左侧分组时漏掉部分依赖或者在删冗余依赖时删过头把能推导其他属性的关键依赖去掉了。解决分解结束后必须反向验证 F 中每一条原始依赖。对每条 X→Y检查是否有某个子关系同时包含 X 和 Y 的全部属性如果没有尝试用所有子关系的依赖集联合推导。推不出来说明分解没有保持函数依赖需要回到最小依赖集那一步重新做。6. 课件的正确用法三遍复习法与一份可抄的自测清单6.1 三遍复习法先框架后定义最后闭卷做题这套课件信息密度不低直接逐页精读效率很低。我的建议是分三遍走。第一遍只看每节的小标题和页面上的大标题把整章框架在纸上写出来目标是能说出“函数依赖、候选码、范式、分解”这几块的关系。第二遍逐页看定义和例题重点是把我在这篇文章里写的判定步骤用自己的话抄一遍抄的过程就是记忆过程。第三遍合上 PPT拿纸笔闭卷做课件里的每道例题做完再翻页对答案。三遍之间至少隔一天那个间隔能检验你是不是真的记进去了。6.2 自测清单能打勾的才是真会以下 7 项是这一章的核心能力每一项都能在 15 分钟内完成自测序号自测项通过标准1求属性集的闭包能对给定 F 循环扩展不遗漏传递依赖2求候选码能用 L/R/LR/N 分类法找出全部候选码3判断范式等级能从 1NF 到 BCNF 逐级卡条件给出依据4验证无损连接能完成 Chase 表格法全过程并给出结论53NF 合成算法能写出最小依赖集、分组、候选码检查三步6BCNF 分解能指出违反 BCNF 的依赖并完成一次递归拆解7区分函数依赖与多值依赖能解释课程、教师、参考书例子为什么不是 4NF这张表就是我自己复习时贴在电脑屏幕旁的东西。每做完一项就在旁边写“过”没过就回去翻对应页码不盲目往下走。说到这儿想起我自己当年的教训。期末复习图快把范式定义缩成两句话背下来觉得不过如此。结果试卷给的复合候选码我按单候选码的思路去判从 2NF 开始就错了一半。分数出来才意识到整章的关键根本不在记住定义而在于每次判断都先求候选码。从那以后我做任何范式题都强制自己在草稿纸上先写候选码这个习惯一直留到现在。希望这份课件能帮你少走这段弯路希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询