📅  最后修改于: 2023-12-03 15:30:23.799000             🧑  作者: Mango
关系型数据库中的范式是一种规范,它旨在通过化简数据的冗余度来提高数据的一致性和完整性。在设计数据库模式时,应该优先考虑符合范式的模式,以便提高数据库的质量和效率。
第一范式是指表中的每一列都是不可再分割的基本数据单元,即每一列的值都是一个不可分割的原子值。在第一范式中,不允许出现表中存在多个可以重复的相同的列。
例如,一个 “Address” 列中包含了 “Street”、“City”、“State” 和 “ZIP” 四种地址信息,此时需要将这些信息拆分成多个独立的列,如下所示:
| Name | Street | City | State | ZIP | | --- | --- | --- | --- | --- | | John | Birch Street | New York | NY | 10001 |
第二范式是指表中的每一列都与主键是完全依赖关系,即不存在部分依赖。对于具有复合主键的表,每一列都应该依赖于所有主键。
例如,一张订单详情表(OrderDetails)包含订单号(OrderId)、商品编码(ProductId)和商品数量(Quantity)三个字段。这时候如果将 “订单号” 和 “商品编码” 作为主键,那 “商品数量” 字段就是部分依赖于主键,此时需要将该表拆分成两个表,如下所示:
OrderTable
| OrderId | Date | | --- | --- | | 001 | 2021-01-01 |
OrderDetailsTable
| OrderId | ProductId | Quantity | | --- | --- | --- | | 001 | P001 | 2 | | 001 | P002 | 3 |
第三范式是指表中的每一列都不包含其他列的信息,即不存在传递依赖关系。如果存在这样的依赖关系,则需要将其拆分成两个独立的表。
例如,一个销售订单表中包含订单号、客户名称、客户地址和客户电话等信息。这里客户地址和客户电话是客户的属性,与订单无关,因此应该将其拆分成一个客户表和一个订单表,如下所示:
Customer Table
| CustomerName | CustomerAddress | CustomerPhone | | --- | --- | --- | | John | Birch Street | 123456 |
OrderTable
| OrderId | CustomerName | OrderDate | | --- | --- | --- | | 001 | John | 2021-01-01 |
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 |