后一个范式都是在满足前一个范式的基础上建立的.
1NF
无重复的列.表中的每一列都是不可分割的基本数据项.不满足1NF的数据库不是关系数据库.
如联系人表(姓名,电话),一个联系人有家庭电话和公司电话,则不符合1NF,应拆分为(姓名,家庭电话,公司电话).
2NF
属性完全依赖于主键.不能存在仅依赖于关键一部分的属性.
如选课关系(学号,课程名称,成绩,学分),组合关键字(学号,课程名称)作为主键.其不满足2NF,因为存在决定关系:课程名称->学分,即存在组合主键中的部分字段决定非主属性的情况.会导致数据冗余,更新/插入/删除异常.
所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是属性完全依赖于主键。比如说数学课考100分的有很多个,那么数据库里就是张三,数学,100;李四,数学,100……如果不分开的话是不是就会造成冗余,范式最主要的目的 大专栏 数据库三大范式和反范式 · oldmee就是禁止冗余。
3NF
属性不传递依赖于其它非主属性.非主键列必须直接依赖于主键,而不能传递依赖。即不能是:非主键A依赖于非主键B,非主键B依赖于主键.
如学生表(学号,姓名,学院编号,学院名称),学号是主键,姓名、学院编号、学院名称都完全依赖于学号,满足2NF,但不满足3NF,因为学院名称直接依赖的是学院编号 ,它是通过传递才依赖于主键.
反范式
范式可以避免数据冗余,减少数据库的空间,减轻维护数据完整性的麻烦.但等级越高的范式设计出来的表越多,可能会增加查询所需时间.当我们的业务所涉及的表非常多,经常会有多表连接,并且我们对表的操作要时间上要尽量的快,这时可以考虑我们使用“反范式”.也就是用空间来换取时间,主动求冗余,把数据冗余在多个表中,当查询时可以减少或者是避免表之间的关联.
比如两个表(用户id,好友id)和(用户id,用户昵称,用户邮箱,联系电话)符合3NF,如果需查询某个用户的好友(昵称)名单,此时需对2个表进行连接查询,可以把第一个表修改成(用户id,好友id,好友昵称)这样只需要查询第一个表就可获取所有好友昵称.