数据库的函数依赖、属性集的闭包、覆盖、模式分解、范式、3NF的分解、BCNF的分解

Functional Dependency 函数依赖

  1. K 是关系模式R 的超码 当且仅当 K ->R
  2. K 是关系模式R 的候选码 当且仅当
    K -> R, 并且
    不存在 a属于 K, a-> R
  • 函数依赖集:若干个函数依赖组成的集合
  • 如果一个关系 r 没有违反函数依赖集 F, 那么称
    关系 r 满足函数依赖集 F ( r satisfies F )
  • 如果关系模式 R 的所有关系都满足函数依赖集 F, 那么称
    函数依赖集F 在关系模式 R 上成立 ( F holds on R )

Closure of Attribute Sets 属性集的闭包

根据一个给定的函数依赖集 F,由属性集 a 可推出的所有属性组成的集合,称为 a 的闭包,记为 a+

计算属性集的闭包

属性集闭包的用途:

  • 判断一个属性集是否超码

    要判断 a 是不是 R 的超码,只要看 a+ 是不是包含 R

  • 判断一个函数依赖是否成立

    要判断 a->b 是不是成立,只要看b属于a+ 是不是成立

Canonical Cover 最小覆盖/规范覆盖

把函数依赖集 F 中多余的函数依赖和多余的属性删除,得到“最小的”函数依赖集合,称为 F 的最小覆盖或规范覆盖

  1. 函数依赖集中的某些函数依赖是多余的

    例如. {A ->B, B -> C, A ->C} 可以简化为等价的函数依赖集合

    {A ->B, B -> C}

  2. 函数依赖中的某些属性是多余的

    例如. {A ->B, B ->C, A ->CD} 可以简化为等价的函数依赖集合

    {A ->B, B ->C, A -> D}

    例如. {A ->B, B ->C, AC ->D} 可以简化为等价的函数依赖集合

    {A -> B, B ->C, A -> D}

Decomposition(模式分解)

Lossless Decomposition 无损分解

Closure of a Set of Functional Dependencies函数依赖集的闭包

由函数依赖集 F 可推断出的所有函数依赖所组成的集合,叫做 F 的闭包,记为 F+

F+ 是 F 的超集

Dependency Preservation(保持函数依赖)

  1. 分解关系模式 R 后, 得到关系模式 R1, R2,…,Rn

  2. 把 F+ 中只包含 R1 属性的函数依赖子集合记为 F1

  3. 把 F+ 中只包含 R2 属性的函数依赖子集合记为 F2

    如此类推

  4. 把 F+ 中只包含 Rn 属性的函数依赖子集合记为 Fn

保持函数依赖. 如果
F1 并 F2 并 … 并 Fn 和 F 是等价的
那么称这个分解是保持函数依赖的(dependency preserving)

Normal Forms(范式)

范式是关系的集合

1NF (First Normal Form,第1范式)

如果一个关系模式R的所有属性域都是原子域,那么R属于第一范式

以下哪些域是原子域?
食品 = { 可乐,薯条,鸡翅,面条,饺子,汤,…… }
套餐 = { (可乐,薯条,鸡翅),(面条,饺子,汤),……}
车票 = { D7727次02车20A号,D7712次08车04A号,…… }
车次 = { D7727次,D7712次,…… }
车厢 = { 02车,08车,…… }
座位 = { 20A号,04A号,…… }
答案
食品,车次,车厢,座位

3NF (Third Normal Form)

BCNF (Boyce-Codd Normal Form)

BCNF定义. 如果 F+ 里面的所有非平凡函数依赖 a->b的 a 都是 R 的超码,那么 R 属于 BCNF
实际上,只需要检查 F 的函数依赖,不需要检查 F+ 的全部函数依赖
Example. 以下关系模式不属于 BCNF:
instr_dept (ID, name, salary, dept_name, building, budget )
因为存在非平凡函数依赖 dept_name-> building, budget
但是 dept_name 不是超码

3NF vs BCNF

  1. Redundancy 冗余

    BCNF 能消除用函数依赖发现的冗余

    3NF 还有一些冗余

  2. Dependency-preserving decomposition 保持函数依赖分解

    所有关系模式都有保持函数依赖的 3NF 分解

    有一些关系模式,它们的 BCNF 分解不能保持函数依赖

Decomposition Algorithms(分解算法)

3NF 分解算法

以下 3NF 分解算法是保持函数依赖的:

  1. 先求出 F 的最小覆盖 Fc

  2. 为 Fc 的每个函数依赖 a->b 生成一个新的关系模式 a U b

  3. 如果生成的每一个关系模式都不包含 R 的候选码,

    ​ 就选择 R 的任意一个候选码 A,生成一个新的关系模式 A

  4. 检查生成的关系模式,如果有 R1 属于 R2,就把 R1 删掉

分解以下关系模式:
cust_banker_branch = (customer_id, employee_id, branch_name, type )
函数依赖集:
customer_id, employee_id -> branch_name, type
employee_id -> branch_name
customer_id, branch_name -> employee_id
首先计算最小覆盖 Fc

  1. 第一个函数依赖中的 branch_name 是多余的

FC = { customer_id, employee_id -> type

​ employee_id -> branch_name

​ customer_id, branch_name -> employee_id }

为每个函数依赖生成一个关系模式:
(customer_id, employee_id, type )
(employee_id, branch_name)
(customer_id, branch_name, employee_id)
(customer_id, employee_id, type ) 已经包含了原关系模式的候选码, 所以不用为候选码生成新的关系模式
第二个关系模式是第三个关系模式的子集,可以删掉
最终得到的分解:
(customer_id, employee_id, type)
(customer_id, branch_name, employee_id)

BCNF 分解算法

假设关系模式 R 有一个非平凡函数依赖 a->b (且a并b = 空 ),a不是超码
我们可以把 R 分解为以下两个关系模式
a U b 和 R – b
如果分解后的两个关系模式还不是BCNF, 就继续分解下去
注意:要判断分解后得到的关系模式 Ri 是否属于 BCNF时, 要用函数依赖集Fi ,而不是用函数依赖集 F

例如:
R = (A, B, C, D, E)
F = { A-> B, BC-> D}
考虑 A -> B,A 不是超码,所以把 R 分解为
R1 = (A,B)
R2 = (A,C,D,E)
F 的函数依赖,都不是仅包含 (A,C,D,E)
所以不能根据 F 来判断 R2 是否属于BCNF
实际上, F+ 中的 AC-> D 使得 R2 不属于 BCNF
所以还要继续对 R2 进行分解

  • 6
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现数据库系统函数依赖属性闭包的算法,可以使用Python编程语言。以下是一种可能的算法实现: ```python # 定义函数依赖类 class FunctionalDependency: def __init__(self, lhs, rhs): self.lhs = lhs self.rhs = rhs # 计算属性闭包 def compute_closure(attributes, functional_dependencies): closure = set(attributes) # 初始化闭包属性合 closure_changed = True while closure_changed: closure_changed = False for fd in functional_dependencies: if fd.lhs.issubset(closure) and not fd.rhs.issubset(closure): closure = closure.union(fd.rhs) closure_changed = True # 闭包发生变化 return closure # 测试示例 attributes = {'A', 'B', 'C', 'D'} functional_dependencies = [ FunctionalDependency({'A'}, {'B'}), FunctionalDependency({'A'}, {'C'}), FunctionalDependency({'C', 'D'}, {'A', 'B'}) ] closure = compute_closure(attributes, functional_dependencies) print("属性闭包为:", closure) ``` 以上代码定义了一个`FunctionalDependency`类来表示函数依赖,并实现了`compute_closure`函数来计算属性闭包。在测试示例中,我们定义了一些属性函数依赖,并调用`compute_closure`函数来计算属性闭包。最后,打印输出结果。 算法实现的思路是通过迭代的方式,不断查找闭包中是否有新的属性加入。首先,将闭包初始化为属性合。然后,对每个函数依赖进行判断,如果函数依赖的左侧属性闭包的子并且右侧属性不是闭包的子,则将右侧属性加入闭包,并标记闭包发生变化。循环迭代,直到闭包不再发生变化为止。最后,返回计算得到的闭包。 以上就是一个可能的Python实现算法,可能还有其他实现方式,具体实现可以根据实际需求进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值