第一范式
1 数据库所有字段都只有单一属性。
 2 单一属性由基本数据类型构成。
 3 数据库的表都是二维的行与列。
 
 例如上面的例子就不满足第一范式,因为是可以继续拆分的,拆分为更多的属性。
第二范式
1 符合第一范式
 2 表必须有个主建
 3 其它字段可以由主键确定
 4 二范式目的是通过拆表减少数据冗余
 
 上面的表存在三个异常:
- 插入异常,如果要新建一个系,目前这个系还没有学生则插入不了。
 - 删除异常,如果这个系的学生都被删除了,那么这个系耶就不存在了。
 - 更新异常,如果我们需要改学生的系名,则需要修改多个地方,系主任都要修改。
 
上面的表比如课程是由系来决定的,每个系不一样,分数则是由学号和课程共同决定的所以上面这张表可以拆分为两张表,这样主键就可以唯一确定一个属性:
 
 这样拆分以后删除异常还是存在,比如学生高芳芳不存在了,那么这个时候法律系也不存在了,同时系主任依赖于系名,只有知道了系名才有系主任,所以需要进一步拆分。
第三范式
1 要求符合第二范式
 2 字段要求依赖于主键,不允许间接依赖
 3 第三范式的目的在于拆分实体(完善主从表)
 
 三范式不是强制要求,需要根据场景进行选择,否则会出现主从表关系过多,影响SQL效率。



![[Windows] 油.管视频下载神器 Gihosoft TubeGet Pro v9.3.88](https://i-blog.csdnimg.cn/direct/6e3b3785bb1f4c158f6d87d2380c5bb0.png)




![二叉搜索树的实现[C++]](https://i-blog.csdnimg.cn/direct/736dbe00da704034a33908d6642f92f9.jpeg#pic_center)










