Mysql 表设计范式
MySQL的三个范式(1NF、2NF、3NF)确实是用来指导数据库设计,确保数据结构的合理性和减少数据冗余的。这些范式通过规定数据表的结构和关系来确保数据的完整性和一致性。下面是对这三个范式的简要解释:
- 第一范式(1NF):
- 定义:每一列都是不可分割的原子项。
- 意义:确保表中的字段都是最基础的单元,不可再分。例如,地址字段不应该包含多个地址,而应该被拆分为更具体的字段,如“省”、“市”、“区”等。
- 第二范式(2NF):
- 定义:在满足第一范式的基础上,非主键列必须完全依赖于主键,而不能只依赖于主键的一部分(针对复合主键)。
- 意义:确保表中的每列都与主键有完整的关系。如果某列只与主键的一部分有关,那么它应该被拆分到另一个表中,并通过主键与原始表关联。
- 第三范式(3NF):
- 定义:在满足第二范式的基础上,非主键列之间不存在传递依赖关系。也就是说,非主键列之间不应该存在依赖关系,而是应该通过主键与其他表关联。
- 意义:消除表中的传递依赖,进一步减少数据冗余。如果一个非主键列依赖于另一个非主键列,那么这两个列应该被拆分到不同的表中,并通过适当的关系连接。
通过将数据按照这些范式进行拆分和组织,可以确保数据库结构的合理性、减少数据冗余、提高查询效率,并使得数据库更易于维护和扩展。当然,在实际应用中,可能需要根据具体情况权衡和选择是否完全遵守这些范式,因为过度的拆分也可能导致查询变得复杂和效率低下。
假设我们有一个记录学生课程成绩的表,下面将分别展示不满足、满足第一范式、满足第二范式以及满足第三范式的表结构,并解释它们之间的区别。
不满足第一范式(1NF)的表结构
表名:订单信息表
字段名 | |
---|---|
商品ID | PK |
用户ID | PK |
用户名 | |
用户地址(省) | |
用户地址(市) | |
用户地址(县) | |
商品名 | |
购买信息(价格,数量) | |
总金额 | |
购买日期 |
问题:这个表中 购买信息(价格,数量) 包含价格,数量两个信息,因此不满足原子性
满足第一范式(1NF)的表结构
我们将其拆分为 单价和数量两个字段即可满足1NF
表名:订单信息表
字段名 | |
---|---|
商品ID | PK |
用户ID | PK |
用户名 | |
用户地址(省) | |
用户地址(市) | |
用户地址(县) | |
商品名 | |
单价 | |
数量 | |
总金额 | |
购买日期 |
问题:这个表结构不满足第二范式,因为用户信息,商品信息,订单信息字段都是非原子性的,各属于不同的依赖主键如数量,总金额,购买日期依赖于(用户id和商品id),商品价格依赖商品id,用户信息依赖用户id。
满足第二范式(2NF)的表结构
我们将其拆分为三张表确保了每个表中的字段都是原子性的,满足了第二范式的要求。
商品表
字段名 | |
---|---|
商品ID | PK |
商品单价 | |
商品信息 |
用户表
字段名 | |
---|---|
用户ID | PK |
用户信息 | |
用户地址(省) | |
用户地址(市) | |
用户地址(县) |
**订单表 **
字段名 | |
---|---|
订单ID | PK |
用户ID | PK |
商品ID | PK |
数量 | |
总金额 | |
购买日期 |
现在订单表中信息,完全依赖订单ID,三张表的非主机字段完全依赖主键字段,因此满足第二范式,但是因为用户地址,县依赖于市,市依赖省,这种传递依赖存在数据冗余,不符合3NF 要求
满足第三范式(3NF)的表结构
我们将用户地址信息单独拉出来设计一地址信息表即可满足第三范式要求
用户表
字段名 | |
---|---|
用户ID | PK |
用户信息 | |
地址ID | PK |
地址信息表
字段名 | |
---|---|
地址ID | PK |
用户地址(省) | |
用户地址(市) | |
用户地址(县) |
总结
- 第一范式(1NF):确保表的每一列都是不可分割的原子项。这通常意味着需要将包含多个数据项的字段拆分为单独的表,并通过关系连接这些表。
- 第二范式(2NF):在第一范式的基础上,确保表中的非主键列完全依赖于主键。如果存在部分依赖,则需要进一步拆分表。
- 第三范式(3NF):在第二范式的基础上,消除表中的传递依赖。这意味着非主键列之间不应该存在依赖关系,而是应该通过主键与其他表关联。
通过遵循这些范式,我们可以创建结构清晰、冗余少的数据库表,从而提高数据库的性能和可维护性。