关系数据库的函数依赖和规范化基础知识

rdbmsdatabasedata visualization更新于 2026/1/26 16:07:17

简介

函数依赖和规范化是关系数据库设计中的重要概念。当一个属性的值决定另一个属性的值时,就会发生函数依赖。规范化是以减少冗余和依赖的方式组织数据库的过程。它是设计高效数据库结构的关键步骤。

什么是函数依赖?

函数依赖是指数据库中属性之间的关系。它们描述了一个属性如何依赖于另一个属性。例如,考虑一个员工记录数据库。员工的 ID 号可能在函数上依赖于其姓名,因为姓名决定了 ID 号。在这种情况下,我们会说 ID 号在函数上依赖于姓名。

函数依赖可用于设计数据库,以消除冗余并确保数据完整性。例如,假设一个数据库存储员工记录及其所在部门。如果我们存储每个员工的部门名称,最终可能会得到同一部门名称的多个副本。

这将是冗余的,并且会占用数据库不必要的空间。相反,我们可以使用函数依赖关系,只存储一次部门名称,并使用员工的 ID 号来确定他们所在的部门。这减少了冗余,提高了数据库的效率。

为什么规范化很重要?

规范化是组织数据库以减少冗余和依赖的过程。它很重要,因为它有助于消除数据不一致,并确保数据以合乎逻辑且有序的方式存储。

例如,假设一个数据库存储客户信息及其购买的产品。如果我们将产品名称与每个客户记录一起存储,最终可能会得到同一产品名称的多个副本。这将是冗余的,并且会占用数据库不必要的空间。相反,我们可以使用规范化为产品创建单独的表,并仅存储一次产品名称。这减少了冗余,提高了数据库的效率。

有几种范式可用于规范化数据库。最常见的范式是第一范式、第二范式和第三范式。

第一范式 (1NF)

第一范式 (1NF) 是规范化的基本级别。要符合 1NF,表必须满足以下条件 -

它必须仅包含原子值。原子值是无法进一步细分的单个值。例如,名称是原子值,但地址不是,因为它可以分解为街道、城市、州和邮政编码的单独值。

它不能包含重复组。重复组是在单个记录中重复的一组值。例如,如果一个表包含一个电话号码字段,则该字段不应包含多个电话号码。相反,每个电话号码应该有单独的字段。

第二范式 (2NF)

第二范式 (2NF) 是更高级别的规范化。要符合 2NF,表必须满足以下条件:

  • 必须符合 1NF。

  • 不能有任何部分依赖关系。当非键属性仅依赖于主键的一部分时,就会发生部分依赖关系。例如,考虑一个包含以下属性的表:EmployeeID(主键)、EmployeeName 和 DepartmentID。如果 DepartmentID 依赖于 EmployeeID,但不依赖于 EmployeeName,则存在部分依赖关系。为了消除这种依赖关系,我们可以为部门创建一个单独的表,并将 DepartmentID 和 DepartmentName 存储在该表中。

第三范式 (3NF)

第三范式 (3NF) 是更高级别的规范化。要符合 3NF,表必须满足以下条件:

  • 必须符合 2NF。

  • 不能有任何传递依赖关系。当一个属性依赖于另一个非主键属性时,就会发生传递依赖关系。例如,考虑一个包含以下属性的表:EmployeeID(主键)、EmployeeName 和 ManagerID。如果 ManagerID 依赖于 EmployeeID(主键),则不存在传递依赖关系。但是,如果 ManagerID 依赖于 EmployeeName(非主键),则存在传递依赖关系。为了消除这种依赖关系,我们可以为经理创建一个单独的表,并将 ManagerID 和 ManagerName 存储在该表中。

实际示例

为了更好地理解这些概念,让我们看一些实际的函数依赖和规范化示例。

示例 1

假设有一个在线商店的客户订单数据库。下表存储了每个订单的信息 -

OrderID

CustomerID

ProductID

Quantity

1

1

10

2

2

1

11

1

3

2

10

3

在此表中,OrderID 是主键,CustomerID 和 ProductID 是外键。Quantity 属性依赖于 OrderID,因为它决定了订单中每种产品的数量。

此表符合第一范式 (1NF),因为它只包含原子值,并且没有任何重复组。但是,它不符合第二范式 (2NF),因为 Quantity 属性依赖于 OrderID,而 OrderID 只是主键 (OrderID, ProductID) 的一部分。为了消除这种部分依赖关系,我们可以创建一个单独的订单详情表,并将 OrderID、ProductID 和 Quantity 存储在该表中。

OrderID

ProductID

Quantity

1

10

2

1

11

1

3

10

3

示例 2

假设某公司有一个员工记录数据库。下表存储了每位员工的信息 -

EmployeeID

EmployeeName

ManagerID

DepartmentID

1

John Smith

3

1

2

Jane Doe

3

1

3

Bob Johnson

4

2

4

Mary Williams

NULL

2

在此表中,EmployeeID 是主键,ManagerID 和 DepartmentID 是外键。ManagerID 依赖于 EmployeeID,因为它决定了员工的经理。DepartmentID 依赖于 ManagerID,因为它决定了员工所在的部门。

此表符合 2NF,因为它符合 1NF,并且没有任何部分依赖关系。但是,它不符合 3NF,因为 DepartmentID 依赖于 ManagerID,而 ManagerID 不是主键。为了消除这种传递依赖关系,我们可以为部门创建一个单独的表,并将 DepartmentID 和 DepartmentName 存储在该表中。然后,我们可以更新员工表,将 DepartmentID 存储为外键。

EmployeeID

EmployeeName

ManagerID

DepartmentID

1

John Smith

3

1

2

Jane Doe

3

1

3

Bob Johnson

4

2

4

Mary Williams

NULL

2

DepartmentID

DepartmentName

1

Sales

2

Marketing

结论

函数依赖和规范化是关系数据库设计中的重要概念。它们有助于消除冗余,并通过以合乎逻辑且高效的方式组织数据库来确保数据完整性。通过理解这些概念并将其应用于数据库设计,您可以创建一个高效、有效且易于维护的数据库。