领域驱动设计(DDD)【7】之数据库设计
文章目录
- 一 物理数据模型概述
- 二 参考词汇表
- 三 租户管理的数据库设计
- 四 组织管理的数据库设计
- 五 项目管理数据库设计
- 六 工时管理的数据库设计
- 与"经验驱动设计"的差异
- 与“ER 图法”的差异
- 模型驱动设计可以分成两大部分:模型的建立和模型的实现。模型的建立要求模型和业务需求一致,模型的实现要求实现和模型一致。而数据库设计,则属于模型的实现。
- 数据库设计需要和领域模型保持一致。
- 按照领域建模的四个模块,依次进行数据库设计。
一 物理数据模型概述
- 数据库设计属于模型驱动设计中的“模型实现”阶段,核心目标是将领域模型转化为包含表结构、字段、主键/外键关系和约束条件的物理数据模型。具体包括:建立表结构、定义字段数据类型与约束、确定主键/外键关系。物理模型的建立需遵循”实现与模型一致”原则,通过领域模型推导数据库结构。
- 物理数据模型支持两种等价表达方式:
- 使用绘图工具(如做点io)制作的符号化图示。
- SQL标准建表语句(CREATETABLE)两种方式可相互转换,图示法更直观便于沟通。
- 表结构符号规范包含三部分:
- 首行:表名称(英文命名)
- 第二行:主键定义(字段名+数据类型+PK标记)
- 后续行:字段列表(属性映射与补充字段)
- 命名规范要求:
- 表名使用词汇表规定的英文简称(如租户→tenant)
- 主键可采用极简命名(id)或表名组合(tenant_id)
- 每个表必须包含四个审计字段:
- created_at(创建时间)
- created_by(创建人ID)
- last_updated_at(最后修改时间)
- last_updated_by(最后修改人ID)
二 参考词汇表
分类 | 中文 | 英文 | 英文简称 |
---|---|---|---|
通用 | 经理 | manager | mng |
通用 | 成员 | member | n/a |
通用 | 负责人 | leader | n/a |
通用 | 记录 | record | n/a |
通用 | 备注 | notes | n/a |
通用 | 类别 | type | n/a |
通用 | 添加 | add | n/a |
通用 | 签订 | sign | n/a |
通用 | 使……生效 | enforce | n/a |
通用 | 结束(项目、合同等) | close | n/a |
通用 | 创建/建立 | create | n/a |
通用 | 启动 | start | n/a |
通用 | 分配 | assign | n/a |
通用 | 更换 | change | n/a |
租户管理 | 租户 | tenant | n/a |
组织管理 | 组织 | organization | org |
组织管理 | 员工 | employee | emp |
组织管理 | 岗位 | post | n/a |
项目管理 | 客户 | client | n/a |
项目管理 | 合同 | contract | n/a |
项目管理 | 项目 | project | n/a |
工时管理 | 工时 | effort | n/a |
三 租户管理的数据库设计
- 一个实体可以映射为一个数据库表。
- name 表示租户的名称。created_at,created_by,last_updated_at 和 last_updated_by 分别表示一条记录的创建时间、创建人、最后一次修改时间和最后一次修改人,创建人和最后修改人保存的是用户的 id。
四 组织管理的数据库设计
- 按照领域模型,租户和组织是一对多关联。一对多关联,在数据库设计时可以映射成一个外键。
FK(foreign key)
代表外键。FK=tenant_id
说明org
表中指向tenant
表的外键是tenant_id
字段。在基于云的应用里,为减少数据库处理的瓶颈,不主张建立真正的外键,而是用程序来保证外键约束。但是在物理数据模型里,希望表达外键参照,方便理解数据表间的关系,把实线箭头换成虚线箭头,表示虚拟外键。 - 关联上的多重性决定了外键字段的非空约束(NOT NULL)。租户和组织间的关联,在租户端实际是
“1..1”
,一个组织至少会关联一个租户,最多也只能关联一个租户。“1..1”
前面的“1”
就映射成了组织表里tenant_id
字段后面的非空约束。
- 数据库中其他所有表都有一个指向
tenant
表的虚拟外键,以便区分是哪个租户的数据。如果每个虚拟外键都画出来,我们的图会变得很乱,所以后面就只在表中写出tenant_id
。
- 接下来,用类似的方法完成组织、组织类别和员工实体。
- 首先org(组织)表有一个指向自身的虚拟外键
superior_id
,表示组织之间的上级关系,对应于领域模型中的自关联。emp
(员工)表和org
表之间有两个方向相反的虚拟外键,一个表示组织的负责人关系,另一个表示员工归属的组织。另外,emp
表中的num
、id_num
、name
、gender
、dob
分别表示员工号、身份证号、姓名、性别和出生日期(date of birth
)。
- 岗位和员工之间是多对多关联。必须增加一个关联表,来表达两者之间的关系。
emp_post
表来表达多对多的关联。表中包含post
(岗位) 和emp
两个表的主键作为自己的虚拟外键。采用由emp_id
和post_id
两个字段组成的复合主键。- 一般来说,主张用单独的
id
主键,只有符合以下两个条件时,才应该使用上面这种联合主键:
第一,两个外键字段,例如emp_id
和post_id
,唯一决定了一条记录;
第二,这个表的主键没有被其他表作为外键引用。
五 项目管理数据库设计
- 接着做项目管理模块,按照之前的前面,画出项目管理模块的物理数据模型图。
- 为避免整张图像蜘蛛网一样凌乱,每个模块画一张图。emp表在组织管理中出现过一次,在项目管理中又出现,所以使用
emp: 2
说明这是 emp 表的第 “2” 次出现。
六 工时管理的数据库设计
与"经验驱动设计"的差异
- 相较于依赖直觉的经验驱动设计(即"拍脑袋法"),领域驱动设计(DDD)方法强调通过领域模型与业务专家对齐需求,再转化为数据库设计。这种方法的优势体现在:
- 领域知识传递有效性:技术化的数据模型和建表语句难以被业务专家理解,而DDD通过领域模型实现业务与技术的高效沟通,确保数据库设计准确反映业务需求。
- 设计规范性保障:经验驱动设计易违反数据库范式(如第三范式),导致数据冗余和一致性问题。DDD的领域模型转换过程天然符合范式要求,其设计结果通常满足第三范式标准。
与“ER 图法”的差异
- 相较于传统ER图法(实体-联系模型),领域驱动设计(DDD)的领域建模方法具有以下核心区别:
-
表达能力差异:领域模型(UML类图)是ER图的超集,既能完整表达ER图的实体关系,还能补充业务规则、行为逻辑等ER图无法涵盖的要素,因此可完全替代ER图。
-
应用范围差异:ER图仅描述静态数据结构,服务于数据库设计;领域模型同时整合数据与行为,可同步指导程序设计与数据库设计,确保系统一致性。
-
方法论定位差异:ER图属于传统软件工程的设计阶段产物,而领域模型对应分析阶段的核心产出。DDD通过领域模型直接衔接分析与设计,消除了传统方法中概念设计→逻辑设计→物理设计的阶段割裂。
- 领域模型补全属性后即等效于传统逻辑设计,其转换为物理数据模型的过程即为物理设计。