对数据库设计的理解—范式选择

本文主要探讨一下本人针对数据库设计的一点心得体会
数据库范式

数据库设计对数据的存储性能,还有开发人员对数据的操作都有莫大的关系。所以建立科学的,规范的的数据库是需要满足一些规范的来优化数据数据存储方式,在关系型数据库中这些规范就可以称为范式。

第一范式:当关系模型R的所有属性都不能再分解为更基本的数据单位时称R为第一范式,及数据表的属性都是最基础的,不可以再分。

第二范式:每个表必须有且仅有一个数据元素为主关键字(Primary key),其他数据元素与主关键字一一对应,在数据库设计中要求数据表如果只有一个主键时就满足第二范式。第二范式主要是要求在一个数据表中,一个表只能存储一种数据,不可以把多种不同数据形式保存在同一张表中。

第三范式:满足第三范式前提是满足第二范式。同时,实体中的属性不能是其他实体中的非主属性,因为这样会出现冗余。如果一个实体出现其他实体的非主属性,可以将这两个实体用外键关联,而不是将另一张表的非主属性直接卸载当前表中。第三范式的目的主要是防止数据的冗余

BC范式(BCNF):BC范式的定义是在关系模型中每一个决定因素都包含候选键,也就是说只要属性或者属性组A能够决定属性B,则A的子集中必须有候选键。看起来很复杂,来看看例子。

StudentId Major Advisor MajGPA
1 人工智能 Edward 4.0
2 大数据 William 3.8
1 大数据 William 3.7
3 大数据 Joseph 4.0

上面这张表学生ID和专业ID为联合主键,但是导师只能对应一个专业,所以我们可以拆分数据表,将Advisor和Maior单独成另一张表。

学生导师表:

StudentId Advisor MajGPA
1 Edward 4.0
2 William 3.8
1 William 3.7
3 Joseph 4.0

导师表:

Advisor Major
Edward 人工智能
William 大数据
Joseph 大数据

好了这就是BC范式了,主要目的还是为了减少冗余。

我的理解和设计

我在设计数据表的时候会严格按照前三个范式进行设计,但是偶尔会不满足BC范式,及处于第三范式和BC范式之间。因为在实际的业务中很有可能会遇到以下情况。

就拿上面这张表为例,如果我们想要查询选修了大数据专业的所有学生的ID,此时如果是BC范式并且是单表查询的话,我们要先查询导师表,找到所有的大数据方面的导师,然后查找学生导师表查找出学生ID,或者两个表做join进行联合查询,而如果是第三范式则可以直接查询到对应学生ID,从速度上来说第三范式是肯定快过BC范式的,但空间上会产生一定的冗余。

如果我们现在把条件想象的比较特别,如果这两个表数据都很多,那么速度差异就更加明显了,同时由于join查询时会占用较长的数据库执行时间,很可能会造成其他数据库请求的等待,这是得不偿失的。而且在实际开发中常常会碰到改表改库的情况,单表的sql语句大多可以自动生成如Mybatis,如果你手写了一条多表联合查询,等下次数据库改动,又要重写,这一点是不符合敏捷开发的原则。综上所述,我个人更愿意用空间换时间,用空间来换开发效率。

-->