数据库范式(详细介绍)

目录

第一范式(原子性)

第二范式(主键唯一性)

第三范式(原子性+主键唯一性)

BC范式(3NFplus)


数据库范式(详细介绍)_第1张图片

第一范式(原子性

确保每列保证原子性,保证这个属性(字段)不能在被分割。

不符合第一范式:

订单
--------------------------------------------------------------
| 订单编号 | 产品名称       | 产品价格          |
--------------------------------------------------------------
| 1      | 手机, 电脑, 鼠标 | 3000, 6000, 100    |
| 2      | 相机, 耳机       | 2000, 300          |
--------------------------------------------------------------
 

在这个例子中,"产品名称"和"产品价格"字段都包含了多个值,使用逗号分隔。这样的设计违反了第一范式(1NF),因为一个字段应该只包含一个值。

为了符合第一范式(1NF),我们可以将每个产品拆分成单独的行,如下所示:

订单
-----------------------------------
| 订单编号 | 产品名称 | 产品价格 |
-----------------------------------
| 1      | 手机   | 3000    |
| 1      | 电脑   | 6000    |
| 1      | 鼠标   | 100     |
| 2      | 相机   | 2000    |
| 2      | 耳机   | 300     |
-----------------------------------
在上述例子中,每个产品都被拆分成了单独的行,每行分别包含一个产品名称和对应的产品价格。这样就符合了第一范式(1NF),每个字段都是原子性的,不可再分。

第二范式(主键唯一性

第二范式在第一范式的基础上,消除了非主属性对于码的部分函数依赖。且增加了一列,这一列为主键列,非主属性都依赖主键列。且没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分,也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。

例子:一个不符合第二范式可以是一个包含重复数据的数据库表。举个简单的例子,假设我们有一个存储订单信息的数据库表,其中包含订单号、顾客姓名和顾客地址等字段:

OrderDetails
-----------------------------------
| OrderID   | CustomerName | CustomerAddress |
-----------------------------------
| 1         | Alice        | 123 Main St     |
| 2         | Bob          | 456 Park Ave  |
| 3         | Alice        | 123 Main St     |
-----------------------------------

在这个例子中,可以看到同一个顾客的姓名和地址信息出现了多次。这种情况下,就不符合第二范式(2NF),因为有部分字段依赖于订单号,而另一部分字段依赖于顾客姓名。这样的表结构存在以下问题:

  1. 数据冗余:同一个顾客的姓名和地址信息重复出现,会导致数据冗余,增加了存储空间的消耗。

  2. 更新异常:如果需要更新顾客的地址,那么就需要同时更新多条记录,容易出现更新异常,导致数据不一致。

第三范式(原子性+主键唯一性

第三范式在第二范式的基础之上,消除了非主属性对于码的传递函数依赖。就是说任何非主属性不依赖于其它非主属性。

一个不符合第三范式(3NF)的例子可以是一个存储产品信息的数据库表,其中包含了产品编号、产品名称、供应商编号、供应商名称和供应商地址等字段:

Products
-------------------------------------------------
| ProductID   | ProductName  | SupplierID | SupplierName | SupplierAddress |
-------------------------------------------------
| 1           | Laptop       | 101        | ABC Inc      | 123 Main St     |
| 2           | Smartphone   | 102        | XYZ Ltd      | 456 Park Ave    |
| 3           | Tablet       | 101        | ABC Inc      | 123 Main St     |
-------------------------------------------------

在这个例子中,可以看到存在以下问题:

  1. 数据冗余:同一个供应商的名称和地址信息重复出现,会导致数据冗余,增加了存储空间的消耗。

  2. 更新异常:如果需要更新某个供应商的地址,那么就需要同时更新多条记录,容易出现更新异常,导致数据不一致。

为了符合第三范式,我们可以将上述表拆分成两个表:

Products
---------------------------------
| ProductID   | ProductName  |
---------------------------------
| 1           | Laptop       |
| 2           | Smartphone   |
| 3           | Tablet       |
---------------------------------

Suppliers
---------------------------------
| SupplierID | SupplierName | SupplierAddress |
---------------------------------
| 101        | ABC Inc      | 123 Main St     |
| 102        | XYZ Ltd      | 456 Park Ave    |
---------------------------------
这样就将产品信息和供应商信息分离开来,避免了数据冗余和更新异常,使得数据库表符合第三范式

BC范式(3NFplus)

BC范式(Boyce-Codd Normal Form)是关系数据库设计中的一种标准化范式。它建立在第三范式(3NF)的基础上,通过进一步消除非主属性对候选键的部分依赖来减少数据冗余。

简单来说,BC范式要求:

  1. 每个非主属性都完全依赖于候选键。也就是说,如果一个属性只依赖于候选键的一部分而不是全部,那么它就不符合BC范式。

  2. 所有的函数依赖都应该是候选键的超键。也就是说,任何非候选键的属性都不应该决定其他非候选键的属性。

BC范式的目标是消除数据冗余,并且确保数据的一致性和完整性。通过将关系数据库设计满足BC范式,可以提高数据库的性能和可维护性。

需要注意的是,BC范式是对关系数据库设计的理论指导,并不是必须遵守的绝对规则。在某些情况下,根据实际需求和性能考虑,可能需要在范式化和反范式化之间做出权衡。

举个例子:假设我们有一个关系数据库用于存储员工信息,包含以下字段:员工编号、姓名、部门、工资。

  1. 员工编号是主键(候选键),每个员工的编号唯一标识其身份。

  2. 姓名、部门和工资都完全依赖于员工编号。

在第三范式(3NF)下,我们可以将数据设计如下:

员工表
------------------------------------------------
| 员工编号 | 姓名     | 部门      | 工资      |
------------------------------------------------
| 001    | 张三   | 技术部   | 5000    |
| 002    | 李四   | 销售部   | 6000    |
| 003    | 王五   | 财务部   | 7000    |
------------------------------------------------

这个设计符合第三范式(3NF),因为每个非主属性(姓名、部门、工资)都完全依赖于候选键(员工编号),没有冗余数据

然而,如果我们进一步考虑BC范式,我们可能会发现在这个设计中存在一些函数依赖问题。假设每个部门都有一个负责人,那么我们可以将负责人作为一个新的实体来设计:

员工表
------------------------------------------------
| 员工编号 | 姓名     | 部门编号  | 工资      |
------------------------------------------------
| 001    | 张三   | 001      | 5000    |
| 002    | 李四   | 002      | 6000    |
| 003    | 王五   | 003      | 7000    |
------------------------------------------------

部门表
---------------------------------
| 部门编号 | 部门名称 | 负责人    |
---------------------------------
| 001    | 技术部   | 张三    |
| 002    | 销售部   | 李四    |
| 003    | 财务部   | 王五    |
---------------------------------
 

通过这种设计,我们将部门信息从员工表中分离出来,避免了部门信息的冗余。在部门表中,负责人属性只取决于部门编号,符合BC范式的要求。

这样的设计提高了数据的一致性和完整性,并且减少了冗余数据。根据实际需求和性能要求,我们可以在范式化和反范式化之间做出权衡,选择适合的数据库设计。

总结:

符合三大范式的数据库设计有助于保证数据的一致性、完整性和可维护性,提高查询效率,并节省数据存储空间。然而,在实际应用中,我们需要根据具体的业务需求和性能要求进行权衡,有时也需要适度地进行反范式化设计。

你可能感兴趣的:(数据库开发,数据库,数据库架构)