mysql如何支持领域驱动设计_mysql DDD数据库建模思路

7次阅读

MySQL 不支持 DDD,但可通过表结构设计、约束和命名规范适配 DDD 原则:聚合根建主表并用外键 / 检查约束保障内聚性,值对象嵌入 JSON 或冗余字段,禁止跨聚合外键引用,用视图封装只读查询,领域逻辑优先放在应用层事务中实现。

mysql 如何支持领域驱动设计_mysql DDD 数据库建模思路

MySQL 本身不支持 DDD,但可以配合 DDD 建模原则使用

MySQL 是关系型数据库,没有内置聚合根、值对象、领域事件等概念,也不提供领域模型校验或生命周期管理。DDD 是一种设计思想,不是数据库能力。关键在于:如何让 MySQL 的表结构、约束和访问方式,不破坏 DDD 的边界与语义。

用表映射聚合根,而非实体或值对象

聚合根是 DDD 中唯一允许被外部直接引用的领域对象。对应到 MySQL,应为每个聚合根建一张主表,并通过外键、唯一约束、CHECK(MySQL 8.0.16+)体现其内聚性。

  • order 表作为 Order 聚合根,包含 idstatuscreated_at 等核心字段;订单项(OrderItem)必须通过 order_id 关联,且不允许独立存在(加 ON DELETE CASCADE
  • 避免把 Address(值对象)单独建 address 表并全局复用——它应作为 JSON 字段嵌入 ordercustomer 表(shipping_address JSON),或冗余为若干字段(ship_street, ship_city),前提是该地址不承载独立业务规则
  • 禁止跨聚合根直接外键引用:比如 product_idorder_item 表中应为普通字段(非外键),因为 Product 是另一个聚合根,引用应通过领域服务协调,而非数据库级强制

用视图 + 存储过程封装领域行为(谨慎使用)

MySQL 可以用 VIEW 暴露只读聚合快照,用 PROCEDURE 封装需事务保证的复合操作(如“创建订单并扣减库存”),但要注意:存储过程会把领域逻辑下推到数据库层,削弱可测试性与语言一致性。

  • 适合场景:报表类聚合查询(CREATE VIEW order_summary AS SELECT ……)、强一致性要求且性能敏感的原子操作
  • 风险点:MySQL 存储过程难调试、难版本化、无法 mock,与应用层 ORM(如 SQLAlchemy、MyBatis)协同成本高
  • 更推荐做法:在应用层用事务包裹多个 INSERT/UPDATE,由领域服务控制流程,MySQL 仅提供 ACID 底层保障

用命名与注释显式表达领域语义

MySQL 不识别领域术语,但字段名、表名、索引名、COMMENT 都是传达意图的载体。这对团队理解边界至关重要。

  • 表名用单数、领域术语:order 而非 ordersinventory_adjustment 而非 stock_log
  • 字段加 COMMENT 说明业务含义:
    ALTER TABLE `order` MODIFY `status` ENUM('draft', 'confirmed', 'shipped', 'cancelled') COMMENT '订单生命周期状态,变更需经领域规则校验';
  • 索引名带业务前缀:idx_order_customer_id 明确这是支撑“按客户查订单”的查询场景,而非技术索引
  • 避免通用字段名:typeflagdata 会模糊领域职责,改用 payment_methodis_tax_includedmetadata_json
DDD 在 MySQL 上落地最难的不是技术实现,而是坚持“聚合内强一致、聚合间最终一致”这一原则。很多团队用外键强行绑定两个聚合根,表面看数据一致,实则把领域耦合锁死在数据库层,后续演进代价极高。

text=ZqhQzanResources