📜  DBMS 中的范式(1)

📅  最后修改于: 2023-12-03 15:30:23.799000             🧑  作者: Mango

DBMS 中的范式

关系型数据库中的范式是一种规范,它旨在通过化简数据的冗余度来提高数据的一致性和完整性。在设计数据库模式时,应该优先考虑符合范式的模式,以便提高数据库的质量和效率。

1NF: 第一范式

第一范式是指表中的每一列都是不可再分割的基本数据单元,即每一列的值都是一个不可分割的原子值。在第一范式中,不允许出现表中存在多个可以重复的相同的列。

例如,一个 “Address” 列中包含了 “Street”、“City”、“State” 和 “ZIP” 四种地址信息,此时需要将这些信息拆分成多个独立的列,如下所示:

| Name | Street | City | State | ZIP | | --- | --- | --- | --- | --- | | John | Birch Street | New York | NY | 10001 |

2NF: 第二范式

第二范式是指表中的每一列都与主键是完全依赖关系,即不存在部分依赖。对于具有复合主键的表,每一列都应该依赖于所有主键。

例如,一张订单详情表(OrderDetails)包含订单号(OrderId)、商品编码(ProductId)和商品数量(Quantity)三个字段。这时候如果将 “订单号” 和 “商品编码” 作为主键,那 “商品数量” 字段就是部分依赖于主键,此时需要将该表拆分成两个表,如下所示:

OrderTable

| OrderId | Date | | --- | --- | | 001 | 2021-01-01 |

OrderDetailsTable

| OrderId | ProductId | Quantity | | --- | --- | --- | | 001 | P001 | 2 | | 001 | P002 | 3 |

3NF: 第三范式

第三范式是指表中的每一列都不包含其他列的信息,即不存在传递依赖关系。如果存在这样的依赖关系,则需要将其拆分成两个独立的表。

例如,一个销售订单表中包含订单号、客户名称、客户地址和客户电话等信息。这里客户地址和客户电话是客户的属性,与订单无关,因此应该将其拆分成一个客户表和一个订单表,如下所示:

Customer Table

| CustomerName | CustomerAddress | CustomerPhone | | --- | --- | --- | | John | Birch Street | 123456 |

OrderTable

| OrderId | CustomerName | OrderDate | | --- | --- | --- | | 001 | John | 2021-01-01 |

BCNF: 巴斯-科德范式

BCNF 是指对于每一个不包含超键的非平凡函数依赖,其左部都是一个候选键。如果存在非平凡函数依赖的左部不是一个候选键,则需要将其拆分成多个独立的表。

例如,一个员工表 Employee 包含了部门名称 DepartmentName 和地址 Address,但是同一部门的员工地址都是相同的,那么 Address 就依赖于 部门名称 这个小数部分,不满足 BCNF 范式。

Employee Table

| EmpId | EmpName | DepartmentName | Address | | --- | --- | --- | --- | | E001 | John | HR | Birch Street | | E002 | Mike | HR | Ocean Ave |

Department Table

| DepartmentName | Address | | --- | --- | | HR | Birch Street |

参考文献
  1. 范式 (数据库)