数据库关系规范化与依赖分析深度解析
立即解锁
发布时间: 2025-08-23 00:25:36 阅读量: 2 订阅数: 11 

### 数据库关系规范化与依赖分析深度解析
#### 1. 依赖关系与范式的基础概念
在数据库设计中,理解各种依赖关系以及范式的概念是至关重要的。首先来看函数依赖(FD)和多值依赖(MVD)的一些特性。当存在函数依赖 A → BCD 和多值依赖 B →→ C 时,我们可以推断出函数依赖 B → C 必然成立。这是因为在具有相同 A 值的情况下,能够得出相应的结论。如果 B → C 成立,那么关系 ABCD 通常就不在 Boyce - Codd 范式(BCNF)中,除非有额外的函数依赖使 B 成为键。这表明在分析关系时,准确识别所有成立的函数依赖是非常重要的。
给定一组函数依赖和多值依赖,我们可以使用推理规则来推断出更多的函数依赖和多值依赖。在应用 Date - Fagin 结果时,如果不先使用多值依赖的推理规则,就必须确保已经识别出了所有的函数依赖。Date - Fagin 结果为我们提供了一种方便的方法来检查一个关系是否处于第四范式(4NF),前提是我们有信心已经识别出了所有的函数依赖。
#### 2. 连接依赖(Join Dependencies)
连接依赖是多值依赖的进一步推广。如果 R1, …, Rn 是关系 R 的无损连接分解,那么连接依赖(JD){R1, …, Rn} 就被认为在关系 R 上成立。例如,关系 R 上的多值依赖 X →→ Y 可以表示为连接依赖 {XY, X(R - Y)}。在 CTB 关系中,多值依赖 C →→ T 可以表示为连接依赖 {CT, CB}。与函数依赖和多值依赖不同的是,目前还没有一套健全且完整的推理规则用于连接依赖。
#### 3. 第五范式(Fifth Normal Form,5NF)
一个关系模式 R 被认为处于第五范式(5NF),当对于在 R 上成立的每个连接依赖 {R1, …, Rn},满足以下两个条件之一:
- 存在某个 i 使得 Ri = R;
- 该连接依赖由 R 上那些左边是 R 的键的函数依赖集所蕴含。
第二个条件需要一些解释,因为我们还没有介绍函数依赖和连接依赖一起的推理规则。直观地说,当键依赖(左边是 R 的键的函数依赖)成立时,我们必须能够证明将 R 分解为 {R1, …, Rn} 是无损连接的。如果存在某个 i 使得 Ri = R,那么连接依赖 {R1, …, Rn} 就是一个平凡的连接依赖,这样的连接依赖总是成立的。
Date 和 Fagin 给出的一个结果表明,如果一个关系模式处于第三范式(3NF),并且它的每个键都由单个属性组成,那么它也处于第五范式。这些条件对于一个关系处于第五范式是充分的,但不是必要的。这个结果在实践中非常有用,因为它允许我们在不识别可能存在于关系上的多值依赖和连接依赖的情况下,就得出该关系处于第五范式的结论。
#### 4. 包含依赖(Inclusion Dependencies)
多值依赖和连接依赖可以用于指导数据库设计,尽管它们不如函数依赖常见,并且更难识别和推理。相比之下,包含依赖非常直观且相当常见。不过,它们通常对数据库设计的影响较小(超出实体 - 关系(ER)设计阶段)。
非正式地说,包含依赖是一种形式的陈述,即一个关系的某些列包含在其他列(通常是另一个关系的列)中。外键约束就是包含依赖的一个例子,一个关系中的引用列必须包含在被引用关系的主键列中。例如,如果 R 和 S 是通过转换两个实体集得到的两个关系,并且每个 R 实体也是一个 S 实体,那么就会存在一个包含依赖,将 R 投影到其键属性上得到的关系包含在将 S 投影到其键属性上得到的关系中。
在处理包含依赖时,我们要记住的主要一点是,不应该拆分参与包含依赖的属性组。例如,如果存在包含依赖 AB ⊆ CD,在分解包含 AB 的关系模式时,应该确保分解得到的至少一个模式包含 A 和 B。否则,在不重构包含 AB 的关系的情况下,就无法检查包含依赖 AB ⊆ CD。
大多数实际中的包含依赖是基于键的,即只涉及键。外键约束就是基于键的包含依赖的一个很好的例子。涉及 ISA 层次结构的 ER 图也会导致基于键的包含依赖。如果所有的包含依赖都是基于键的,我们很少需要担心拆分参与包含依赖的属性组,因为分解通常不会拆分主键。但是,从第三范式转换到 Boyce - Codd 范式总是会涉及拆分某个键(理想情况下不是主键),因为指导拆分的依赖形式是 X → A,其中 A 是键的一部分。
#### 5. 案例研究:互联网商店数据库设计
以互联网商店的数据库设计为例,DBDudes 确定了以下关系模式:
- Books(isbn: CHAR(10), title: CHAR(8), author: CHAR(80), qty in stock: INTEGER, price: REAL, year published: INTEGER)
- Customers(cid: INTEGER, cname: CHAR(80), address: CHAR(200))
- Orders(ordernum: INTEGER, isbn: CHAR(10), cid: INTEGER, cardnum: CHAR(16), qty: INTEGER, order date: DATE, ship date: DATE)
DBDudes 对这些关系进行了冗余分析。Books 关系只有一个键 (isbn),并且表上没有其他函数依赖,因此 Books 关系处于 Boyce - Codd 范式。Customers 关系也只有一个键 (cid),并且表上没有其他函数依赖,所以 Customers 关系也处于 Boyce - Codd 范式。
对于 Orders 表,DBDudes 已经确定了 ordernum, isbn 作为键。此外,由于每个订单是由一个客户在一个特定日期使用一个特定的信用卡号下的,所以存在以下三个函数依赖:
- ordernum → cid
- ordernum → order date
- ordernum → cardnum
DBDudes 的专家得出结论,Orders 表甚至不在第三范式中。他们决定将 Orders 分解为以下两个关系:
- Orders(ordernum, cid, order date, cardnum)
- Orderlists(ordernum, isbn, qty, ship date)
分解后的两个关系 Orders 和 Orderlists 都处于 Boyce - Codd 范式,并且由于 ordernum 是(新的)Orders 的键,所以这个分解是无损连接的。读者可以检查这个分解也是依赖保持的。以下是 Orders 和 Order
0
0
复制全文
相关推荐









