news 2026/7/1 23:10:49

接口还是慢,也许是你的表太规范了

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
接口还是慢,也许是你的表太规范了

当业务逻辑稍微复杂一点,也建立了合适的索引,可能仍然解决不好接口访问数据库时的性能问题。有时,为了遵循数据库第三范式而精心设计的表结构和JOIN查询,正成为新的性能瓶颈。

第一范式(1NF)要求表的每个格子只能存一个值;第二范式(2NF)要求存在多列主键时,属性列必须完全依赖于所有主键列,而不是部分依赖;第三范式(3NF)则要求属性列之间不能存在传递依赖,即如果某列存储了其他列的 ID,就不应再重复存储该 ID 对应的其他属性。通过第三范式设计表结构,可以实现数据无冗余、依赖唯一。

在实际业务中,严格遵循它往往导致许多查询需要通过 JOIN 多张表才能凑齐一条完整信息。要查询满足条件的所有行,可能需要多次扫描全表、连接、排序,耗时耗力。这时,我们就应考虑增加反规范化设计

1. 冗余列和派生列

冗余列是指违反上述 2NF 或 3NF,把原本依赖其他表的属性字段直接添加到当前表中。最常见的做法,是在订单表中增加用户名、商品名称等字段,避免每次查询都去关联用户表或商品表。派生列则是指通过其他列的值经过较为复杂的计算得出的新列,例如订单总价由单价和数量计算而来,若是简单计算,通常用视图即可解决,但若计算逻辑复杂或查询频繁,则可考虑将其持久化为实体列。

引入冗余列或派生列时,有一个简单的判断标准:大部分读取操作是否都需要用到某个外键关联信息或某个计算值。在记录历史数据(如订单、操作日志)的场景下,为了保证历史记录的完整性和不可变,即使主表的数据后续被修改或删除,也有必要在历史表中冗余存储关键信息的快照。

2. JSON 字段

在很多场景下,JSON字段是对数据库表结构的有利补充。例如,可以在一个字段内,存储一个由多个标签组成的数组,或者存储一个结构化的对象信息。从范式角度看,存储数组违反了第一范式,而存储对象则可能引入传递依赖,违反第三范式。

使用JSON字段的判断标准,在于确认字段内部的值是否仅与当前表记录本身相关,其他表不会直接关联到该JSON字段内部的某个具体值。如果JSON对象或数组内部的值不需要独立查询、更新或作为关联条件,那么用 JSON 存储非常合理,既能保持结构灵活,也能减少关联开销。


(图:使用冗余列、派生列、JSON列的典型表结构)

3. 预连接、预聚合报表

增加冗余列、派生列主要针对有明确筛选条件、范围较小的查询。但对于报表类、分析类的查询,其特点往往是需要扫描大量数据并进行复杂的连接和聚合,无论如何优化都难以避免全表扫描。这时,我们可以参考数据仓库的分层设计思想,构建预连接和预聚合的中间层。通常可以分为以下几层:

  • 数据接入与原始层(ODS):存放从业务数据库同步过来的原始数据,仅做格式标准化。
  • 数据明细与整合层(DWD):对原始数据进行清洗、转换,并关联补充必要的字段,形成一份干净、完整的明细数据。
  • 数据轻度汇总层(DWM):根据常见的报表维度(如按天、按部门、按产品类别),对明细数据进行轻度汇总聚合,形成中间结果。例如,预先计算好每天的销售额、订单数。
  • 数据应用与报表层(APP):基于汇总层的数据,进一步加工成业务可直接使用的结论性数据。这一层数据通常只会计算一次,保证历史数据不变,以保证对外输出的报表与数据库数据之间的统一。

此处,我们本身就是在设计业务数据库,“数据接入与原始层”就直接对应原始表;“数据明细与整合层”对应冗余列、派生列、查询视图;“数据轻度汇总层”、“数据应用与报表层”才是我们针对报表数据查询需求,需要增加的表。

通过这种分层预计算,将频繁使用的关联统计结果,批量写入,或用计划任务提前计算,在查询时只需扫描轻量级的汇总结果,从而实现了报表查询的及时响应。

4. 数据源与查询视图

反规范化是在规范设计与查询性能之间寻求平衡的重要手段。实施时,首先必须明确哪些表是底层数据源,哪些表或列是通过数据源重复生成的,并确保只直接修改数据源,生成表则应通过定时任务或实时链路保持同步。

在查询时,应只获取需要的数据列,避免使用 SELECT *,特别是在 ORM 框架中注意不要自动查询用不到的 TEXT、JSON 等大字段。

在写 WHERE 条件时,尽量将过滤条件写在最内层的子查询中,尽早减少数据处理量。对于非索引字段的查询,可以尝试结合索引字段过度限定。例如,查询某个结束日期范围内的记录,如果开始日期字段有索引,可以同时加上对开始日期的合理推断条件,以便数据库能利用索引快速定位数据。

总的来说,第三范式的规范化设计保证了“真相只有一个”,利于维护一致的原始数据。而反规范化则是在此基础上,通过有策略地冗余、预计算和结构化存储,固化常用的查询视图,从而兼顾查询性能与存储效率。

即使采用反规范化设计,也须时刻牢记“真相只有一个”的原则,保证数据的更新顺序,先修改原始表,再更新衍生表和列。这样才能在复杂业务中既保有清晰的模型,又获得高效的访问体验。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 11:02:37

【SSM毕设全套源码+文档】基于ssm的怀旧小筑客栈管理系统的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/7/1 8:53:40

计算机网络实验:(二)交换机和集线器的工作原理

目录 一、实验目的 二、实验要求 1.通过推荐视频学习Cisco Packet Tracer软件的使用方法; 2.掌握集线器的工作原理; 3.掌握交换机的工作原理和自学习算法 三、实验环境 四、实验结果 五、思考题 六、实验心得体会 一、实验目的 1.掌握Cisco Packet Tracer软…

作者头像 李华
网站建设 2026/7/1 20:33:07

FontExpert|高效字体管理,预览安装一键搞定

有朋友昨天私信求实用的字体管理工具,翻了翻收藏,发现 FontExpert 刚好适配需求,绿色版不用繁琐安装,不管是设计用还是日常整理字体都很顺手,分享给有需要的人。 下载地址:https://pan.quark.cn/s/45c23e1…

作者头像 李华
网站建设 2026/7/1 22:24:09

开机Database connections will be migrated 弹窗

开机弹窗问题 你遇到的 Database connections will be migrated 弹窗,来自 MySQL Notifier 这个工具。它想把自己的连接信息迁移到 MySQL Workbench 里。解决方法:直接点击弹窗里的 Yes 就可以一劳永逸,这个操作对你用 Navicat 连接数据库完…

作者头像 李华