数据库三大范式

记得有一次,我在一家小公司里做数据库维护,那时候公司刚刚起步,数据量不大,但结构比较混乱。
有一次,我处理一个销售订单的查询,发现数据重复严重,更新一个订单信息,相关联的订单信息都要跟着改,忙得头昏脑胀。

那时候我还在实习,对数据库的规范化不是很懂,只能硬着头皮一个字段一个字段地检查。
花了大半天时间,终于发现订单表的主键只有订单号,而订单金额只依赖于订单号,这不就是典型的第二范式(2 NF)的问题吗?我立刻把订单金额移到另一个表中,新的表以订单号和商品号作为主键,这样订单金额就只依赖于主键,不再依赖于订单号,问题就解决了。

那时候我突然想到,如果再往上规范,比如订单中的客户信息也依赖于订单号,而不是直接依赖于主键,那不还是会有问题吗?于是我又把客户信息拆分出来,建立了单独的表。

这次经历让我对数据库范式有了更深的认识。
规范化的过程,就像整理乱糟糟的房间,虽然一开始比较麻烦,但长远来看,能节省很多时间和精力。
不过,我也在想,对于小公司来说,过度规范化会不会造成资源浪费呢?毕竟,效率和资源也是需要权衡的。

数据库三大范式

说白了,数据库三大范式是关系型数据库设计中用来减少数据冗余、增加数据有效性和提高存储效率的三大准则。
其实很简单,这三大范式分别是第一范式(1 NF)、第二范式(2 NF)和第三范式(3 NF)。

先说最重要的,1 NF要求字段原子性,比如去年我们跑的那个项目,表中的每个字段只能表示单一含义,不能有复合字段,比如“姓名”“爱好1 ”“爱好2 ”这种设计就是错的。
另外一点,2 NF要求非主键字段必须完全依赖于整个主键,比如“订单ID+产品ID”为联合主键,但“客户地址”仅依赖“订单ID”这种设计也是不对的。
还有个细节挺关键的,3 NF要求非主键字段直接依赖于主键,不能依赖其他非主键字段,比如帖子表中包含“发帖人ID”“发帖人姓名”,但姓名依赖ID,这种设计就需要改进。

我一开始也以为完全遵循范式是最佳选择,但后来发现不对,因为这样可能导致表数量过多,查询需要多表关联,影响性能。
等等,还有个事,完全遵循范式可能会导致数据冗余和更新异常。
所以,在实际应用中,我们需要根据业务需求在3 NF基础上适度冗余,或者使用索引、缓存等技术来弥补性能损失。

我觉得值得试试的是,在遵循范式的基础上,根据具体业务场景适度调整,以达到数据一致性和查询效率的平衡。

数据库三范式是什么

记得有一次,我帮一家初创公司优化他们的数据库,那时候他们正准备上线一个电商网站。
他们的产品表里,产品名称、描述、库存量、价格这些信息都混在一起,一看就是没有按照范式来设计。
我花了两天时间,按照三范式重新设计了他们的数据库。

先是从第一范式开始,把产品名称、描述这些可以拆分的字段拆分出来,变成了单独的表。
然后又按照第二范式,把那些依赖主键的字段,比如产品价格,也单独成表。
最后,我又按照第三范式,把那些有传递依赖的字段,比如学院地址,也独立出来。

结果出来后,我发现数据库的查询速度确实快了不少,而且数据的冗余也减少了。
但是,我也发现,因为表变多了,有时候写查询语句还得在多个表之间跳来跳去,写起来有点复杂。

等等,我突然想到,如果他们的业务场景比较简单,可能完全遵循三范式反而会更好,因为这样可以简化维护。
但是对于那些需要频繁查询的场景,可能适当牺牲一些范式来提升性能会更合适。
不过,这也得看公司怎么权衡了。