4. 医疗数据明细层(DWD)建模

明细层(DWD)是数仓分层中承上启下的关键一层:它把 ODS 中贴源、杂乱、多源异构的原始数据,按业务过程重新组织为“可被复用的一致性明细”。与 ODS 的“原样落地”不同,DWD 要回答三个问题:这条数据描述的是哪个业务过程?它的最小可分析单元(粒度)是什么?围绕它有哪些稳定的分析维度?本节围绕业务过程梳理、事实表与维度表设计、医疗事件粒度选择、清洗与标准化四条主线展开。

一、业务过程梳理:先定“过程”,再定“表”

医疗数据的业务过程通常围绕患者就诊旅程展开,常见可识别过程包括:挂号、就诊(门诊/急诊/住院)、开立医嘱、执行医嘱、收费、检验检查申请与报告、发药与用药、手术、护理记录、出院结算等。梳理时建议用“过程—事件—动作—主体”四要素描述,例如“检验报告发布”这一过程,事件是报告出具,动作是审核发布,主体是检验科技师与患者。

梳理的产出不是表,而是一份业务过程清单,每个过程标注:源系统、触发时机、主键候选、时间戳字段、涉及维度、是否可累加。这份清单直接决定后续事实表的划分边界——一个业务过程通常对应一张(或一组)事实表,避免把“挂号”和“收费”硬塞进同一张表。

二、事实表与维度表设计

DWD 中事实表承载“发生了什么、发生多少、何时发生”,维度表承载“谁、在哪、什么类别”。医疗场景下事实表多为事务事实表(如一次收费、一条检验结果),少数为周期快照(如每日床位占用)或累积快照(如住院全流程节点)。

维度表设计要抓住医疗特有的缓慢变化维问题:患者基本信息(姓名、联系方式、地址)会变,科室会合并拆分,医生会调岗。对需要保留历史口径的维度(如科室归属),采用 SCD Type 2 拉链表,用 start_date、end_date、is_current 标记版本;对仅需最新值的属性(如患者手机号)可用 Type 1 覆盖。

事实表字段一般包含:业务主键、维度外键(患者、科室、医生、时间、项目)、度量值(金额、数量、时长)、以及审计字段(源系统、加载时间、批次号)。度量值要区分可加(金额)、半可加(余额)、不可加(比率),不可加指标应在下游计算而非落库。

三、医疗事件粒度选择

粒度是 DWD 建模中最容易出错、也最影响下游的决策。医疗事件粒度常见有:一次就诊、一条医嘱、一次执行、一条检验明细、一次收费明细。选择原则是“最细可用、可上卷”:能落到检验项目明细,就不要只落到报告头;能落到收费明细,就不要只落到结算单。

以检验为例,若粒度选“报告头”,则无法分析单项指标趋势;选“检验明细(报告+项目)”则可上卷到报告、就诊、患者。但粒度过细会带来膨胀,例如一条医嘱对应多次执行,若事实表按“执行”粒度,则医嘱信息需通过维度或冗余字段带入,避免下游反复关联。

判断粒度是否合适的一个实用方法:问“这张表的一行代表什么?”如果答案能用一句业务语言说清(如“一位患者在一次就诊中的一条检验项目结果”),粒度就是清晰的。

四、清洗与标准化

清洗解决“脏”,标准化解决“乱”。医疗数据常见问题包括:性别编码不统一(1/2、M/F、男/女)、日期格式混杂、金额单位不一致、诊断名称同义异名、科室名称随系统变更。清洗规则应可配置、可追溯,建议在 DWD 层保留原始值与标准化值两列,便于回溯。

标准化重点包括:编码标准化(性别、婚姻、民族、诊断 ICD-10、手术 ICD-9-CM-3、检验项目 LOINC 或院内标准码)、时间标准化(统一为 yyyy-MM-dd HH:mm:ss,时区一致)、金额标准化(统一为元,保留两位小数)、空值与异常处理(未知编码统一为 -1 或 'UNKNOWN',不轻易丢弃)。

下面给出一个可参考的清洗映射示例(示例数据,非实测):

-- 性别标准化映射(示例)
CASE
  WHEN gender IN ('1','M','男') THEN 'M'
  WHEN gender IN ('2','F','女') THEN 'F'
  WHEN gender IS NULL OR gender = '' THEN 'UNKNOWN'
  ELSE 'OTHER'
END AS gender_std

-- 金额标准化(示例)
CAST(amount AS DECIMAL(18,2)) AS amount_std

-- 诊断名称标准化(示例,映射到 ICD-10)
COALESCE(icd_map.icd10_code, 'R69') AS diag_code_std

清洗与标准化完成后,应做质量校验:主键唯一性、外键可关联率、关键字段空值率、金额非负、时间先后合理(如出院时间不早于入院时间)。校验不通过的数据进入隔离表并记录原因,而不是静默丢弃。

DWD 建模四步链路:过程 → 事实/维度 → 粒度 → 清洗标准化 ① 业务过程梳理 挂号 / 就诊 / 医嘱 检验 / 收费 / 发药 手术 / 护理 / 结算 产出:业务过程清单 ② 事实表 / 维度表 事实:度量 + 外键 维度:患者/科室/医生 SCD2 拉链保留历史 产出:事实表 + 维度表 ③ 医疗事件粒度 就诊 / 医嘱 / 执行 检验明细 / 收费明细 原则:最细可用可上卷 产出:一行业务含义 ④ 清洗与标准化 编码 / 时间 / 金额 ICD-10 / LOINC 映射 空值异常统一处理 产出:一致性明细 医疗事件粒度层级(以检验为例) 就诊粒度:一次就诊 → 可分析就诊次数、总费用 报告粒度:一份检验报告 → 可分析报告量、报告类型 明细粒度:报告 + 检验项目 → 可分析单项指标趋势 越往下越细,可上卷;越往上越粗,不可下钻 DWD 推荐落在“明细粒度”,下游按需聚合 清洗与标准化关键动作 编码标准化 性别/诊断/检验项目 时间标准化 统一格式与时区 金额标准化 统一为元,两位小数 空值异常处理 UNKNOWN / 隔离表 质量校验:主键唯一 · 外键可关联 · 空值率 · 时间先后合理 不通过 → 隔离表 + 原因记录,不静默丢弃

五、一个可落地的 DWD 建模检查清单

为便于实际执行,下面给出一份可直接对照使用的检查清单(示例,可按项目裁剪):

检查项判断标准常见问题
业务过程是否唯一一张事实表只描述一个过程挂号与收费混表
粒度是否明确能用一句话说清一行含义报告头与明细混存
维度外键是否可关联关联率 ≥ 99%(示例阈值)科室编码缺失
SCD 策略是否明确需历史口径的维度用 Type 2科室变更后历史归属错乱
标准化映射是否覆盖性别、诊断、检验项目有映射表同义异名未归一
质量校验是否执行主键、外键、空值、时间、金额异常数据静默丢弃

DWD 建模不是一次性动作,而是随业务过程新增、源系统变更、标准码升级持续演进的过程。建议把业务过程清单、粒度说明、映射表、校验规则都纳入版本管理,使每一次变更都可追溯、可回滚,这样 DWD 才能真正成为下游指标与标签体系可信赖的“一致性明细底座”。