4. 绩效数据采集与ETL工程

医院绩效分析平台的数据来源极其分散:HIS 产生收费与医嘱明细,电子病历系统保存病案首页与手术记录,LIS/PACS 输出检查检验工作量,HRP 或人事系统维护科室与人员编制,财务系统提供成本与收入科目。这些系统的数据库类型、编码规则、更新频率各不相同。ETL 工程的任务,就是把这些异构数据稳定、可追溯地汇聚成绩效指标可计算的统一数据底座。本节围绕抽取、清洗、转换、加载四个环节,以及增量/全量采集与调度机制展开。

一、抽取:先确定采集边界与抽取方式

抽取前必须明确三件事:抽取对象(哪些表、哪些字段)、抽取粒度(按明细还是按日汇总)、抽取时间窗口。绩效分析通常需要“最小可核算单元”,例如按人、按科室、按收费项目、按就诊流水号。以住院收入明细为例,抽取字段至少包括:就诊流水号、科室代码、收费项目代码、项目名称、数量、金额、计费时间、执行科室、开单医生。缺少执行科室,就无法把收入归属到实际执行单元。

抽取方式分为全量抽取与增量抽取。全量抽取每次读取源表全部数据,实现简单、结果确定,适合数据量小、无可靠时间戳或需要重建基线的场景,如科室字典、人员花名册、收费项目字典。增量抽取只读取上次抽取后发生变化的数据,依赖源系统的增量标识,常见有三类:时间戳字段(如 update_time)、自增主键(如 id)、数据库日志(如 CDC 捕获)。绩效平台中,收费明细、医嘱、检查检验记录数据量大且持续增长,应优先采用增量抽取。

增量抽取的关键是水位线(watermark)管理。每次抽取成功后记录本次最大时间戳或最大主键,下次从该水位线之后继续读取。为避免边界数据丢失,通常采用“左开右闭”或“闭区间回退若干秒”的策略。例如上次水位线为 2024-06-01 00:00:00,本次抽取条件写为 update_time > '2024-06-01 00:00:00' AND update_time <= '2024-06-02 00:00:00',并把水位线推进到 2024-06-02 00:00:00。若源系统存在延迟提交,可回退 5~10 分钟重抽,用主键去重保证幂等。

二、清洗:处理缺失、重复、异常与口径不一致

清洗解决“数据能不能用”的问题。绩效数据常见问题包括:科室代码为空或为历史废弃代码、收费项目名称为空、金额为负(退费)、同一笔业务重复推送、时间格式不统一。清洗规则应逐条可配置、可追溯,而不是写死在代码里。

典型清洗动作包括:

  • 空值处理:关键字段(就诊流水号、科室代码、金额)为空时进入异常表,不进入主流程;非关键字段用默认值或“未知”填充。
  • 去重:按业务主键(如就诊流水号+收费项目代码+计费时间)去重,保留最新一条。
  • 异常值过滤:金额绝对值超过阈值、数量为负且无对应退费标识的记录,标记为待核查。
  • 格式标准化:统一日期为 yyyy-MM-dd HH:mm:ss,统一科室代码为院内标准编码。

清洗不是一次性动作,而是每次加载前都执行的规则集。建议把清洗规则维护成一张规则表,字段包括规则编号、目标字段、规则类型、阈值、生效时间、是否阻断。这样当业务口径调整时,只需改规则,不必改代码。

三、转换:把业务数据映射为绩效可计算口径

转换是 ETL 中最具业务含量的环节。它把源系统的原始字段,映射为绩效指标计算所需的维度与度量。常见转换包括:

  • 维度关联:用科室代码关联科室维度表,补齐科室名称、科室类别(临床/医技/护理)、所属院区。
  • 指标派生:由收入明细汇总出“科室收入”“医生个人收入”;由医嘱明细统计“出院人次”“手术台次”。
  • 口径统一:把不同系统的收费项目代码映射到统一的绩效项目分类,如“检查”“检验”“治疗”“手术”“药品”“耗材”。
  • 单位换算:把金额统一为元,把数量统一为次/人/台。

转换结果应落到绩效事实表,典型结构为:日期、科室代码、人员代码、指标代码、指标值、数据来源、批次号。批次号用于追溯每次加载的数据版本,便于对账和回滚。

四、加载:幂等写入与分区管理

加载环节要保证“重复执行不产生重复数据”。常用做法有两种:一是按批次号先删除再插入(delete-insert),二是按业务主键做 upsert。绩效事实表通常按日期分区,加载时只覆盖目标日期分区,避免全表重写。加载完成后记录加载日志:批次号、开始时间、结束时间、抽取行数、清洗通过行数、异常行数、加载行数、状态。任何一行异常都应可定位到源记录。

五、增量与全量采集的调度机制

调度机制决定数据什么时候到、以什么顺序到。绩效平台通常采用“日批 + 小时增量”的组合:字典类数据每日全量刷新一次;收费、医嘱、检查检验等事实数据每小时增量抽取一次;每日凌晨执行一次全量对账,校验当日增量累计与源系统日汇总是否一致。

调度依赖必须显式声明:维度表加载完成 → 事实表抽取 → 清洗 → 转换 → 加载 → 指标计算。任一环节失败,下游不应继续。调度工具可用 Airflow、DolphinScheduler 或数据库作业,核心是任务依赖、重试策略、失败告警和补数能力。补数时指定日期区间,系统按批次重新执行抽取到加载的全链路,并覆盖对应分区。

绩效数据 ETL 采集链路与调度依赖 源系统 HIS 收费明细 电子病历/病案 LIS / PACS HRP / 人事 / 财务 抽取 Extract 全量:字典/人员 增量:时间戳/主键 水位线 watermark 回退窗口去重 清洗 Clean 空值/异常入异常表 业务主键去重 格式/编码标准化 规则表可配置 转换 Transform 维度关联科室/人员 项目分类映射 指标派生汇总 单位统一为元/次 加载 Load:按日期分区 + 批次号幂等写入 delete-insert / upsert 绩效事实表(分区) 加载日志/批次追溯 调度机制 字典:每日全量 事实:每小时增量 凌晨全量对账 失败重试 + 补数 调度依赖顺序 维度表加载 → 事实抽取 → 清洗 → 转换 → 加载 → 指标计算 任一环节失败,下游阻断;补数按日期区间重跑并覆盖对应分区

六、一个可落地的批次日志与对账示例

为了让采集过程可核查,建议每次调度都写入一张批次日志表。以下为示例结构(字段与取值均为教学示例,非实测数据):

批次号: BATCH_20240602_0300
抽取范围: 2024-06-01 00:00:00 ~ 2024-06-02 00:00:00
抽取行数: 128430
清洗通过: 127905
异常行数: 525
加载行数: 127905
状态: SUCCESS
异常原因分布: 科室代码为空 312 / 金额异常 98 / 重复主键 115

对账时,把加载后的当日收入合计与 HIS 日结报表收入合计比对。若差异超过预设阈值(例如 0.5%),则触发告警并暂停指标计算,先定位是抽取遗漏、清洗误杀还是转换映射错误。差异定位可从异常表、批次日志和源系统日结三处交叉核对。

增量抽取的水位线必须持久化保存,不能只放在内存或临时变量中。调度重跑时,水位线应支持手动指定,以便补数。
清洗规则中的“阻断”与“放行”要区分清楚:关键字段缺失应阻断并进入异常表,非关键字段缺失可放行但打标。若把阻断规则设得过宽,会导致大量正常数据被拦截;设得过窄,则脏数据进入指标计算,造成绩效结果失真。

综上,绩效数据采集与 ETL 工程的核心不是“把数据搬过来”,而是建立一条可配置、可追溯、可重跑的采集链路:抽取阶段明确全量与增量的边界,清洗阶段用规则表处理缺失与异常,转换阶段完成业务口径映射,加载阶段保证幂等与分区覆盖,调度阶段用依赖、重试和补数机制保障稳定性。只有这条链路可靠,后续的绩效指标计算与分析才有可信的数据基础。