4. 平台数据存储架构
数字健康管理平台的数据形态差异极大:用户档案、设备绑定关系、订单与权限是典型的事务型数据;心率、血压、血糖、睡眠分期、步数等是高频写入、按时间窗口聚合的时序数据;影像报告、PDF 体检单、DICOM、音频与可穿戴原始包是体量大、一次写入多次读取的非结构化对象;而跨机构的人群健康分析、慢病风险建模、运营指标看板,则需要面向分析的数据湖与数据仓库。存储架构的核心任务不是“选一个最好的数据库”,而是让每类数据落到最合适的存储引擎,并通过清晰的数据流把它们串起来。
一、五类存储的定位与关键参数
关系型数据库(如 PostgreSQL、MySQL)承担强一致事务:用户注册、设备绑定、家庭成员关系、订单、授权同意书、告警规则配置。它擅长多表关联、唯一约束、外键与事务回滚。选型时重点看:单表数据量是否超过千万级、写入 QPS 是否超过 5000、是否需要跨行事务。健康平台中,用户与设备元数据通常控制在百万级,关系库完全够用;但若把每秒数万点的体征数据也塞进关系库,索引维护和写入放大将迅速拖垮实例。
时序数据库(如 InfluxDB、TimescaleDB、TDengine)面向“时间戳 + 指标 + 标签”模型。以心率为例,一条记录可表示为 measurement=heart_rate, tags={device_id, user_id}, fields={bpm=78}, time=2025-03-01T08:00:00Z。它的关键能力是时间范围扫描、降采样、连续查询与高压缩比。典型参数:单设备采样间隔 1s~60s,保留原始精度 7~30 天,之后按 1min/5min 聚合长期保存。时序库的标签基数(tag cardinality)是常见陷阱:把 session_id 或毫秒时间戳作为标签,会导致索引爆炸,应改为字段或直接不入标签。
对象存储(如 S3、MinIO、OSS)保存不可变的大文件:体检 PDF、DICOM 影像、睡眠报告截图、设备固件、导出包。它按对象键寻址,适合冷热分层与生命周期策略。例如:health-report/{tenant}/{yyyy}/{MM}/{user_id}/{report_id}.pdf。对象存储不提供复杂查询,因此必须在关系库或元数据表中保存对象键、大小、校验和、内容类型与业务归属,形成“元数据在库、内容在对象存储”的组合。
数据湖(如 Hudi、Iceberg、Delta Lake on S3)保存原始与半清洗数据,支持 Schema 演进、时间旅行与批量回填。它接收来自 CDC、日志、设备网关的原始事件,保留最细粒度事实,供算法团队探索。数据仓库(如 ClickHouse、Doris、Snowflake、BigQuery)则保存建模后的宽表与指标层,面向 BI 查询和固定报表,强调列式压缩、向量化执行与预聚合。
二、组合策略:不是五选一,而是分层协作
真实平台通常采用“关系库 + 时序库 + 对象存储 + 湖仓”四层组合。以一次血压测量为例:设备网关收到 {user_id: U10086, device_id: BP-0231, systolic: 132, diastolic: 85, ts: 1740787200} 后,时序库写入原始点;关系库更新该设备最近上报时间与在线状态;若用户同时上传了体检报告 PDF,则 PDF 写入对象存储,关系库仅记录 report_id 与 object_key;夜间批处理将时序库按小时聚合,写入数据湖 ODS 层,再经 DWD 清洗、DWS 汇总,最终在数据仓库生成“用户日血压均值”宽表,供看板查询。
这种分工的关键判断依据是访问模式:按主键/外键做点查与事务 → 关系库;按时间范围做聚合与降采样 → 时序库;按对象键做整文件读写 → 对象存储;按分区做批量扫描与 Schema 演进 → 数据湖;按维度做多表关联与指标查询 → 数据仓库。把访问模式与存储能力对齐,比单纯比较产品参数更有效。
三、选型决策表与示例参数
下表给出一份可直接用于评审的选型决策表,参数为教学示例,实际项目需按压测结果调整。
| 数据类型 | 推荐存储 | 写入特征 | 查询特征 | 保留策略(示例) |
|---|---|---|---|---|
| 用户档案、设备绑定 | 关系型数据库 | 低频,事务写入 | 主键点查、多表关联 | 长期保留,软删除 |
| 心率、血压、血糖 | 时序数据库 | 高频,批量写入 | 时间范围聚合、降采样 | 原始 30 天,1min 聚合 2 年 |
| 体检 PDF、DICOM | 对象存储 | 一次写入,极少修改 | 按 object_key 读取 | 热 90 天,冷归档 5 年 |
| 设备原始包、日志 | 数据湖 | 批量/流式追加 | 全量扫描、回填 | ODS 保留 1 年,DWD 3 年 |
| 日/周健康指标宽表 | 数据仓库 | 批处理写入 | 多维聚合、BI 查询 | 按分区滚动保留 3 年 |
四、落地时的三个常见陷阱
陷阱一:时序库标签基数失控。把 user_id 作为标签尚可接受(百万级),但把 session_id、trace_id 或毫秒时间戳作为标签,会生成海量时间线,导致内存与索引膨胀。正确做法是:标签只保留设备型号、机构、指标类型等低基数字段,高基数字段放入 field 或写入数据湖。
陷阱二:对象存储当数据库用。对象存储不支持按业务字段检索,若把用户 ID、报告类型只写在文件名里,后续按“某用户所有异常报告”查询将非常困难。必须在关系库或元数据表中维护 object_key、user_id、report_type、created_at、checksum 等字段,形成可检索的元数据索引。
陷阱三:湖仓边界模糊导致重复建设。数据湖负责“存全、存原始、可回放”,数据仓库负责“算好、算快、可复用”。若把 BI 查询直接压到数据湖原始层,会因小文件过多和缺少统计信息而变慢;若把原始事件只存仓库,又会因 Schema 固化而无法回填。建议明确:ODS 层只追加不修改,DWD 层做清洗与标准化,DWS 层做轻度汇总,ADS 层面向具体应用。
综上,数字健康平台的存储架构应以访问模式为第一判断依据,以关系库保障事务、时序库承载高频指标、对象存储容纳大文件、数据湖保留原始事实、数据仓库输出分析价值。五者通过元数据关联与分层数据流协同工作,才能支撑从单用户健康档案到群体健康分析的完整链路。