关系数据库理论之最小函数依赖集「建议收藏」

关系数据库理论之最小函数依赖集「建议收藏」前言在本文中,会介绍为什么要引入最小函数依赖集,最小函数依赖集是什么,以及如何求最小函数依赖集。为什么需要最小函数依赖集在关系数据模型中,一个关系通常由R(U,F)构成,U为属性的全集,F为函数依赖集。在实际生活中,我们可以根据语义来定义关系中属性的依赖关系,例如学号可以唯一确定一位学生的姓名、性别等等。但是,有时候给出的函数依赖集并不是最简的,这有时会拖累我们对关系的后续处理,例如关系的分…

大家好,又见面了,我是你们的朋友全栈君。

前言

在本文中,会介绍为什么要引入最小函数依赖集,最小函数依赖集是什么,以及如何求最小函数依赖集。

为什么需要最小函数依赖集

在关系数据模型中,一个关系通常由R(U,F)构成,U为属性的全集,F为函数依赖集。在实际生活中,我们可以根据语义来定义关系中属性的依赖关系,例如学号可以唯一确定一位学生的姓名、性别等等。但是,有时候给出的函数依赖集并不是最简的,这有时会拖累我们对关系的后续处理,例如关系的分解、判断是否为无损分解等。所以,我们在必要时,需要对函数依赖集进行化简,这就是需要最小函数依赖集的原因。
在正式介绍最小函数依赖集之前,还需要了解一个概念,那就是闭包。准确的说是属性集X关于函数依赖集F的闭包

闭包

闭包分为两种,一种是函数依赖集F的闭包,另外一种是属性集X关于函数依赖集F的闭包。前者不做讨论,重点说说后者。先来看定义

F为属性集U上的一组函数依赖集,XY ∈ \in U X F + X_F^+ XF+= {
A|X → \rightarrow A能由F根据Armstrong公理导出}, X F + X_F^+ XF+称为属性集X关于函数依赖集F的闭包。

说白了,就是给定属性集X,根据现有的函数依赖集,看其能推出什么属性。
这里的Armstrong公理系统不用深究,想具体了解的可以点击查看百度百科。
举例:

已知关系模式R<U,F>,其中:
U = {
A,B,C,D,E},
F = {
AB → \rightarrow C,B → \rightarrow D,C → \rightarrow E,EC → \rightarrow B,AC → \rightarrow B}
( A B ) F + (AB)_F^+ (AB)F+

解:

从AB出发,此时我们的集合里已经包含了{A,B}。
我们从现有的函数依赖集中可知,
AB可以推出C,于是C加入集合,
B可以推出D,于是D加入集合,
C可以推出E,于是E加入集合,
EC可以推出B,因为C、E、B都在集合中,于是不加入,
AC可以推出B,因为A、B、C都在集合中,于是不加入
至此,可求得 ( A B ) F + (AB)_F^+ (AB)F+ ={A、B、C、D、E}。

最小函数依赖集

定义

如果函数依赖集F满足下列条件,则称F为一个极小函数依赖集,亦称为最小依赖集最小覆盖
(1)、F中任一函数依赖右部仅含有一个属性。
(2)、F中不存在这样的函数依赖 X → \rightarrow A,使得FF-{X → \rightarrow A} 等价。
(3)、F中不存在这样的函数依赖X → \rightarrow AX有真子集Z使得F-{X → \rightarrow A} ⋃ \bigcup {
Z → \rightarrow A}
F等价。

解释

以上定义翻译成大白话就是,一个函数依赖集F要想称为最小函数依赖集,要满足以下三点:
1、F中任一函数依赖的右边只有一个属性。
2、F中不存在这样的函数依赖:从现有的函数依赖集中删除一个函数依赖X → \rightarrow A,删除后所得的函数依赖集与原来的函数依赖集等价,这样的函数依赖是不允许存在的。
3、F中不存在这样的函数依赖:假设函数依赖集中存在AB → \rightarrow Y,现对该依赖的左部进行化简,即删除A,得B → \rightarrow Y;或删除B,得A → \rightarrow Y,若经过化简后的函数依赖集与没有化简前的函数依赖集等价,那么这样的函数依赖是不允许存在的。

算法

1、首先,先利用函数依赖的分解性,将函数依赖集中右部不为单个属性的分解为单属性。

2、对于经过第1步筛选后的函数依赖集F中的每一个函数依赖X → \rightarrow A,进行以下操作:

  • 2.1、将X → \rightarrow A从函数依赖中剔除
  • 2.2、基于剔除后的函数依赖,计算属性X的闭包,看其是否包含了A,若是,则该函数依赖是多余的(这里体现出前面说的等价,因为如果基于化简后的函数依赖依赖,计算X的闭包依然包含A,则说明A可以由其他依赖推出,X → \rightarrow A不是必须的),可以删除,否则不能删除

3、对于经过第2步筛选后的函数依赖集F中每个左部不为单个属性的函数依赖AB → \rightarrow Y,进行以下操作:
我们约定,经过第二步筛选后的函数依赖集记为F1,经过第三步处理后的函数依赖集为F2。

  • 3.1、去除A,得B → \rightarrow Y,得F2,基于F1和F2计算属性B的闭包,如果二者相等,则说明它们是等价的,A可以去除;如果不相等,则A不能去除。
  • 3.2、去除B,得A → \rightarrow Y,得F2,基于F1和F2计算属性A的闭包,如果二者相等则说明它们是等价的,B可以去除;如果不相等,则B不能去除。

知识链接:函数依赖的分解性
若X → \rightarrow YZ,则X → \rightarrow Y 且 X → \rightarrow Z。

举例

关系模式R(U,F)中,U={A,B,C,D,E,G},F={B → \rightarrow D,DG → \rightarrow C,BD → \rightarrow E,AG → \rightarrow B,ADG → \rightarrow BC};求F的最小函数依赖集。

解:
1、首先根据函数依赖的分解性,对F进行第一次筛选,需要变动的有:
ADG → \rightarrow BC拆解成ADG → \rightarrow B、ADG → \rightarrow C
得新函数依赖集:
F = {B → \rightarrow D,DG → \rightarrow C,BD → \rightarrow E,AG → \rightarrow B,ADG → \rightarrow B,ADG → \rightarrow C}

2、筛选多余的函数依赖

  • 2.1:去除B → \rightarrow D,得F = {DG → \rightarrow C,BD → \rightarrow E,AG → \rightarrow B,ADG → \rightarrow B,ADG → \rightarrow C}, B F + B_F^+ BF+ = {B},不包含D,故B → \rightarrow D不删除。
  • 2.2:去除DG → \rightarrow C,得F = {B → \rightarrow D、BD → \rightarrow E,AG → \rightarrow B,ADG → \rightarrow B,ADG → \rightarrow C}, ( D G ) F + (DG)_F^+ (DG)F+={D,G},不包含C,故DG → \rightarrow C不删除。
  • 2.3:去除BD → \rightarrow E,得F = {B → \rightarrow D,DG → \rightarrow C,AG → \rightarrow B,ADG → \rightarrow B,ADG → \rightarrow C}, ( B D ) F + (BD)_F^+ (BD)F+ = {B,D},不包含E,故BD → \rightarrow E不删除。
  • 2.4:去除AG → \rightarrow B,得F = {B → \rightarrow D,DG → \rightarrow C,BD → \rightarrow E,ADG → \rightarrow B,ADG → \rightarrow C}, ( A G ) F + (AG)_F^+ (AG)F+ = {A,G},不包含B,故AG → \rightarrow B不删除。
  • 2.5:去除ADG → \rightarrow B,得F = {B → \rightarrow D,DG → \rightarrow C,BD → \rightarrow E,AG → \rightarrow B,ADG → \rightarrow C}, ( A D G ) F + (ADG)_F^+ (ADG)F+ = {A,D,G,C,B,E},包含B,故ADG → \rightarrow B去除
  • 2.6:去除ADG → \rightarrow C,得F = {B → \rightarrow D,DG → \rightarrow C,BD → \rightarrow E,AG → \rightarrow B,ADG → \rightarrow B}, ( A D G ) F + (ADG)_F^+ (ADG)F+ = {A,D,G,C,B,E},包含C,故ADG → \rightarrow C去除
    经过第二部筛选后,函数依赖集F变为{B → \rightarrow D,DG → \rightarrow C,BD → \rightarrow E,AG → \rightarrow B}。

3、化简函数依赖左侧不为单个属性的函数依赖

  • 3.1:先看DG → \rightarrow C
    • 3.1.1:去除D,得G → \rightarrow C,得函数依赖集F1 = {B → \rightarrow D,G → \rightarrow C,BD → \rightarrow E,AG → \rightarrow B}。
      基于F1,可求得 G F + G_F^+ GF+ = {G,C}。
      基于F(第二步求出的,下同),可求得 G F + G_F^+ GF+ = {G}
      可见二者并不相同,所以D不去除。
    • 3.1.2:去除G,得D → \rightarrow C,得函数依赖集F1 = {B → \rightarrow D,D → \rightarrow C,BD → \rightarrow E,AG → \rightarrow B}
      基于F1,可求得 D F + D_F^+ DF+ = {D,C}
      基于F,可求得 D F + D_F^+ DF+ ={D}
      可见二者并不相同,所以G不去除。

综上,DG → \rightarrow C,已是最简。

  • 3.2:再看BD → \rightarrow E
    • 3.2.1:去除B,得D → \rightarrow E,得函数依赖集F1 = {B → \rightarrow D,DG → \rightarrow C,D → \rightarrow E,AG → \rightarrow B}
      基于F1,可求得 D F + D_F^+ DF+ = {D,E}
      基于F,可求得 D F + D_F^+ DF+ = {D}
      可见二者并不相同,所以B不去除。
    • 3.2.2:去除D,得B → \rightarrow E,得函数依赖集F1 = {B → \rightarrow D,DG → \rightarrow C,B → \rightarrow E,AG → \rightarrow B}
      基于F1,可求得 B F + B_F^+ BF+ = {B,E,D}
      基于F,可求得 B F + B_F^+ BF+ = {B,D,E}
      可见二者相同,所以D可以去除

综上,BD → \rightarrow E,可化简为B → \rightarrow E。

  • 3.3:最后看AG → \rightarrow B
    • 3.3.1:去除A,得G → \rightarrow B,得函数依赖集F1 = {B → \rightarrow D,DG → \rightarrow C,B → \rightarrow E,G → \rightarrow B}
      基于F1,可求得 G F + G_F^+ GF+ = {G,B}
      基于F,可求得 G F + G_F^+ GF+ = {G}
      可见二者并不相同,所以A不可去除。
    • 3.3.2:去除G,得A → \rightarrow B,得函数依赖F1 = {B → \rightarrow D,DG → \rightarrow C,B → \rightarrow E,A → \rightarrow B}
      基于F1,可求得 A F + A_F^+ AF+ = {A,B}
      基于F,可求得 A F + A_F^+ AF+ = {A}
      可见二者并不相同,所以G不可去除。

综上,AG → \rightarrow B,已是最简。
综上,R的最小函数依赖集为F = {B → \rightarrow D,DG → \rightarrow C,B → \rightarrow E,AG → \rightarrow B}

写在最后

这个问题是我在考研复试的时候复习过程中遇到的,主要的纠结点在于第三步的判断上,查资料的时候发现网上很多都没有写清,最后还是在度娘的文库里找到了比较清楚的解释,在此做一下思路的整理。
本文定义以及例子参考自:

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/149857.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • mysql5.7安装及配置超详细教程_mysql安装教程 linux

    mysql5.7安装及配置超详细教程_mysql安装教程 linuxMySQL5.7.35安装教程下载工具官网下载下载在下图中选择你自己需要的版本即可第二种下载方式如下图所示下载下载完成后对工具包进行解压,我解压的在D盘解压好过后在里面新建my.ini文件(如果你不知道怎么创建my.ini文件请看)右击新建文本文档创建文本文档过后进行重命名讲文本文档的后缀名改为ini如图操作再将新建的文本文档改名为my.ini编辑my.ini文件将下面的代码复制进去记得更改里面【basedir】【datadir】的路径为你自己的安装路径[mysqld]#

    2022年8月22日
    13
  • windows服务器解决挖矿程序问题

    windows服务器解决挖矿程序问题windows服务器解决挖矿程序问题

    2022年6月17日
    26
  • win7 java修复工具哪个好_DLL修复工具哪个好

    win7 java修复工具哪个好_DLL修复工具哪个好为什么会用到dll修复工具呢?因为在打开某些程序或者软件的时候会提示找不到某某.dll文件,关键是这些dll文件还不一样,去网上下载这些dll文件结果显示跟系统的版本不一致,反正就是各种麻烦,自己去找又费时又费力,而且往往对于有些游戏来说,修补了某一个dll又提示缺少另一个dll文件,这些其实可能都是系统本身太精简或者没有安装一些依赖软件导致的,这时候你完全不需要手动去找这些dll文件,只需要使用…

    2022年5月11日
    42
  • JAVA日期格式化(Simpledateformat)

    Java日期格式化常用方法Java中Date类中的一些日期格式话方法都已过期,所以不推荐使用。一般格式化时,常用到这两个类:Calendar和SimpleDateFormat,使用方法如下:1.Calendar类Calendar类是abstract的,所以实例化方式得用静态方法:Calendarc=Calendar.getInstance();,此时的生成的实例依据的是当前系统时间;c.se…

    2022年4月17日
    554
  • pycharm 全局搜索快捷键「建议收藏」

    pycharm 全局搜索快捷键「建议收藏」pycharm全局搜索快捷键:ctrl+shift+f如果快捷键被系统占用了,那么在pycharm中是不能使用的,我使用的win10自带的输入,这里是已经存在的快捷键,需要关闭才可以使用

    2022年5月31日
    123
  • linux中find命令基本使用方法_find命令用法及参数

    linux中find命令基本使用方法_find命令用法及参数Linux系统find命令用法Linux查找命令find是Linux系统中最重要和最常用的命令之一,用于查找与指定参数条件匹配的文件及目录列表。find查找命令可以在各种条件下使用,我们可以通过权限,用户,组,文件类型,修改日期,大小等多种条件来查找文件。这里我会以实例的形式向大家说明find命令的具体用法。find命令的格式很简单,一般分成三个部分:1)find命令;2)搜索路径(目录可以写多个);3)表达式。对于find命令,最需要学习的是表达式这一段。表达式决定了我们要找的文件是什么属性的文件

    2022年8月31日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号