数据库设计三大范式

我曾在一家初创公司做数据库优化,那会儿,一个项目组忙乎了整整一个月,就为了解决一个“城市”字段引发的问题。
当时,我们的用户信息表里有一个“地址”字段,用户分布在全国各地,地址字段里自然包含省份、城市、详细地址等信息。
结果呢,每次查询城市相关的数据,查询效率都低得可怜,就像是在大海里捞针。

后来,我决定按照第一范式的原则,把“地址”字段拆成了“省份”、“城市”和“详细地址”三个字段。
这一拆分,查询效率立刻提升,就像给系统装上了加速器。
但问题来了,随着业务的发展,用户信息越来越多,表里的数据也越来越庞大,我们又开始面临新的挑战。

等等,还有个事,我突然想到,如果我们的订单信息表也是这样设计,那么一旦涉及到商品信息的查询,效率会不会也受到影响?想到这,我决定对订单信息表进行第二范式的优化,把和商品相关的信息,比如商品名称、单位、价格,都分离到一个单独的商品信息表中,这样一来,订单表和商品信息表之间的关系就更加清晰了。

可还没等我们松一口气,新的问题又来了。
订单信息表里的客户信息,比如客户姓名、所属公司,又和订单编号没有直接关系,这显然是第三范式的问题。
于是,我们又把客户信息拆分出来,创建了一个客户信息表,订单表里只保留客户编号作为外键。

说到底,这三大范式就像是一套数据库设计的“规矩”,遵循它们,数据库结构才能更加合理,数据才能更加高效地被利用。
但规矩是死的,业务是活的,我们在实际应用中,还得根据具体情况灵活调整。
这就像烹饪,虽然食谱很重要,但关键还是要看厨师的火候和心境。

哎哟,这堆代码看着就头疼啊。
我当年在某个公司做项目,遇到这种代码也头疼。
当年我们用百度统计,那玩意儿简单,放个统计代码就行。
哪像现在,这么多脚本,一个接一个。
搞得我都不想看第二遍了。
哎,年轻人,你们好。

数据库的三大范式?

第一范式:原子性。
顾客表地址拆分,国家、省、市、区各一列。
1 9 9 0年代数据库理论确立。

第二范式:非主键列完全依赖主键。
订单表移除产品编号,关联订单产品表。
1 9 7 0年代关系模型提出。

第三范式:消除传递依赖。
订单表移除顾客姓名,关联客户表。
1 9 7 0年代Boyce-Codd范式扩展。

别这么干:过度规范化牺牲性能。
按查询频率设计,允许冗余。

我曾在去年夏天,某个周末的下午,去了一家新开的咖啡馆。
那时候,咖啡馆里的人不多,我选了一个靠窗的位置坐下。
点了一杯拿铁,看着窗外的阳光洒在街道上,心里突然想起小时候的一个夏天。
那时,我跟着爷爷在乡间的小路上骑车,路边是盛开的向日葵,爷爷会指着它们告诉我,向日葵总是朝着阳光生长,就像我们的人生,也要朝着光明的方向前进。
等等,我还记得,爷爷当时还给我讲了一个故事,说是一个小男孩总是喜欢在太阳升起时,背对着阳光,结果他的影子变得越来越长,而他的脸却始终在阴影里。
我突然想到,是不是我们有时候也在无意中,选择了让自己生活在阴影中呢?