# mysql三范式 范式|详情 ---|--- [第一范式](#第一范式)|要求数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值。 [第二范式](#第二范式)|实体中没一行的所有非主属性都必须完全依赖于主键;即:非主属性必须完全依赖于主键。 [第三范式](#第三范式)|实体中的属性不能是其他实体中的非主属性。因为这样会出现冗余。即:属性不依赖于其他非主属性。 ## 第一范式 ```text 数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值。 ``` - 不符合第一范式的实例: ![](https://raw.githubusercontent.com/shiwenyuan/pic/master/20200413125928.png) - 存在问题: - 最后一条记录和第一条重复(不唯一,没有主键) - 联系方式字段可以再分,不是原子性的 ![](https://raw.githubusercontent.com/shiwenyuan/pic/master/20200413130053.png) ```text 关于第一范式,每一行必须唯一,也就是每个表必须有主键,这是数据库设计的最基本要求,主要采用数值型或定长字符串表示,关于列不可再分,应该根据具体的情况来决定。如联系方式,为了开发上的便利可能就采用一个字段。 ``` ## 第二范式 ```text 第二范式是建立在第一范式基础上的,另外要求所有非主键字段完全依赖主键,不能产生部分依赖 ``` 实例: ![](https://raw.githubusercontent.com/shiwenyuan/pic/master/20200413130147.png) 确定主键: ![](https://raw.githubusercontent.com/shiwenyuan/pic/master/20200413130213.png) ```text 以上虽然确定了主键,但此表会出现大量的冗余,主要涉及到的冗余字段为“学生姓名”和“教师姓名”,出现冗余的原因在于,学生姓名部分依赖了主键的一个字段学生编号,而没有依赖教师编号,而教师姓名部分依赖了主键的一个字段教师编号,这就是第二范式部分依赖。 ``` 解决: ![](https://raw.githubusercontent.com/shiwenyuan/pic/master/20200413130829.png) ## 第三范式 建立在第二范式基础上的,非主键字段不能传递依赖于主键字段(不要产生传递依赖) ![](https://raw.githubusercontent.com/shiwenyuan/pic/master/20200413130659.png) 上表中,班级名称字段存在冗余,因为班级名称字段没有直接依赖于主键,班级名称字段依赖于班级编号,班级编号依赖于学生编号,这就是传递依赖,解决的办法就是将冗余字段单独拿出来建立表: ![](https://raw.githubusercontent.com/shiwenyuan/pic/master/20200413130740.png) ### 总结 实际开发中,数据库设计尽量遵循三范式,但是还是根据实际情况进行取舍,有时可能会拿冗余换速度,最终目的是要满足客户需求