zoukankan      html  css  js  c++  java
  • 关系数据库设计

    码和函数依赖:

    令r(R)是一个关系模式。R的子集K是r(R)的超码的条件是:在r(R)中的合法实例中,对于r的实例中的所有元组t1, t2总满足:若t1≠t2则,t1[K]≠t2[K]。也就是说,在关系r(R)中没有两条元组在属性集K上可能具有相同的值。

    考虑关系模式r(R),令a是R的子集,且b是R的子集。

    给定r(R)的一个实例,称这个实例满足函数依赖a→b的条件是:对实例中所有元组t1和t2,若t1[a]=t2[a],则t1[b]=t2[b]。

    如果在r(R)的每个合法实例中都满足函数依赖a→b,则称函数依赖a→b在关系模式r(R)上是成立的。

    有些函数依赖称为平凡的,因为它们在所有关系中都满足。一般地,如果b是a的子集,则形如a→b的函数依赖是平凡的。

    函数依赖理论:

    给定关系模式r(R)上的函数依赖集F,如果r(R)的每一个满足F的实例也满足 f ,则R上的函数依赖 f 被 r 上的函数依赖集F逻辑蕴含。

    Armstrong公理:

    1. 自反律,若a为一属性集且b是a的子集,则a→b成立。
    2. 增补律,若a→b成立且c为一属性集,则ac→bc成立。
    3. 传递律,若a→b和b→c成立,则a→c成立。

    简化Armstrong公理:

    1. 合并律,若a→b和a→c成立,则a→bc成立。
    2. 分解律,若a→bc成立,则a→b和a→c成立。
    3. 伪传递律,若a→b成立和bc→d成立,则ac→d成立。

     F的闭包是被F逻辑蕴含的所有函数依赖的集合,记作F+

    F的闭包F+:

    给定一个关系R的函数依赖集F,则F的闭包F+的算法过程如下:

    F+=F
    repeat
      for each F+中的函数依赖 f
        在f上应用增补律和自反律
        将结果放到F+中
      for each F+中的一对函数依赖f1和f2
        如果f1和f2能用传递律结合起来
        则将结果放到F+中
    until F+不再发生变化

    属性a的闭包a+

    如果a→b,则称b为属性a函数确定。

    令a为一个属性集。则将函数依赖集F下被a函数确定的所有属性的集合称为F下a的闭包,记作a+。计算F下a的闭包a+的算法过程如下:

    result=a
    repeat
      for each 函数依赖 b→c in F do
        begin
          if b 属于result then result=result∪c
        end
    until(result不变)

    如何获取R的所有候选码?

    对于一个关系R,对其属性集合进行任意组合,然后依次计算这些属性组合的闭包。如果某个属性组合的闭包包含所有属性,那么这个属性组合就是候选码。

    属性闭包算法的多种用途:

    1. 为了判断a是否为超码,我们计算a+,检查a+是否包含R中的所有属性。
    2. 通过检查b是否的a+的子集,可以检查出函数依赖a→b是否成立。
    3. 另一种计算F的闭包F+的方法:对任意的a,a是R的子集,可以找出闭包a+,对任意的b,b是a+的子集,可以输出一个函数依赖a→b。

    如果去除函数依赖中的一个属性不改变该函数依赖集的闭包,则称该属性是无关的。

    无关属性的形式化定义如下:考虑函数依赖集F及F中的函数依赖a→b,

    • 如果A是a的一个元素并且F逻辑蕴含(F - {a→b})∪{(a-A)→b},则属性A在a中是无关的。
    • 如果A是b的一个元素并且函数依赖集(F-{a→b})∪{a→(b-A)}逻辑蕴含F,则属性A在b中是无关的。

    无损分解:将关系模式R分解为R1和R2,如果R1∩R2是R1或R2的超码,则R上的分解就是无损的。

    Boyce-Codd范式:

    具有函数依赖集F的关系模式R属于BCNF的条件是,对F+中的所有形如a→b的函数依赖(其中a是R的子集,并且b是R的子集),下面至少有一项成立:

    1. a→b是平凡的函数依赖(即,b是a的子集)
    2. a是模式R的一个超码

    一个数据库设计属于BCNF的条件是,构成该设计的关系模式集中的每个模式都属于BCNF。

    设R为不属于BCNF的一个模式。则存在至少一个非平凡的函数依赖a→b,其中a不是R的超码。则需要在设计中用以下两个模式取代R:

    • a∪b
    • R - ( b - a ) 

    判定方法(避免计算F+是因为F+一般都很大):

    在某些情况下,判定一个关系是否属于BCNF可简化成:

    • 为了检查非平凡的函数依赖a→b是否违反BCNF,计算a+,并且验证它是否包含R中所有属性,即验证它是否是R的超码。
    • 检查关系模式R是否属于BCNF,仅需检查给定集合F中的函数依赖是否违反了BCNF就足够了,不用检查F+中的所有函数依赖。

    需要注意的是,如果一个关系没有被分解,那么我们可以证明如果F中没有函数依赖违反BCNF,那么F+中也不会有函数依赖违反BCNF。但是当一个关系分解后,这个结论将不再成立。

    所以为了检查R分解后的关系Ri是否属于BCNF,可以用如下判定:

    • 对于Ri中属性的每个子集a,确保a+要么不包含Ri-a的任何属性,要么包含Ri的所有属性。

    如果Ri上有某个属性集a违反了该条件,考虑如下的函数依赖,可以证明它出现在F+中:

             a→(a+-a)∩Ri

    分解方法:

    给出一个关系模式R,若R不属于BCNF,则可用下面的算法将R分解成一组BCNF模式R1,R2,...,Rn

    result:={R};
    done:=false;
    计算F+while (not done) do
    if(result中存在模式Ri不属于BCNF)
    then begin
        令 a→b 为一个在Ri上成立的非平凡函数依赖,满足 a→Ri 不属于F+,并且a∩b;
        result:=(result-Ri)∪(Ri-b)∪(a,b)
    end
    else
    done:=true;

    下面给出一个例子:

    给定关系模式class(class_id, title, dept_name, creadits, sec_id, semester, year, building, room_number, capacity, time_slot_id)

    给出函数依赖(a→a+的形式):

    course_id→title, dept_name, credits

    building, room_number→capacity

    course_id, sec_id, semester, year→building, room, time_slot_id

    易知,该模式的候选码为{course_id, sec_id, semester, year}。

    • 分解class:

    函数依赖course_id→title, dept_name, credits成立,但course_id不是超码。因此class不属于BCNF。所以将class替换成:

    course(course_id, title, dept_name, credits)

    course-1(course_id, sec_id, semester, year, building, room_number, capacity, time_slot_id)

    course上唯一成立的非平凡函数依赖:course_id→title, dept_name, credits,因为course_id是course的超码,所以course属于BCNF。

    • 分解class-1

    函数依赖building, room_number→capacity在class上成立,但{building, room_number}不是class-1的超码,所以将class-1替换成:

    classroom(building, room_number, capacity)

    section(course_id, sec_id, semester, year, building, room_number, time_slot_id)

    显而易见,classroom和section属于BCNF

    需要注意的一点是,如果一个关系已经被分离过了,那么在原有的函数依赖集合F中找不到使该关系不满足BCNF的函数依赖并不意味着这个关系就是函数依赖,而应该遍历函数依赖集合的闭包F+,来寻找相关的函数依赖。

  • 相关阅读:
    基于visual c++之windows核心编程代码分析(33)实现防火墙模型
    基于visual c++之windows核心编程代码分析(31)SNMP协议编程
    未来的职业?
    关于 Delphi 中流的使用(8) 压缩与解压缩的函数
    Delphi 中的 XMLDocument 类详解(2) 记要
    Delphi 中的 XMLDocument 类详解(1) 等待研究的内容
    关于 Delphi 中流的使用(5) 组件序列化
    关于 Delphi 中流的使用(6) 用流读写结构化文件
    xml 语法提示
    关于 Delphi 中流的使用(4) 遍历读取流中的所有数据
  • 原文地址:https://www.cnblogs.com/TheFutureIsNow/p/10789307.html
Copyright © 2011-2022 走看看