
IoT 平台的存储选型核心问题是:数据将以什么模式被查询------按设备取最近趋势、跨设备时段聚合,还是分析时多序列对齐。不同答案对应不同的数据库。
DC3 的时序层做成与消息总线同构的可插拔家族:dc3-tsdb-core 定义端口,四个适配器各自对接一款时序数据库,由配置项 dc3.tsdb.type 选择,同时只激活一个:
- TimescaleDB(默认):PostgreSQL 生态内嵌,与平台主库同源,运维成本最低,支持连续聚合做分级 rollup;
- TDengine:国产开源,"一个采集点一张表"的超级表模型,压缩比与写入吞吐是强项;
- InfluxDB(3.x):时序领域的老牌选手,v3 HTTP API 直连,零客户端依赖;
- IoTDB(2.x):国产开源(Apache 顶级项目),树形路径模型与工业场景天然契合。
能力矩阵:按实际声明发布,非预估

选型文档里最值得看的是一张能力矩阵(docs/tsdb-stores.md),它的每个格子都来自适配器的实际能力声明,不是营销口径:
- 分桶聚合:四库全支持(time_bucket / INTERVAL / date_bin / 窗口分组);
- 精确分位数(PERCENTILE):Timescale 与 TDengine 支持,InfluxDB 与 IoTDB 无此函数;
- 按驱动分组统计:IoTDB 因为路径模型的差异,如实声明为不支持;
- rollup 分级聚合:仅 TimescaleDB 提供原生支持(共享连续聚合),其余三库为原始扫描。
这些"不支持"是显式契约的一部分,原因见下文。
24 例 TCK 与"绝不给错数据"
四款适配器都要通过同一套 24 例库中立契约套件(dc3-tsdb-tck)。数据库不支持的能力,适配器如实声明为 false,契约套件按能力门控跳过对应用例,而数据中心门面对这些能力做降级处理:延迟直方图返回零桶、精确分位数与相关系数由门面从有界拉取的数据中自算。
一句话概括这套机制的价值取向:宁可少给能力,绝不给错数据。 存储抽象的主要风险是"抽象层隐式改变语义",TCK 与能力声明的组合将其转化为显式契约。

换型三步走
- 起目标存储:
make up STACK=optional SERVICES="tdengine"(或 influxdb / iotdb),IoTDB 首启自动挂载微秒精度配置; - 改环境变量
DC3_TSDB_TYPE=tdengine,按需覆盖连接参数; - Maven 侧把所选适配器加入数据中心依赖(默认只打包 TimescaleDB)。
与 MQ 家族同一个约定:默认适配器随服务打包,其余按需引入------没人应该为不用的存储付出 jar 体积与启动开销。
实事求是的边界
- 空桶补零四库均不支持,由消费端补零------这是有意的语义统一;
- TDengine / IoTDB 适配已通过契约验证,生产规模的容量规划仍需按实际数据量测试;
- 矩阵中的能力以适配器声明为准,会随版本演进更新,以 docs/tsdb-stores.md 为准。
仓库 :GitHub
pnoker/iot-dc3· Giteepnoker/iot-dc3(GVP)文档:docs.dc3.site · 时序选型 docs/tsdb-stores.md · book.dc3.site · demo.dc3.site