3. 实验室时序数据模型与存储选型
实验室时序数据平台的核心问题,不是“把数据存进去”,而是“用正确的模型描述数据,再选一个能长期稳定承载它的存储引擎”。如果模型设计错了,后面无论换多贵的数据库,查询都会越来越慢、标签越来越乱、磁盘越来越贵。本节围绕三件事展开:时序数据模型怎么建、标签与字段怎么分、关系型数据库与 InfluxDB、TimescaleDB、TDengine 等时序数据库如何选型。
一、时序数据模型:measurement、tag、field、timestamp
实验室时序数据最典型的四元结构是:measurement(测量/表名)、tag(标签,索引维度)、field(字段,实际数值)、timestamp(时间戳)。以一台环境试验箱为例,采集点每 10 秒上报一次温度、湿度、设定值、运行状态,可以写成:
measurement: env_chamber
tags: device_id=CH-01, lab=LAB-A, sensor=TH-01
fields: temp=23.6, humidity=45.2, setpoint=23.0, run_state=1
timestamp: 2025-03-11T09:30:00+08:00
这里的关键判断是:tag 是“谁/在哪/属于什么”这类低基数、用于过滤和分组的字符串维度;field 是“测到了多少”这类随时间变化、需要做聚合和计算的数值或状态量。device_id、lab、sensor 适合做 tag,因为查询常按设备、实验室、传感器筛选;temp、humidity 适合做 field,因为要对它们求平均、最大、最小、积分。run_state 虽然看起来像状态,但它是随时间变化的量,通常放 field;如果它被频繁用于过滤“只查运行中的设备”,也可以考虑单独建一个状态 measurement,而不是硬塞进 tag。
时间戳必须统一时区与精度。实验室常见做法是:采集端统一用 UTC 存储,展示层按本地时区转换;精度按采样周期决定,10 秒采样用秒级或毫秒级均可,但同一平台内应保持一致,避免同一 measurement 里混用秒和毫秒导致排序错乱。
二、标签与字段设计:基数、粒度与命名
标签设计的最大陷阱是高基数。如果把每次实验的 run_id、样品编号、操作员姓名都做成 tag,标签组合数会爆炸,索引膨胀,写入和查询都会退化。合理的做法是:把真正用于“筛选和分组”的维度做成 tag,把“每次实验不同、数量巨大”的标识放到 field 或单独的关系表中,通过外键关联。
命名要统一。建议采用小写加下划线,measurement 用“对象_指标”或“对象”命名,tag key 用 device_id、lab、sensor、unit 这类稳定语义,field key 用 temp、humidity、pressure、voltage 这类物理量名。单位不要混进 field 名,例如不要写 temp_c 和 temp_f 两个字段,而应统一用 temp,单位在元数据或 tag 中声明。
下面这张图给出一个实验室时序数据模型的典型结构:左侧是采集对象,中间是 measurement 的 tag/field 划分,右侧是写入存储后的查询视角。
三、关系型数据库 vs 时序数据库
很多实验室最初用 MySQL 或 PostgreSQL 存时序数据,单表按时间建索引,短期可用,但数据量到亿级后会出现写入瓶颈、索引膨胀、聚合查询慢、压缩率低等问题。关系型数据库的优势是事务、关联查询、生态成熟,适合存元数据、实验记录、设备台账、报警配置;时序数据库的优势是高写入吞吐、按时间分区、列式压缩、内置降采样和保留策略,适合存高频采集值。
| 对比维度 | 关系型数据库(MySQL/PostgreSQL) | 时序数据库(InfluxDB/TimescaleDB/TDengine) |
|---|---|---|
| 数据模型 | 行式表,强 Schema | 时间线模型,tag/field 分离 |
| 写入吞吐 | 万级/秒,受索引影响 | 十万级~百万级/秒 |
| 压缩率 | 低,原始行存储 | 高,列式+时间戳压缩 |
| 聚合查询 | 需手写 SQL 和索引优化 | 内置 time_bucket、降采样、连续聚合 |
| 保留策略 | 需自行分区和清理 | 原生 retention policy / TTL |
| 事务与关联 | 强,适合元数据 | 弱,不适合复杂关联 |
实际工程中,常见架构是“关系型 + 时序型”混合:PostgreSQL 存设备台账、实验批次、用户权限、报警规则;时序数据库存采集值。两者通过 device_id、run_id 关联,查询时先查元数据拿到维度,再查时序库拿数值。
四、InfluxDB、TimescaleDB、TDengine 选型要点
InfluxDB 是专用时序数据库,tag/field 模型清晰,Flux/InfluxQL 查询语言成熟,适合快速搭建、写入量大、以监控和指标为主的场景。它的短板是集群版商业授权、复杂关联弱、标签基数敏感。实验室若以设备监控、环境数据采集为主,InfluxDB 上手快。
TimescaleDB 是 PostgreSQL 扩展,本质仍是 PostgreSQL,优势是 SQL 完整、事务和关联强、生态成熟,通过 hypertable 自动按时间分区,支持 continuous aggregate 连续聚合。适合已有 PostgreSQL 团队、需要同时做元数据关联和时序分析的实验室。它的写入性能不如专用时序库,但胜在“一个数据库解决大部分问题”。
TDengine 是国产时序数据库,采用“一个设备一张表”的模型,超级表 + 子表设计,写入和压缩性能突出,自带缓存、流计算和降采样,适合设备数量多、采集频率高、国产化要求强的场景。它的 SQL 方言与标准 SQL 有差异,生态和工具链相对前两者略窄,选型时需评估团队熟悉度。
综合来看,选型可以按以下顺序判断:如果团队强依赖 SQL 和事务、需要频繁关联元数据,优先 TimescaleDB;如果追求开箱即用、监控指标为主、写入量大,优先 InfluxDB;如果设备数量极大、国产化要求高、能接受专用 SQL 方言,优先 TDengine。无论选哪个,模型设计先行:先确定 measurement、tag、field、timestamp,再决定存储引擎,才能让平台在数据量增长后仍然可查、可扩、可维护。