大多数面试的时候,问数据库知识,问得最多得就是索引、事务。但是有一个知识点不可忽略就是数据库范式,熟悉数据库范式,会给你带来意想不到的收获
第一范式(1NF)定义:强调列的原子性。即列不能够分存其他几列
如下表就不满足1NF要求,进货、销售属性列均包含两个属性
不满足1NF的数据库一定不是关系型数据库
第二范式(2NF)定义:2NF在1NF的基础上,消除了非主属性对于主键的部分函数依赖
在1NF的基础上,增加两点
表必须有一个主键 非主键类必须完全依赖于主键,不能只依赖主键的一部分考虑如下表
学号 | 课程名 | 姓名 | 年龄 | 成绩 | 学分 |
---|---|---|---|---|---|
[学号,课程名][学号,课程名][学号,课程名], 组合属性,作为主键。只有成绩完全依赖于主键[学号,课程名][学号,课程名][学号,课程名],姓名、年龄依赖于学号学号学号、学分依赖于课程名课程名课程名,属于部分依赖主键
缺点:不满足2NF的表,主要的缺点就是数据冗余。同一个课程由nnn个学生选修,学分重复n−1n-1n−1次。同一个学生选修mmm门课,则姓名、年龄就重复m−1m-1m−1次
可以拆分为
学生表: [学号,姓名,年龄] 课程表:[课程号,学分] 成绩表[学号,课程,成绩]
第三范式(3NF)定义:3NF在2NF的基础上,消除非主属性对于主键的传递函数依赖
在2NF的基础上增加,非主属性列必须直接依赖于主键,不能存在传递依赖。即非主属性A依赖于非主属性B,非主属性B依赖于主键
如下表:属于2NF,但不属于3NF。学院地点、学院电话传递函数依赖于学号(主键)
学号 | 姓名 | 年龄 | 所在学院 | 学院地点 | 学院电话 |
---|---|---|---|---|---|
其实也存在数据冗余。如果插入同一个学院的学生,学院地点、学院电话将会重复
可以拆分为
学生表:[学号,姓名,年龄,所在学院] 学院表:[学院,学院地点,学院电话]
鲍依斯-科得范式(BCNF)定义:在3NF基础上,消除了主属性对主键的部分和传递函数依赖
在3NF的基础上,不存在任何属性对任一候选关键字的部分和传递函数依赖
如下表(一个仓库,只能有一个管理员,一个仓库可以存储多种物品)
仓库ID | 管理员ID | 物品ID | 物品数量 |
---|---|---|---|
[仓库、管理员、物品][仓库、管理员、物品][仓库、管理员、物品]组合属性为主键,数量数量数量为非主属性,显然是满足3NF的
但是存在仓库→\rightarrow→管理员、管理员→\rightarrow→仓库。主属性对主键的部分函数依赖
缺点:更新异常:换了仓库管理员,表中同一仓库的所有行的管理员id都要修改
可以拆分为
仓库管理表: [仓库,管理员]、[仓库、物品、物品数量]
参考文章数据库范式(1NF 2NF 3NF BCNF)详解