概念:每列的数据必须保证其原子性,即每列的数据必须细化到不可再拆分
案例:
学号 | 姓名 | 班级 |
---|---|---|
001 | 张三 | Java01班 |
002 | 李四 | Java02班 |
003 | 王五 | UI01班 |
004 | 赵六 | 产品02班 |
在上述表中,班级字段存在数据冗余,如果我们想统计Java学科的人数或者01班级的人数岂不是很尴尬?根据第一大范式条件必须保证每一列数据的原子性,我们可细化分如下:
学号 | 姓名 | 学科 | 班级 |
---|---|---|---|
001 | 张三 | Java | 01班 |
002 | 李四 | Java | 02班 |
003 | 王五 | UI | 01班 |
004 | 赵六 | 产品 | 02班 |
概念:在满足第一范式的条件下,每一列的数据都完全依赖于主键,不产生局部依赖,每张表都只描述一件事物
案例:
学号 | 姓名 | 年龄 | 商品id | 商品名称 | 商品价格 |
---|---|---|---|---|---|
001 | 张三 | 21 | 110 | 笔记本电脑 | 4999 |
002 | 李四 | 22 | 111 | 华为手机 | 2499 |
根据第二大范式,表中的数据不能产生局部依赖,上述表中很明显姓名、年龄是依赖于学号的,而商品名称、商品价格是依赖于商品id的,表设计中存在局部依赖,并且一张表中描述了两个事物
根据第二范式细化:拆分成一张学生表和一张商品表
学生表:
学号 | 姓名 | 年龄 |
---|---|---|
001 | 张三 | 21 |
002 | 李四 | 22 |
商品表:
商品id | 商品名称 | 商品价格 |
---|---|---|
110 | 笔记本电脑 | 4999 |
111 | 华为手机 | 2499 |
概念:在满足第二范式的条件下,表中的每一列不存在传递依赖,每列都直接依赖于主键
案例:
编号 | 姓名 | 年龄 | 部门名称 | 部门地点 |
---|---|---|---|---|
001 | 张三 | 21 | 研发部 | 南昌 |
002 | 李四 | 22 | 运营部 | 九江 |
根据第三范式,每一列应该直接依赖于主键
我们应该拆分成一张用户表和一张部门表,通过建立外键来建立两表之间的关系
员工表:
编号 | 姓名 | 年龄 | 部门编号 |
---|---|---|---|
001 | 张三 | 21 | 001 |
002 | 李四 | 22 | 002 |
部门表
部门id | 部门名称 | 部门地点 |
---|---|---|
001 | 研发部 | 南昌 |
002 | 运营部 | 九江 |
一般我们设计表都会按照数据库的三大范式,但是在某些情况下我们查询的数据在多张表中,例如我们需要查询员工的信息并且希望带出员工的部门名称,这个时候我们必须使用join关联表查询,如果这些数据是查询非常频繁的,那么无疑会降低数据库的读性能
反范式设计表:
编号 | 姓名 | 年龄 | 部门名称 |
---|---|---|---|
001 | 张三 | 21 | 研发部 |
002 | 李四 | 22 | 运营部 |
此时数据都在一张表,查询也不用join关联查询,以此提高读取性能