1.什么是范式?
设计数据库表时所要遵循的某种规范的级别,比如家里装修买建材,最环保的是E0级,其次是E1级,还有E2级等等。
数据库范式也分为1NF,2NF,3NF,BCNF,4NF,5NF,一般在设计关系型数据库的时候,最多考虑到BCNF足够,为了性能上或者应对扩展的需要,达到1NF或者2NF即可。
需要注意的是符合高一级范式的设计,必定符合低一级范式,如符合2NF的关系模式,必定符合1NF
2.范式优缺点
优点:减少数据冗余,尽量让每一个数据只出现一次,保证数据的一致性。
缺点:在获取数据的时候,可能需要 join 多张表来获取最后的数据,查询脚本及速度可能会慢。
3.第一范式(1NF)
符合1NF的关系中的每个属性都不可再分,通俗的理解为,数据库表的每一列都是不可再分的原子列,如下图所示就不符合1NF的要求
比如:
商品名称 | 商品数量 | 商品单价 |
鸡蛋 | 1 | 4.5 |
4.第二范式(2NF)
2NF在1NF的基础上,消除了非主属性对于码的部分函数依赖
id | 姓名 | 系名 | 系主任 | 课名 | 分数 |
1 | 张三 | 机械 | 陈黎明 | 机械基础 | 60 |
1 | 张三 | 机械 | 陈黎明 | 专业英语 | 88 |
1 | 张三 | 机械 | 陈黎明 | 高等数学 | 84 |
2 | 李四 | 工学 | 张国 | 高等数学 | 64 |
什么是部分函数依赖:就是A依赖于B和C,A又依赖于B。
什么意思呢? 就是通过B和C可以确定A,但是只通过B也可以确定A,这个A就有部分依赖,A依赖于B和C,A又依赖于B,那么C就就是A的部分依赖
这个表有两个主键.学号和课名。可以通过两个主键学号id和课名确定分数。但是缺少其中任意一个主键都不能够确认分数。这是完全依赖。可以的。
然后通过学号id和课名可以确定姓名,但是只通过学号id就能确定姓名,所以他是有部分依赖的。
满足第二范式就要去除部分依赖,拆分:
id | 姓名 | 系名 | 系主任 |
1 | 张三 | 机械 | 陈黎明 |
2 | 李四 | 工学 | 张国 |
id | 课名 | 分数 |
1 | 机械基础 | 60 |
1 | 专业英语 | 88 |
1 | 高等数学 | 84 |
2 | 高等数学 | 64 |
此时不存在部分依赖,满足第二范式.
5.第三范式(3NF)
不能存在传递函数依赖:比如A依赖于B,B依赖于C,然后C就传递函数依赖于A,这就是传递函数依赖。
id | 姓名 | 系名 | 系主任 |
1 | 张三 | 机械 | 陈黎明 |
2 | 李四 | 工学 | 张国 |
系名依赖于学号id,系主任依赖于系名,所以系主任传输依赖于学号id,不满足第三范式,需要拆分:
id | 姓名 | 系名 |
1 | 张三 | 机械 |
2 | 李四 | 工学 |
系名 | 系主任 |
机械 | 陈黎明 |
工学 | 张国 |
id | 课名 | 分数 |
1 | 机械基础 | 60 |
1 | 专业英语 | 88 |
1 | 高等数学 | 84 |
2 | 高等数学 | 64 |
符合第三范式。
需要注意的是,在设计表结构的时候不一定要根据三范式,因为三范式是减少了数据的冗余,但是要查所有的数据就需要将所有的表join,增加的脚本的复杂度并且降低了脚本查询效率。具体要不要完全满足三范式,根据自己业务需求决定。