找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

431

积分

0

好友

61

主题
发表于 昨天 00:39 | 查看: 5| 回复: 0

在进行数据库设计时,规范要求我们遵循经典的三大范式:

  • 第一范式:要求属性具备原子性,不可再分。
  • 第二范式:要求记录有唯一标识,确保实体的唯一性。
  • 第三范式:要求字段间没有冗余,即任何字段都不能由其他字段派生出来。

刻板遵循范式可能导致的问题

然而,在实际业务场景中,完全僵化地遵守范式,特别是第三范式,有时会引发逻辑悖论。

举例说明: 在一个电商订单系统中,假设用户地址仅保存在用户表里。若用户在下单时地址为“上海A”,系统根据第三范式,订单表只保存用户ID。然而,若用户在订单发货前将地址修改为“北京B”,当快递员根据当前用户地址“北京B”去取件(比如用户发起退货)时,实际上应该去的是“上海A”。这便造成了业务逻辑的混乱,最终导致用户体验受损甚至投诉

为了解决这个问题,常见的做法是:在创建订单时,将用户当时的收货地址直接冗余存储在订单表中。 这时问题来了:这难道不是直接违反了第三范式吗

关键思路转变:从“冗余”到“业务快照”

答案是:这并非简单的技术妥协,而是一种有明确业务目的的设计。

  • 视角转换:我们不应将此处的“地址”简单视为对用户表中地址的冗余复制。更合理的理解是,这是订单在创建那一刻,对用户收货地址信息的一个不可变的“快照”。这个快照是订单本身的一个属性,它独立于后续用户信息的任何变更。
  • 核心理念:这种设计是 “业务驱动” 的,而非对范式的无原则违背。我们不应为了范式而范式,合理的反范式设计应当满足以下前提:
    1. 冗余数据有明确的、不可变的业务意义(如订单快照、历史状态)。
    2. 冗余不会引入难以维护的数据一致性问题(例如,这里的地址快照一旦生成便不再更新,与用户当前地址解耦)。
    3. 冗余能显著提升业务效率或简化模型(例如,查询订单信息时无需再关联用户表获取历史地址,简化了后端业务模型与查询逻辑)。

因此,在数据库设计中,理解业务上下文比机械套用规则更为重要。适当的、有业务依据的冗余,是构建健壮、高效系统的重要手段。




上一篇:自动驾驶HIL测试实战:硬件在环仿真的核心价值与技术要点
下一篇:Java性能优化:try-catch在for循环内外的最佳实践与底层原理解析
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-8 23:51 , Processed in 0.077990 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表