MySQL三大范式查询详解(mysql 三大范式查询)

MySQL三大范式查询详解

在关系型数据库中,三大范式是非常重要的概念,它可以保证数据库的数据结构设计合理、高效。本文将详细讲解三大范式及在MySQL数据库中的实现,并提供查询示例。

一、第一范式(1NF)

第一范式要求数据表中的所有列都是不可分割的原子值,也就是每个列都应该只包含一个单一的数据类型(如整型、浮点型等),而不是包含多个数据。这个实务表包括下列数据项:OrderNumber、Date、CustomerName、Address、ItemNumber、Description、Price。这样的表不符合第一范式,因为它的内容不是原子性的。

+————-+————+—————-+———————+————+————-+——-+

| OrderNumber | Date | CustomerName | Address | ItemNumber | Description | Price |

+————-+————+—————-+———————+————+————-+——-+

| 00123 | 2020-03-01 | John Smith | 123 Maple Street | 137 | Widget | 12.95 |

| 00123 | 2020-03-01 | John Smith | 123 Maple Street | 140 | Gadget | 28.95 |

| 00201 | 2020-03-02 | Jane Doe | 456 Oak Street | 137 | Widget | 12.95 |

| 00201 | 2020-03-02 | Jane Doe | 456 Oak Street | 141 | Gizmo | 23.95 |

| 00315 | 2020-03-02 | Sam Johnson | 789 Elm Street | 140 | Gadget | 28.95 |

| 00315 | 2020-03-02 | Sam Johnson | 789 Elm Street | 137 | Widget | 12.95 |

| 00315 | 2020-03-02 | Sam Johnson | 789 Elm Street | 141 | Gizmo | 23.95 |

| 00430 | 2020-03-03 | Susan Williams | 101 Pine Street | 137 | Widget | 12.95 |

| 00430 | 2020-03-03 | Susan Williams | 101 Pine Street | 140 | Gadget | 28.95 |

| 00582 | 2020-03-04 | Jack Brown | 314 Walnut Street | 140 | Gadget | 28.95 |

| 00582 | 2020-03-04 | Jack Brown | 314 Walnut Street | 137 | Widget | 12.95 |

| 00582 | 2020-03-04 | Jack Brown | 314 Walnut Street | 141 | Gizmo | 23.95 |

+————-+————+—————-+———————+————+————-+——-+

我们可以将数据分为两个表,购买订单表(Orders)和订单条目表(OrderItems):

Orders:

+————-+————+—————-+———————+

| OrderNumber | Date | CustomerName | Address |

+————-+————+—————-+———————+

| 00123 | 2020-03-01 | John Smith | 123 Maple Street |

| 00201 | 2020-03-02 | Jane Doe | 456 Oak Street |

| 00315 | 2020-03-02 | Sam Johnson | 789 Elm Street |

| 00430 | 2020-03-03 | Susan Williams | 101 Pine Street |

| 00582 | 2020-03-04 | Jack Brown | 314 Walnut Street |

+————-+————+—————-+———————+

OrderItems:

+————-+————+————-+——-+

| OrderNumber | ItemNumber | Description | Price |

+————-+————+————-+——-+

| 00123 | 137 | Widget | 12.95 |

| 00123 | 140 | Gadget | 28.95 |

| 00201 | 137 | Widget | 12.95 |

| 00201 | 141 | Gizmo | 23.95 |

| 00315 | 140 | Gadget | 28.95 |

| 00315 | 137 | Widget | 12.95 |

| 00315 | 141 | Gizmo | 23.95 |

| 00430 | 137 | Widget | 12.95 |

| 00430 | 140 | Gadget | 28.95 |

| 00582 | 140 | Gadget | 28.95 |

| 00582 | 137 | Widget | 12.95 |

| 00582 | 141 | Gizmo | 23.95 |

+————-+————+————-+——-+

二、第二范式(2NF)

第二范式要求在满足第一范式的前提下,非主键列必须依赖于主键,而不能部分依赖主键。

举个例子,我们创建一个员工(Employees)表,包括以下数据项:

+———+————-+———-+————-+

| EmpID | FirstName | LastName | DeptID |

+———+————-+———-+————-+

| 100 | John | Smith | 1 |

| 101 | Jane | Doe | 2 |

| 102 | Sam | Johnson | 1 |

+———+————-+———-+————-+

出于数据结构设计的考虑,这里我们仅保留了DeptID的编号,通过外键关联到另一个表Deptartment中获取其他部门信息:

+———+———–+————+

| DeptID | DeptName | DeptHead |

+———+———–+————+

| 1 | IT | John Smith |

| 2 | Finance | Jane Doe |

+———+———–+————+

三、第三范式(3NF)

第三范式要求在满足第一、第二范式的前提下,非主键列之间不能存在传递依赖关系。这个规则被描述为“每个非主属性都必须直接依赖于主键,不能对其他非主属性产生传递依赖”。

对于订单模型,我们已经将其拆成了两个表,Orders和OrderItems,但仍然存在一些问题。比如,如果我们将Product表中的Description列移至OrderItems表,那么Description列将既依赖于Product表的主键ProductID,又依赖于OrderItems表的主键OrderNumber和ItemNumber,这就违反了第三范式。

为了避免这种情况,我们需要创建一个新的Product表,其中包含描述信息和价格:

+————+————-+

| ItemNumber | Price |

+————+————-+

| 137 | 12.95 |

| 140 | 28.95 |

| 141 | 23.95 |

+————+————-+

OrderItems表则只需包含三个数据项:OrderNumber、ItemNumber和数量(Quantity):

+————-+————+———-+

| OrderNumber | ItemNumber | Quantity |

+————-+————+———-+

| 00123 | 137 | 1 |

| 00123 | 140 | 1 |

| 00201 | 137 | 1 |

| 00201 | 141 | 1 |

| 00315 | 140 | 1 |

| 00315 | 137 | 1 |

| 00315 | 141 | 1 |

| 00430 | 137 | 1 |

| 00430 | 140 | 1 |

| 00582 | 140 | 1 |

| 00582 | 137 | 1 |

| 00582 | 141 | 1 |

+————-+————+———-+

在这种情况下,我们可以通过JOIN操作连接这三个表来查询订单草稿的详细信息。例如,如果我们想获得订单数量大于1的产品列表:

SELECT Product.Description, SUM(OrderItems.Quantity) AS TotalQuantity

FROM Orders

JOIN OrderItems ON Orders.OrderNumber = OrderItems.OrderNumber

JOIN Product ON OrderItems.ItemNumber = Product.ItemNumber

GROUP BY Product.Description

HAVING SUM(OrderItems.Quantity) > 1;

以上查询可以通过联结三个表来获取数据。我们将Order表联接到OrderItems表的OrderNumber列,然后将OrderItems表联接到Product表的ItemNumber列,以便获取每个产品的描述信息和价格。我们按产品描述进行汇总,并选择数量大于1的产品。


数据运维技术 » MySQL三大范式查询详解(mysql 三大范式查询)