金三银四精选面试题-了解过数据库设计三大范式吗?在项目中遵循过吗?
2023-11-19 09:47:40
了解过数据库设计三大范式吗?在项目中遵循过吗?
数据库设计的三大范式是一种设计规则,旨在帮助设计出高质量的数据库模型。这些规则旨在确保数据库表中的数据是冗余尽可能少,数据冗余会导致数据的不一致性。
第一范式(1NF)要求每个字段都是原子性的,也就是说,每个字段都只能包含单个值。
第二范式(2NF)要求每个表中的非主键字段都完全依赖于表的主键。
第三范式(3NF)要求每个非主键字段都与主键字段或其它非主键字段没有传递依赖关系。
在我参与的项目中,我们确实遵循过这三大范式。我们在设计数据库模型时会考虑这些规则,以确保数据库表是冗余尽可能少的,并且数据的一致性得到保证。
范式再给我们带来的上面的好处时,同时也伴随着一些不好的地方:按照范式的规范设计出来的表,等级越高的范式设计出来的表越多。如第一范式可能设计 出来的表可能只有一张表而已,再按照第二范式去设计这张表时就可能出来两张或更多张表,如果再按第三范式或更高的范式去设计这张表会出现更多比第二范式多 的表。表的数量越多,当我们去查询一些数据,必然要去多表中去查询数据,这样查询的时间要比在一张表中查询中所用的时间要高很多。
也就是说我们所用的范式越高,对数据操作的性能越低。所以我们在利用范式设计表的时候,要根据具体的需求再去权衡是否使用更高范式去设计表。在一般的项目中,我们用的最多也就是第三范式,第三范式也就可以满足我们的项目需求,性能好而且方便管理数据;
当我们的业务所涉及的表非常多,经常会有多表发生关系,并且我们对表的操作要时间上要尽量的快,这时可以考虑我们使用“反范式”。
所谓反范式,故名思义,跟范式所要求的正好相反,在反范式的设计模式,我们可以允许适当的数据的冗余,用这个冗余去取操作数据时间的缩短。也就是利用空间来换取时间,把数据冗余在多个表中,当查询时可以减少或者是避免表之间的关联;
场景分析:
如我们现在要对一个 学校的课程表进行操作,现在有两张表,一张是学生信息student(a_id,a_name,a_adress,b_id)表,一张是课程表 subject(b_id,b_subject),现在我们需要一个这样的信息,把选择每个课程的的课程名称和学生姓名输出来:
SQL语句为:
select B.b_id,B.b_subject,A_a_name from student A ,subject B;
当上面的数据量不多时,我们这样去查询没有问题;当我们的两张表的数据都是在百万级的时候,我们去查上面的信息, 问题出现了,这个查询动不动就是几百毫秒,甚至更慢,这样的查询效率根本不能满足我们对于网页速度的要求(一般不能超过100毫秒),怎么办?当然要反范式,在课程表里面添加冗余字段——学生姓名,这样我们就可以通过下面的查询达到同样的目的:
SQL语句为:
select b_id,b_subject,a_name from subject B;
将两个查询放在一起查看执行计划,就会发现,第一个查询开销占了92%,而第二个才8%,也就是说,第二个查询比起第一个查询,效率上优化了10倍以上,成果显著啊。
当我们开始着手一个项目后,范式的应用是这样的变化的:
第三范式数据库的设计—–>当数据量越来越大,达到百万级时,经常要对一些多表数据进行大范围高频率进行操作——->范式数据库的设计———->网站的数据量再持续增长———->范式和反范式的数据库设计
当我们的数据量非常大,目前除了对数据库的设计改动外,还可以通过对数据层进行缓存处理。如现在使用效果显著的Memcached ,一个分布式的缓存系统,我们将数据库信息以实体类的方式和图片文件等保存在Memcached里面,只要是可序列化的数据,经过装箱和拆箱,都可以保存 到Memcached中并随时可以快速的访问到这些对象,Memcached可以解决大量数据的缓存并保持多台Web Server得到的缓存数据是一致的。