1)部分函数依赖 Partial Functional Dependency
在关系模式R(U)中,如果X→Y,并且存在X的一个真子集X₀,使得X₀→Y也成立,
则称Y对X部分函数依赖。这意味着Y的值不仅依赖于X的全部,还依赖于X的某个真子集。
决定因素X可能成为
超键(Super Key)
示例:
考虑一个学生选课的关系模式,包含属性集{学号, 姓名, 课程号, 成绩}。
如果学号和姓名的组合可以确定一个学生的成绩(即(学号, 姓名)→ 成绩),
但单独学号或单独姓名也能确定成绩(即学号→成绩,姓名→成绩),
则成绩对学号和姓名的组合是部分函数依赖的。
例2中的LecID, LName, LEmail → LName, LEmail。staffNo, sName → branchNo。
2)完全函数依赖 Full Functional Dependency
在关系模式R(U)中,如果X→Y,并且不存在X的任何真子集X₀,使得X₀→Y也成立,
则称Y对X完全函数依赖。这意味着Y的值完全由X的全部属性唯一确定,而不是X的任何真子集。
- 唯一性:Y的值仅由X的全部属性唯一确定,不存在其他更小的子集能确定Y。
- 非冗余性:完全函数依赖有助于减少数据冗余,因为Y的值不能通过X的任何真子集得到。
- Determinants in full functional dependencies will become candidate keys if we split the table.
决定因素X在新的表中可能会成为候选键(Candidate Key)
示例:
在成绩表(学号, 课程号, 成绩)的关系中,
成绩完全依赖于学号和课程号的组合(即(学号, 课程号)→ 成绩)。
单独知道学号或课程号是无法确定成绩的,只有同时知道学号和课程号,才能唯一确定一个学生的某门课程的成绩。
例2中的 staffNo → branchNo。
3) 传递依赖 Transitive Dependency
Transitive dependency describes a condition where A, B, and C are attributes of a relation such that if A → B and B → C, then C is transitively dependent on A via B (provided that A is
not functionally dependent on B or C).
传递依赖描述了一个关系中的属性A、B和C之间的一种条件,即如果A → B且B → C,那么C就通过B传递依赖于A(前提是A不是直接函数依赖于B或C)。
(5)超键 Super Key
能够唯一标识表中每一行记录(元组)的属性集,称为超键。
- 唯一性:没有两行数据拥有完全相同的超键值
- 可包含冗余属性:超键可以包含多余的信息。即使移除某些属性,只要剩余的属性集仍然能唯一标识元组,那么它仍然是超键。
- 多个超键可能存在:一个表中可能有多个超键,每个超键都能唯一标识表中的每一行数据。
(6)候选键 Candidate Key
能够唯一标识表中每一行记录(元组)的最小属性集,称为候选键。
- 唯一性:没有两行数据拥有完全相同的候选键值。
- 最小性:候选键不包含任何不必要的属性,即去掉任何一个属性都会导致它无法再唯一标识表中的记录。
- 多个候选键可能存在:一个表中可能有多个候选键,每个都能唯一标识表中的每一行数据。
超键或候选键,是一个或多个属性的集合,通过它可以唯一确定数据库表中的一个元组。
主键是表中选定的一个候选键,用于唯一标识表中的每一行记录。在大多数情况下,表中会选择一个候选键作为主键,但理论上可以选择任何候选键作为主键。
E.g. 有一个学生表,其中包含学号、姓名、性别等属性。
(学号、姓名、性别)可以作为一个超键,因为它能唯一标识一个学生。但是,这个超键包含了多余的属性,因为学号本身就能唯一标识一个学生。
学号可以作为一个候选键,因为它能唯一标识一个学生,且不包含多余的属性。
同样地,如果姓名没有重名,那么姓名也可以作为一个候选键。
The determinant has a M:1 or 1:1 relationship with other attributes in FDs.
在函数依赖中,决定因素与其他属性之间存在多对一(M:1)或一对一(1:1)的关系。
•
Two staff members may have the same name.
Thus, one staff name can be associated with more than one staff number.
StaffNo : sName (M:1)
•
Two staff members may have the same position.
Thus, one position may be associated with more than one staff number
StaffNo : branchNo (M:1)
二、范式 Normal Forms
The Process of Normalisation 数据库规范化的过程
1、第一范式 First Normal Form (1NF)
如果一个关系(表)满足 “表中的所有数据值都是原子的,即:表项应该是单一的值,而不是集合或复合对象” 这一条件,则称该关系处于第一范式(1NF)。
All data values should be atomic.
Table entries should be single values, not sets or composite objects.
第一范式确保了数据库表中的每一列都只能包含单一的值。
如果关系中的某些数据值不是原子的,即包含了集合、列表、数组或其他复合数据类型,
那么该关系就处于未规范化形式(0NF),需要进行规范化处理以达到第一范式的要求。
Look at “Texts” attribute:
•
To
update
the textbook name “T1” to something else, you need to manually update all “T1”s.
“T1”被多次引用,则需要确保每个引用都得到了更新,这是一个繁琐且容易出错的过程。
•
To
delete
T1 from the pool of textbooks, you need to manually do so, too.
遍历整个数据库,找到所有引用“T1”的地方,并将其删除或替换为其他教科书名称。
•
You cannot
add
a textbook without giving the information of Module (because Module is a Primary Key). 如果所需的Module尚未定义,就无法添加新的教科书。
Normalise 0NF to 1NF
(1) 去除重复组 Remove the repeating group:
通过
在包含重复数据的空列 (例中的Texts列) 中输入适当的数据,来消除重复组。
即
展平表格‘flattening’ the table。
(2) 分配新主键 Assign a new primary/unique key
为扁平化后的新表分配一个新的主键。
这个主键应该是唯一的,用于唯一标识表中的每一行。
主键可以是单个字段,也可以是多个字段的组合,即复合主键。
Problems in 1NF
•
Changing module code from “M1” to something else requires you to check the whole table.
•
Adding
a new lecturer with no modules and text is impossible.
•
If a (department, lecturer) pair is
modified
, the change must be made to all (Module, Text) pairs.
For example, to change (D1, L1) to some other value, you must manually change the first four rows.
•
If (M3, T4) is
deleted
, L2 will be permanently lost!
(1) 识别主键/唯一键。
(2) 将重复的数据和唯一键属性的一个副本放入一个单独的关系表中。
2、第二范式 Second Normal Form (2NF)
如果一个关系(表)满足以下两个条件:
1.
满足第一范式,即表中的所有数据值都是原子的。
2.关系的
所有非主键属性必须完全依赖于主键,而不是仅仅依赖于主键的一部分。
即:
对于关系中的每一个非主键属性B,
必须存在从整个主键A到B的函数依赖A → B,
而
不存在从主键A的某个真子集C(C ⊂ A)到B的部分函数依赖C → B。
则称该关系处于第二范式(2NF)。
第二范式确保了关系中的非主键属性不会因主键的某一部分发生变化而受到影响,从而避免了数据冗余和更新异常。同时,它也保证了关系中的每一行都是唯一确定的,由完整的主键来唯一标识。
Normalise 1NF to 2NF
1、确定主键:明确每个关系(表)的主键,即能够唯一标识表中每一行记录的列或列的组合。
2、分析与检查函数依赖:确定哪些属性(或属性组)的值决定了其他属性的值。
检查是否存在部分依赖。
3、分解关系以消除部分依赖:通过创建新的关系(表)来消除部分依赖。
将依赖于主键某一部分的非主键属性及其对应的主键部分移至新表中,而原表保留未被部分依赖影响的剩余主键部分。
这样,新表的主键将是原表中被部分依赖所特指的那一部分主键,从而消除了部分依赖,并使数据更加规范化。
4、确保新表也符合1NF:在创建新表时,必须确保新表同样满足第一范式的要求。
示例: 假设有一个表StudentCourses,用于记录学生选修的课程信息。
这个表包含以下字段: StudentID, CourseID, CourseName, Semester, Instructor。
StudentID和CourseID共同作为主键,即复合主键,它们一起能够唯一标识表中的每一行。
然而,CourseName和Instructor这两个字段实际上只依赖于CourseID,而不是主键的全部(StudentID和CourseID)。这构成了一个部分依赖。
为了消除这种部分依赖,我们可以将CourseName和Instructor以及它们所依赖的CourseID移至一个新表中Courses中。
同时,原表StudentCourses将保留StudentID、CourseID、Semester这些字段,但不再包含CourseName和Instructor,因为这两个字段现在由Courses表管理。
StudentCourses表仅包含与选课记录直接相关的信息(学生和课程之间的关联,以及学期),
而Courses表则管理课程本身的信息(CourseName和Instructor)。
这样就消除了对主键的部分依赖,并使数据更加规范化。
同时,这也减少了数据冗余,同一门课程的信息不再在每个选课记录中重复。
Problems in 2NF:
Look at the table 2NFa
•
We cannot
add
a lecturer who is not assigned with any module.
Because module is the primary key.
•
This is a theoretical discussion. Similar issues can be a real problem in some other tables.
•
By
deleting
M3, we lose L2 forever.
•
To
change
the department for L1, we need to change multiple rows manually.
3、第三范式 Third Normal Form (3NF)
如果一个关系(表)满足以下条件:
1.
满足第二范式:即表中的每个非主属性完全依赖于候选键。
(候选键是表中能够唯一标识一条记录的属性或属性组合,主键是候选键的一个特例)
2.
消除传递依赖:
表中的
每个非键属性必须直接依赖于主键,而不能通过其他非键属性间接依赖于主键。
No
non-key attribute is transitively dependent on
the primary key
.
即
非主属性之间不存在函数依赖关系。
则称该关系处于第三范式(3NF)。
Problems Resolved in 3NF:
Problems in 2NFa:
• INSERT: Can't add lecturers who teach no modules
• UPDATE: To change the department for L1 we must alter two rows
• DELETE: If we delete M3 we delete L2 as well
In 3NF all of these are resolved (for this relation – but 3NF can still have anomalies!)
Normalise 2NF to 3NF
1、确定主键:明确每个关系(表)的主键,即能够唯一标识表中每一行记录的列或列的组合。
2、分析与检查函数依赖:确定哪些属性(或属性组)的值决定了其他属性的值。
检查是否存在
传递依赖。
(非主键字段依赖于另一个非主键字段,而这个非主键字段又依赖于主键)
3、分解关系以消除传递依赖:通过创建新的关系(表)来消除部分依赖。
将这些传递依赖的属性和它们的决定因素(即被依赖的非主键属性)移动到一个新的表1中。
同时,在新的表2中,保留决定因素的一个副本(通常是主键或外键)。
这样,原关系中的所有非主键字段都将直接依赖于主键,从而满足3NF的要求。
4、确保新表也符合2NF:在创建新表时,必须确保新表同样满足第二范式的要求。
注:字段=列=属性
示例:
订单ID | 客户ID | 客户名称 | 订单金额 | 运送公司 | 运送经理 |
---|
O001 | C001 | 阿里巴巴 | 1000 | 顺丰 | 张经理 |
O002 | C002 | 京东 | 1500 | 圆通 | 王经理 |
假设订单ID是主键,则:订单ID → 运送公司 → 运送经理
“运送经理”这个非键属性传递依赖于“运送公司”,而“运送公司”又依赖于“订单ID”。
为了符合第三范式,我们可以将表进行分解:
重构后的表:
1.订单表:
订单ID | 客户ID | 客户名称 | 订单金额 | 运送公司 |
---|
O001 | C001 | 阿里巴巴 | 1000 | 顺丰 |
O002 | C002 | 京东 | 1500 | 圆通 |
2.运送公司信息表:
•
LecID (A) → LEmail (B) → LName (C)
Not a transitive dependency. Because LEmail is functionally dependent on LecID.
尽管 LEcID → LEmail → LName 链是传递的,但这种传递性并不构成拆分表的充分理由。
我们关注的是那种可能导致数据冗余和更新异常的传递依赖,而不仅仅是形式上的传递关系。
The type of transitive dependencies we are looking for should support relationships, or foreign keys.
拆分表的必要条件
1. staffNo (A) → branchNo (B) → bAddress (C):典型的传递依赖
staffNo 直接决定了 branchNo,而 branchNo 又决定了 bAddress。
这里,bAddress 对 staffNo 的依赖是传递的,因为 staffNo 不直接决定 bAddress。
在这种情况下,可能会考虑拆分表以减少数据冗余和提高数据一致性。
2. LecID (A) → LEmail (B) → LName (C):并不构成需要拆表的传递依赖。
LecID → LName 也成立,LName 实际上也直接依赖于 LecID。
因此,虽然 LName 可以通过 LEmail 间接依赖于 LecID,但这种依赖不是拆分表的必要条件。
三、示例
有一个表示在线商店订单的表格,表格中的每一条记录代表一个订单中的一个商品。
每个订单属于一个特定的客户,而每个客户只有一个地址。每个产品都有一个固定的价格。
表格的列包括:{订单号, 产品, 客户, 地址, 数量, 单价}。
{order, product, customer, address, quantity, unitPrice}
例如:(001, Laptop, Xiaobai, ChinaJiangsu, 1, $500) 。
主键是{订单号, 产品},表示每个订单中的每个产品都是唯一的,没有其他候选键。
任务是将这个表格规范化到第三范式(3NF)。
此表格已处于1NF。
1、确定主键:
{order, product}
2、分析与检查函数依赖:
" Each order is for a single customer and each customer has a single address."
•
{order} →{customer, address} 部分函数依赖
•
{order} → {customer} → {address} 部分函数依赖、传递依赖
"Each product has a single price."
•
{product} →{unitPrice} 部分函数依赖
"Each order transitively determines address via customer."
•
{order} → {customer} → {address} 部分函数依赖、传递依赖
Normalisation to 2NF
2NF: no partial dependencies on candidate keys
需解决两个部分函数依赖:{order} → {customer, address} , {product} → {unitPrice}
(1) To remove {order} → {customer, address}, we move {customer, address} to another relation, along with a copy of its determinant, order.
注:下划线的是每个表中的主键
R1: {order, customer, address}
With remaining relation R2: {order, product, quantity, unitPrice}
(2)There is a partial FD in R2: {Product} → {UnitPrice}
To remove this, we move it to another relation R3 拆分R2,得到R3和R4
R3: {Product, unitPrice}
and with remaining relation R4: {order, product, quantity}
Normalisation to 3NF
•
R1 has a transitive FD on its key 需要解决一个传递依赖
•
To remove {order} → {customer} → {Address}, decompose R1 over: 分解R1为R5和R6
R5: {order, customer}
R6: {customer, address}
总结
• 1NF: {order, product, customer, address, quantity, unitPrice}
• 2NF:
R1: {order, customer, address} 2NF
R3: {product, unitPrice} 3NF
R4: {order, product, quantity} 3NF
• 3NF:
R3: {product, unitPrice} 3NF
R4: {order, product, quantity} 3NF
R5: {order, customer} 3NF
R6: {customer, address} 3NF