3. 数据整合工程总体架构

药物重定位的数据整合工程,本质上要解决一个矛盾:数据来源极度异构(化学结构、靶点互作、电子病历、文献、专利、不良反应报告),而下游的假设生成与验证又要求数据在语义上高度一致、可追溯、可复现。如果直接把各来源数据“拉平”成一张大表,短期看似方便,长期必然在字段冲突、版本漂移和血缘丢失上付出代价。因此,总体架构的第一原则是分层解耦:让每一层只承担一类职责,层与层之间通过稳定的契约交互。

分层设计:从原始落地到可服务

一个可落地的分层方案通常包含五层。最底层是数据源层,保留原始文件或API响应,不做任何清洗,目的是可回溯。其上是原始落地层(Raw/Bronze),按来源与批次原样存储,例如把ChEMBL的活性数据、DrugBank的靶点关系、PubMed的摘要分别落到对象存储或数据湖表中,并记录抓取时间、来源版本、校验和。第三层是标准化层(Silver),完成实体归一、单位统一、字段映射与去重,输出“干净但仍是分领域”的表。第四层是整合层(Gold),把药物、靶点、疾病、通路、不良反应等实体通过统一标识(如InChIKey、UniProt AC、MONDO ID、MedDRA编码)连接成知识图谱或宽表。最上层是服务层,对外提供查询API、特征视图、训练样本集和可复现的数据快照。

分层的价值在于:当某个上游来源更新时,只需重跑该来源对应的Raw→Silver→Gold链路,而不必推翻整个系统。同时,每一层都可以独立做质量校验,问题定位从“整条链路”缩小到“某一层某一来源”。

分层架构(自下而上) 数据源层 ChEMBL · DrugBank · PubMed · CT.gov · FAERS · 专利 只读接入,不修改原始语义 原始落地层 Raw / Bronze 按来源+批次原样存储,记录版本、抓取时间、校验和 对象存储 / 数据湖表,不可变追加 标准化层 Silver 实体归一 · 单位统一 · 字段映射 · 去重 · 质量标记 InChIKey / UniProt AC / MONDO / MedDRA 整合层 Gold 药物–靶点–疾病–通路–不良反应 关联图谱 / 宽表 统一主键 + 证据溯源字段 服务层 查询API · 特征视图 · 训练样本集 · 可复现快照 面向建模与验证,不直接暴露原始表 横向模块划分 采集与调度模块 增量抓取 · 限流重试 · 批次元数据登记 标准化与实体解析模块 名称→标识映射 · 冲突裁决 · 人工复核队列 整合与图谱构建模块 关系合并 · 证据加权 · 版本化快照 质量与血缘模块 完整性/一致性校验 · 字段级血缘 · 异常告警 服务与发布模块 API网关 · 特征物化 · 快照发布与回滚 技术选型要点 存储:对象存储 + 列式湖表 + 图数据库 计算:批处理为主,实体解析可并行化 扩展:新增来源只加适配器,不改核心Schema 关键契约:每层输出必须带 source_id、source_version、ingest_time、record_hash; Gold层每条关系必须可回溯到至少一条Silver记录,否则视为血缘断裂。

模块划分:按职责而非按数据源切分

很多团队习惯“一个数据源一个模块”,这在来源少时可行,但来源增加到十几个后,重复的清洗逻辑会迅速膨胀。更稳妥的做法是按职责划分模块:采集与调度负责增量抓取、限流重试和批次元数据登记;标准化与实体解析负责把“阿司匹林”“Aspirin”“乙酰水杨酸”映射到同一InChIKey,并处理冲突;整合与图谱构建负责关系合并、证据加权和版本化快照;质量与血缘负责完整性、一致性校验和字段级追踪;服务与发布负责API、特征物化和快照回滚。每个模块通过明确的输入输出契约交互,新增数据源时只需增加一个适配器,而不是修改核心Schema。

技术选型:以可复现为约束

技术选型不应追求“最新”,而应围绕三个约束:可复现、可扩展、可审计。存储上,原始层用对象存储(如S3兼容接口)保存不可变文件,标准化层和整合层用列式格式(Parquet)加湖表(Iceberg/Hudi/Delta)管理版本;图关系如果查询频繁,可同步到图数据库,但图数据库应视为Gold层的物化视图,而非唯一真相源。计算上,批处理足以覆盖大多数场景,实体解析中的相似度计算可以并行化。调度可用Airflow或Dagster,关键是每次运行都产出带版本号的快照,而不是覆盖旧数据。

一个常见的误区是把“数据量不大”当作跳过版本管理的理由。药物重定位的结论往往需要回溯到具体某次数据快照,如果Gold层被原地覆盖,后续验证就无法复现。因此,即使数据只有几GB,也建议保留Raw和Silver的批次版本。

可扩展性:新增来源与新增关系的代价

可扩展性可以用两个问题来检验:新增一个数据源需要改几处?新增一种实体关系需要改几处?理想情况下,新增来源只涉及“适配器+映射配置+质量规则”三处,核心整合逻辑不变;新增关系类型只需在Gold层注册关系Schema和证据权重规则,不影响已有链路。为达到这一点,标准化层应输出统一的中间表示,例如所有活性记录都归一到“药物标识、靶点标识、活性值、单位、实验条件、来源”这组字段,整合层再基于这组字段做跨源合并。

判断架构是否过度设计的一个实用标准:如果当前只有3个数据源、且半年内不会增加,那么把Raw和Silver合并、用脚本直接生成Gold是可以接受的;但一旦来源超过5个或需要对外发布数据版本,就应回到分层方案。

一个可参考的落地顺序

实际搭建时,不建议一次性把五层全部建完。更务实的顺序是:先选2~3个核心来源(例如ChEMBL的活性数据、DrugBank的靶点关系、MONDO的疾病本体),打通Raw→Silver→Gold的最小链路,确保实体归一和血缘字段可用;再接入服务层,用一个简单API验证下游能否消费;最后逐步增加来源和质量规则。每增加一个来源,都回头检查标准化层的字段映射是否仍然成立,必要时做向后兼容的Schema演进。

架构的最终目标不是“层数多”,而是让数据从原始来源到可服务状态的过程可解释、可重跑、可回滚。只要这三条成立,分层和模块划分就是有效的;反之,即使画出了漂亮的架构图,也无法支撑药物重定位中反复迭代的假设验证。