假设我们有一个订单系统,包含以下实体和属性:订单(Order)、客户(Customer)和产品(Product)。
1. 第一范式(1NF)要求每个属性都是原子性的,即不可再分的。对于订单系统来说,每个订单可能包含多个产品,所以我们需要将订单和产品拆分为两个表,并在订单表中保存订单总金额。这样,每个订单只包含一条记录,且订单中的金额只与该订单相关。
订单(Order)表:
- 订单ID(Order ID):主键
- 客户ID(Customer ID):外键,关联到客户表的客户ID
- 订单总金额(Total Amount)
产品(Product)表:
- 产品ID(Product ID):主键
- 产品名称(Product Name)
- 产品单价(Price)
订单细节(Order Detail)表:
- 订单ID(Order ID):外键,关联到订单表的订单ID
- 产品ID(Product ID):外键,关联到产品表的产品ID
- 数量(Quantity)
2. 第二范式(2NF)要求非主键属性必须完全依赖于候选键。在上述1NF的基础上,我们可以将订单细节表(Order Detail)再细分为两个表,分别包含订单ID和产品ID,以及数量和单价。这样,可以避免重复存储单价信息。
订单(Order)表:
- 订单ID(Order ID):主键
- 客户ID(Customer ID):外键,关联到客户表的客户ID
- 订单总金额(Total Amount)
产品(Product)表:
- 产品ID(Product ID):主键
- 产品名称(Product Name)
- 产品单价(Price)
订单产品(Order Product)表:
- 订单ID(Order ID):外键,关联到订单表的订单ID
- 产品ID(Product ID):外键,关联到产品表的产品ID
产品详情(Product Detail)表:
- 产品ID(Product ID):外键,关联到产品表的产品ID
- 数量(Quantity)
- 单价(Price)
3. 第三范式(3NF)要求非主键属性之间不能存在传递依赖关系。在上述2NF的基础上,我们可以发现产品详情表(Product Detail)中的数量和单价是存在传递依赖关系的,因为它们都依赖于产品ID。因此,我们需要将数量和单价剥离出来,单独创建一个表。
订单(Order)表:
- 订单ID(Order ID):主键
- 客户ID(Customer ID):外键,关联到客户表的客户ID
- 订单总金额(Total Amount)
产品(Product)表:
- 产品ID(Product ID):主键
- 产品名称(Product Name)
订单产品(Order Product)表:
- 订单ID(Order ID):外键,关联到订单表的订单ID
- 产品ID(Product ID):外键,关联到产品表的产品ID
- 产品单价(Product Price)表:包含产品ID和单价,用于记录每个产品的单价。
- 产品数量(Product Quantity)表:包含订单产品ID和数量,用于记录每个订单产品的数量信息