是否按业务领域做过库表建模?
未标记
考查重点:领域实体与事务约束。从业务概念与状态规则推实体关系,给一条事务说明为什么这些表/约束必须一起保持正确
本题目录
参考答案
核心回答
按业务领域建模,应先识别业务概念、规则和状态变化,再决定实体关系及库表结构。回答项目经历时,可以用自己真实负责的一个业务流程,说明为什么拆这些表、哪些约束必须一起保持、查询和并发如何支持;仅列出“用户表、订单表、商品表”还不足以体现建模过程。
例如以订单为说明案例,应先定义订单、订单项、支付、退款和库存各自的职责,而不是因为页面里一起展示,就把它们全部堆进一张大表。
从业务规则到模型
先与业务统一术语和边界:订单的“完成”是支付完成、发货完成还是履约完成?支付与结算中的“金额”含义是否一致?这些定义决定哪些状态和字段应由哪个业务模块维护。
再识别实体、值对象和聚合。订单有稳定身份,订单项、金额和地址等承载不同规则;聚合围绕必须一起维护的不变量组织,例如订单项金额与订单应付金额如何保持一致。支付流水和库存有各自生命周期,不能因为有关联就认定必须属于同一聚合。
如何映射到库表
领域对象与表不必一一对应。关系型存储可以使用订单主表、订单项表及必要的状态/版本字段,将关系和约束落实为主键、唯一键、非空及合理的数据类型;业务逻辑仍需表达合法状态迁移,不能只靠任意更新状态字符串。
下单时需要保留当时的商品名称、单价等快照,避免商品后续变化改写历史;金额使用合适精度,时间明确时区和业务口径。并发修改可结合版本条件更新或数据库锁,关键业务请求设置唯一标识以防重复。
索引围绕实际查询设计,例如按用户、商家、时间和状态查询。高频读模型可适当冗余,但需要明确数据来源与同步策略,不能让多张表都成为同一事实的独立权威。
事务和演进如何取舍
同一事务边界内优先保证业务不变量;跨领域协作通过明确接口或事件,并处理失败、重复和最终一致窗口。领域边界可以先落在一个模块化单体中,不必一开始就拆成多个服务和数据库。
设计评审可以用具体用例验证:创建、支付、取消、退款、重复请求、并发修改和历史查询各怎样走,数据是否能追溯。再考虑字段迁移、回填、兼容和索引成本。
常见追问
领域建模和数仓维度建模一样吗? 不一样。前者主要组织业务行为和一致性边界,后者主要支持统计分析。对应教程电商问数第1章可用于对照业务库与分析数仓的目标差异。
参考资料
- 国内:美团技术团队:领域驱动设计在互联网业务开发中的实践:借鉴从需求到聚合和仓储的步骤,组织正文中先表达业务规则、再落到工程实现的建模顺序。
- 国内:美团技术团队:DDD 在大众点评交易系统演进中的应用:交易退款等场景说明数据表先行为何可能分散业务规则,以及统一模型怎样管理变化。
- 国内:听风(JavaGuide 授权收录并完善):MySQL 高性能优化规范建议:参考字段与索引设计,解释正文中概念关系如何落到物理表,并权衡类型、冗余及查询维护成本。
- 国外:Martin Fowler:Domain Model:依据领域模型同时包含行为与数据的定义,区分正文中的业务建模与只列字段的表设计。
- 国外:Microsoft:Design the infrastructure persistence layer:借鉴聚合与仓储边界的讨论,解释正文中业务不变量、持久化与独立查询模型的关系。