面试必问的数据库-4.1:表--建表方面,你可以考虑下,你项目是用三范式还是反范式,理由是什么?

有时候在面试的时候,有的面试官可能就问你数据库方面的一些知识。

有没有独立做过项目啊,

那你是怎么设计数据库的呢?

 

这里就不得不面对一个问题:

建表方面,你可以考虑下,你项目是用三范式还是反范式,理由是什么?

 

官方的描述:

1NF:

无重复的列.表中的每一列都是不可分割的基本数据项.

2NF:

属性完全依赖于主键.

3NF:

属性不传递依赖于其它非主属性.

非主键列必须直接依赖于主键,而不能传递依赖。

即不能是:非主键A依赖于非主键B,非主键B依赖于主键.

 

那什么是反范式呢?

反范式:

反范式化指的是通过增加冗余或重复的数据来提高数据库的读性能

 

例如:在下面中的user_role用户-角色中间表增加字段role_name。

 

反范式化可以减少关联查询时,join表的次数。

 

三范式详细说明:

1. 第一范式

确保数据表中每列(字段)的原子性。

如果数据表中每个字段都是不可再分的最小数据单元,则满足第一范式。

例如:user用户表,包含字段id,username,password

 

2. 第二范式

在第一范式的基础上更进一步,目标是确保表中的每列都和主键相关。

如果一个关系满足第一范式,并且除了主键之外的其他列,都依赖于该主键,则满足第二范式。

例如:一个用户只有一种角色,而一个角色对应多个用户。则可以按如下方式建立数据表关系,使其满足第二范式。

user用户表,字段id,username,password,role_id

role角色表,字段id,name

用户表通过角色id(role_id)来关联角色表

 

3. 第三范式

在第二范式的基础上更进一步,目标是确保表中的列都和主键直接相关,而不是间接相关。

例如:一个用户可以对应多个角色,一个角色也可以对应多个用户。则可以按如下方式建立数据表关系,使其满足第三范式。

user用户表,字段id,username,password

role角色表,字段id,name

user_role用户-角色中间表,id,user_id,role_id

像这样,通过第三张表(中间表)来建立用户表和角色表之间的关系,同时又符合范式化的原则,就可以称为第三范式。

 

我们项目中基本符合三范式的规则,

好像不存在反范式,

如果有很多的关联查询,我们会将数据组合成一个大的document,然后保存在非结构数据库中,如mongoDB。

然后每天做定时任务同步数据到mongoDB中,

查询的时候直接查mongo就可以了。

 

其实这里也有不好的地方,因为数据库表的各种关系存在,因此在同步的时候,同步先后问题,

各种判断比较复杂,导致我们数据时有时无的会丢失,在mysql中存在,同步到mongo中就丢失,

导致数据不一致。只能写一个接口手动强制同步。

目前我们项目还没有解决这种同步出错的问题。还是上面这种处理方式。

应该是有一些好的同步插件来做这种同步,

例如,mysql同步到es的logstash插件。

所以这个同步这块还是可以优化的。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章