数据库建模和设计(2):函数依赖、闭包、最小函数依赖集、范式、模式分解

本文深入探讨了关系数据库中的核心概念,包括函数依赖、候选键、Armstrong公理系统、范式理论及其应用。通过丰富的实例讲解了如何进行模式分解以达到特定的范式要求,确保数据的完整性和减少冗余。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、函数依赖:

在关系R中,若属性或者属性集 A 中 两个元祖的值相等,如果这两个元祖中对应的属性或者属性集B中的值也相同,则记作A——>B。 A函数决定B; 或者 B函数依赖于A。

例1:下表就是问题领域, 则存在的函数依赖有哪些呢?


属性A的值都不相等,所以A--->B;  而属性B中前两行元祖相同,对应的属性C的前两组元祖也相同,所以B----->C;

而属性C的三行元祖是全部相同的,对应的属性A和属性B,没有三行元祖的值是全部一样的,所以C函数不决定任何.


属性A的元祖的值相同的时候,对应的属性C元祖的值也都相同,所以A--->C

而属性B元祖的值相同的时候,没有全部一样的属性对应的元祖的值也一样。(b2的值虽然和d2的值对应,但是值为b3的两个元祖对应的是d3、d4,值不是相同的,故:B不能决定D;

而属性C中,前两行的元祖的值相同,对应的A属性中的前两行元祖的值也相等,但是属性C后三行的值c2是都一样的,在A、B、D属性中,后三行的值没有完全一样的,故:C也不能决定其他。

属性D中第2、3行中的值相等,对应的属性B中,第2、3行的元祖的值也是相等的,所以:D----->B;


对X——>Y,若Y⊄X,则称X→Y为非平凡的函数依赖; 如:(职工号,姓名)→性别,职工号——>姓名;

平凡函数依赖:(职工号,姓名)→姓名;  (职工号,性别)——>性别;

1、完全函数依赖:

设X,Y是关系R的两个属性集合,X’是X的真子集,存在X→Y,但对每一个X’都有X’!→Y,则称Y完全函数依赖于X。

比如:(学号,课号)——>成绩;   单独一个学号,不能决定成绩,单独一个课程,也不能决定成绩;只有二者同时,才能决定;

2、部分函数依赖:

设X,Y是关系R的两个属性集合,存在X→Y,若X’是X的真子集,存在X’→Y,则称Y部分函数依赖于X。

(学号,课号)——>姓名;学号和课号能决定姓名, 单独一个 学号 也能决定 姓名;

3、传递函数依赖:

设X,Y,Z是关系R中互不相同的属性集合,存在X→Y(Y !→X),Y→Z,则称Z传递函数依赖于X。

学号——>系号,系号——>系主任;       系主任   传递依赖于  学号;

二、候选键:


(1)可任选一候选键作为R的主键(Primary Key);    即:当候选码多于一个时,选定其中一个作为主码

(2)包含在任一候选键中的属性称主属性(Prime Attribute),其他属性称非主属性

(3)若K是R的一个候选键,SK, 则称S为R的一个超键(Super Key)。

(4)若k是候选键(码),则必须满足两个条件,k的闭包是U,k没有冗余。

2、候选码的确定(算法)

设关系模式R中U=ABC.......等N个属性,U中的属性在FD中有四种范围:

(1)左右出现;
(2)只在左部出现;
(3)只在右部出现;
(4)不在左右出现;

算法:按以下步骤求候选键:
1.只在FD右部出现的属性,不属于候选码;
2.只在FD左部出现的属性,一定存在于某候选码当中;
3.外部属性一定存在于任何候选码当中;  (左右都不出现)

4.其他属性逐个与2,3的属性组合,求属性闭包,直至X的闭包等于U,若等于U,则X为候选码。

3、候选码以及属性相关的案例;

U={学号,姓名,年龄,班号,班长,课号,成绩 }     

候选键:学号,课号;

主属性:学号,课号;(主要的属性,能决定其他属性的),  即:学号,课号称为U的主属性;

非主属性:U中剩余的属性,即:姓名,年龄,班号,班长,成绩;

例1:R<U,F>,U=(A,B,C,D,E,G),F={AB-->C,CD-->E,E-->A.A-->G},求候选码以及主属性。

因为:G只在右边出现,所以候选码肯定不包含G,AB只出现在左边,所以,候选码中肯定有BD,而BD的闭包还是BD,则对BD进行组合,除了G以外,BD可以跟A,C,E进行组合。

  先看ABD
  ABD本身自包ABD,而AB-->C,CD-->E,A-->G,所以ABD的闭包为ABDCEG=U
  再看BDC
  CD-->E,E-->A,A-->G,BDC本身自包,所以BDC的闭包为BDCEAG=U
  最后看BDE
  E-->A,A-->G,AB-->C,BDE本身自包,所以BDE的闭包为BDEAGC=U

  因为(ABD)、(BCD)、(BDE)的闭包都是ABCDEG所以本问题的候选码有3个分别是ABC、BCD和BDE

 

候选码:ABC,BCD,BDE;

主属性:ABCDE;

非主属性:G;

例2:R<U,F>,U=(A,B,C),F={AB-->C,C-->B},求候选码。

因为:A只出现在左边,所以候选码中肯定存在A,然而A的闭包还是A,所以需要对A进行组合,可以和B,C进行组合。

先看AB

  AB本身自包AB,而AB-->C,所以AB的闭包为ABC=U;

再看AC

  C-->B,而AC本身自包AC,所以AC的闭包为ABC=U;

候选码:AB,AC

主属性:ABC;              非主属性:无;        此时又称为 全码。(所有属性构成码)。


三、Armstrong公理系统

设关系模式R<U,F>,其中U为属性集,F是U上的一组函数依赖,那么有如下推理规则

① A1自反律:若Y⊆X⊆U,则X→Y为F所蕴含;                    即:ABC→AB;   AB——>A (平凡依赖函数);
② A2增广律:若X→Y为F所蕴含,且Z⊆U,则XZ→YZ为F所蕴含;
③ A3传递律:若X→Y,Y→Z为F所蕴含,则X→Z为F所蕴含。
根据上面三条推理规则,又可推出下面三条推理规则:
④ 合并规则:若X→Y,X→Z,则X→YZ为F所蕴含;
⑤ 伪传递规则:若X→Y,WY→Z,则XW→Z为F所蕴含;  即:A→B,AC→BC;BC→D ;得出AC→D;
⑥ 分解规则:若X→Y,Z⊆Y,则X→Z为F所蕴含。      即:A→BC;  能得出:  A→B,A→C;

四、闭包:

闭包就是由一个属性直接或间接推导出的所有属性的集合。


例如:f={a->b,b->c,a->d,e->f};由a可直接得到b和d,间接得到c,则a的闭包就是{a,b,c,d};

已知关系R(A1,A2,A3,A4,A5,A6),函数依赖集F为{ (A2,A3)——>A4,A3——>A6,(A2,A5)——>A1 }, 问(A2,A3)关于F的属性闭包为:{A2,A3,A4,A6};  因为:A2,A3能带到A4,A3能得到A6;

已知关系R(A,B,C,D,E,F,G),函数依赖集F为{ A ——>B,B——>D,AD——>EF,AG——>C}, 问:A关于F的属性闭包为:{A,B,D,E,F};     因为:A能得到B,B能得到D,AD能得到EF;

五、最小函数依赖集(最小覆盖):

1、定义:

如果函数依赖集F满足以下条件,则称F为一个极小函数依赖集。也称为最小依赖集或最小覆盖。

(1)F中任一函数依赖的右部仅含有一个属性。

(2)F中不存在这样的函数依赖X→A,使得F与F-{X→A}等价。

(3)F中不存在这样的函数依赖X→A,X有真子集Z使得F-{X→A}U{Z→A}与F等价。

2、最小依赖集通用算法:

① 用分解的法则,使F中的任何一个函数依赖的右部仅含有一个属性;

② 去掉多余的函数依赖:从第一个函数依赖X→Y开始将其从F中去掉,然后在剩下的函数依赖中求X的闭包X+,看X+是否包含Y,若是,则去掉X→Y;否则不能去掉,依次做下去。直到找不到冗余的函数依赖;

③ 去掉各依赖左部多余的属性。一个一个地检查函数依赖左部非单个属性的依赖。例如XY→A,若要判Y为多余的,则以X→A代替XY→A是否等价?若A属于(X)+,则Y是多余属性,可以去掉。(以上步骤中,求出关系依赖集F,此时,再F的基础上,求出X或者Y的闭包,是否包含A)

3、最小依赖集案例:

例1:关系模式R(U,F)中,U=ABCDEG,F={B->D,DG->C,BD->E,AG->B,ADG->BC};求F的最小函数依赖集

步骤:

(1)用分解的法则,使F中的任何一个函数依赖的右部仅含有一个属性;得到:F={ B->D,DG->C,BD->E,AG->B,ADG->B,ADG->C};

(2)去掉多余的函数依赖:从第一个函数依赖X→Y开始将其从F中去掉,然后在剩下的函数依赖中求X的闭包X+,依次做下去。直到找不到冗余的函数依赖;

① 去掉B->D,此时F={ DG->C,BD->E,AG->B,ADG->B,ADG->C},此条件下得出B的闭包 B+ = B;B+不包含D,所以B->D保留。

②去掉DG->C,此时F={ B->D,BD->E,AG->B,ADG->B,ADG->C},此时DG闭包DG+ = DG,不包含C,所以不能去掉DG->C.

③ 去掉BD->E,此时F={ B->D,DG->C,AG->B,ADG->B,ADG->C},此时闭包BD+ = BD,不包含E,所以不能去掉BD->E,继续保留。

④去掉AG->B,此时F={ B->D,DG->C,BD->E,ADG->B,ADG->C};此时AG+ = AG,不包含B,所以不能去掉AG->B,继续保留。

⑤去掉ADG->B,此时F={ B->D,DG->C,BD->E,AG->B,ADG->C},此时ADG+ = ADGCBE,包含了B,所以删除ADG->B,不保留。

去掉ADG->C,此时F={ B->D,DG->C,BD->E,AG->B},此时ADG+ = ADGCBD,包含了C,所以删除ADG->C,不保留。

综上所得,此时得到F={ B->D,DG->C,BD->E,AG->B};

3去掉各依赖左部多余的属性。一个一个地检查函数依赖左部非单个属性的依赖。

此时函数依赖左边非单个属性有:DG->C,BD->E,AG->B;所以做如下操作:

①先来看DG->C,首先去掉D,则此时G的闭包G+ = G,不包含C,保留D。再次去掉G,此时D+ = D,不包含C,所以G也不能去掉;

②再来看

<think>嗯,用户现在问的是关系型数据库中的函数依赖。之前他们问过关系代数中的除运算,可能是在学习数据库理论的基础知识,或者是在准备考试。现在需要解释函数依赖,这可能涉及到数据库设计范式理论这些内容。 首先,用户可能已经了解了除运算,现在转向更基础的概念,比如函数依赖。需要确保解释清楚函数依赖的定义、作用,以及它在数据库设计中的应用,比如在规范化过程中的重要性。 用户可能是学生或者刚入门的开发者,想要理解如何设计高效的数据库结构。他们可能遇到数据冗余或更新异常的问题,而函数依赖是解决这些问题的关键。因此,需要结合实际例子,说明函数依赖如何影响数据库设计,以及如何识别处理不同的依赖类型。 考虑到用户之前的问题,可能已经有一定的理论基础,但需要更深入的解释。要避免过于技术化的术语,用通俗易懂的语言例子来说明。比如,用学生表的例子,学号决定姓名,这样学号→姓名就是一个函数依赖,这样用户更容易理解。 另外,用户可能需要了解函数依赖的分类,比如完全函数依赖、部分依赖、传递依赖,这些是范式分解的基础。需要解释这些概念,并说明它们在消除冗余中的作用。例如,部分依赖会导致2NF的问题,传递依赖导致3NF的问题,这样用户能明白为什么需要分解表结构。 还需要提到阿姆斯特朗公理,虽然可能稍微深入,但作为理论基础,可以简要介绍,说明如何推导函数依赖。不过,如果用户只是需要应用层面的理解,这部分可以简略带过,重点放在实际应用例子上。 用户可能还想知道如何在实际中应用这些理论,比如在数据库设计时如何识别函数依赖,如何通过分解表来达到更高的范式。可能需要给出步骤或方法,比如如何分析属性之间的关系,如何确定候选键等。 最后,要确保回答结构清晰,分点说明,每个部分都有例子辅助理解。避免大段文字,使用列表、示例表格等方式,让信息更易消化。同时,检查是否覆盖了函数依赖的所有重要方面,包括定义、类型、应用、公理系统以及实际意义。</think>### 关系型数据库中的函数依赖详解 #### **1. 基本定义** **函数依赖(Functional Dependency, FD)** 是描述关系模式中属性间逻辑约束的核心概念。 - **形式化表达**:若在关系$R$中,属性$X$的值能唯一确定属性$Y$的值,则称**$X$函数决定$Y$**,记作$X \rightarrow Y$ - 例:在学生表中,学号$sno$决定姓名$sname$,即$sno \rightarrow sname$ - 若$X \rightarrow Y$且$Y \rightarrow X$,则称**$X \leftrightarrow Y$相互依赖** #### **2. 关键性质** | 性质 | 描述 | 数学表达 | |------------|----------------------------------------------------------------------|---------------------------| | **自反性** | 属性总能决定其子 | 若$Y \subseteq X$, 则$X \rightarrow Y$ | | **增广性** | 若$X \rightarrow Y$,则$XZ \rightarrow YZ$ | | | **传递性** | 若$X \rightarrow Y$且$Y \rightarrow Z$,则$X \rightarrow Z$ | | #### **3. 依赖类型** ##### **(1) 完全函数依赖** - **定义**:$X \rightarrow Y$,且$X$的**任何真子**都不能决定$Y$ - 例:在选课表$(sno, cno) \rightarrow score$中,单独$sno$或$cno$都不能确定成绩 - **符号**:$X \stackrel{f}{\rightarrow} Y$ ##### **(2) 部分函数依赖** - **定义**:存在$X$的某个真子$X'$,使得$X' \rightarrow Y$ - 例:在表$(sno, cno, sname)$中,$sno \rightarrow sname$,因此$(sno, cno) \stackrel{p}{\rightarrow} sname$ - **危害**:导致2NF问题 ##### **(3) 传递函数依赖** - **定义**:若$X \rightarrow Y$,$Y \nrightarrow X$,且$Y \rightarrow Z$,则$X \rightarrow Z$ - 例:部门表$dept(dno, dname, location)$中,$dno \rightarrow dname$, $dname \rightarrow location$ - **危害**:导致3NF问题 #### **4. 闭包与覆盖** - **闭包$X^+$**:所有能被$X$函数决定的属性合 - 计算算法: 1. 初始化$X^+ = X$ 2. 循环应用函数依赖,直到不再扩大 3. 例:若$X \rightarrow Y$, $Y \rightarrow Z$,则$X^+ = XYZ$ - **最小覆盖**:满足以下条件的函数依赖$F_{min}$ 1. 每个依赖右边为单个属性 2. 删除任意依赖后不再等价 3. 删除左边任意属性后不再等价 #### **5. 实际应用案例** **场景**:商品订单系统 - 关系模式: $$Order(order\_id, customer\_id, product\_id, quantity, unit\_price, total, customer\_name)$$ **函数依赖分析**: 1. $order\_id \rightarrow customer\_id$ 2. $customer\_id \rightarrow customer\_name$ 3. $(product\_id, order\_id) \rightarrow quantity$ 4. $product\_id \rightarrow unit\_price$ 5. $quantity, unit\_price \rightarrow total$ **问题发现**: - 存在传递依赖$order\_id \rightarrow customer\_id \rightarrow customer\_name$ - 导致数据冗余:同一客户多次下单时需重复存储姓名 **解决方案**: 通过3NF分解为: - 订单表:$Order(order\_id, customer\_id, product\_id, quantity)$ - 客户表:$Customer(customer\_id, customer\_name)$ - 产品表:$Product(product\_id, unit\_price)$ - 计算表:$Total(quantity, unit\_price, total)$ #### **6. Armstrong公理系统** **三大推理规则**: 1. **自反律**:若$Y \subseteq X$,则$X \rightarrow Y$ 2. **增广律**:若$X \rightarrow Y$,则$XZ \rightarrow YZ$ 3. **传递律**:若$X \rightarrow Y$且$Y \rightarrow Z$,则$X \rightarrow Z$ **附加规则**: - **合并规则**:若$X \rightarrow Y$且$X \rightarrow Z$,则$X \rightarrow YZ$ - **分解规则**:若$X \rightarrow YZ$,则$X \rightarrow Y$且$X \rightarrow Z$ #### **7. 与范式的关系** | 范式级别 | 消除的依赖类型 | 示例问题 | |----------|----------------------|----------------------------| | 1NF | 非原子值依赖 | 多值存储(如地址合并字段) | | 2NF | 部分函数依赖 | 主键部分决定非主属性 | | 3NF | 传递函数依赖 | 非主属性间的间接依赖 | | BCNF | 主属性对键的依赖 | 所有非平凡依赖左边包含键 | #### **8. 实际应用价值** 1. **数据库设计**:指导关系模式分解,避免数据冗余 2. **查询优化**:利用依赖关系简化查询条件 3. **完整性约束**:通过FD定义业务规则(如"部门编号决定部门名称") 4. **数据清洗**:检测违反函数依赖的数据异常 #### **9. 特殊依赖类型** - **多值依赖**:$X \twoheadrightarrow Y$,表示$X$决定$Y$的一组值(与FD不同) - **连接依赖**:关系模式可无损分解为多个子模式的约束条件 **函数依赖是关系数据库理论的基石**,理解其原理能有效提升: - 数据库设计的合理性 - 数据存储的空间效率 - 数据更新操作的正确性 - 查询处理的性能优化 通过分析属性间的函数依赖关系,可以系统性地解决数据库设计中的冗余异常问题,为构建高效可靠的数据库系统提供理论保障。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值