时序数据模型
一条时序 Point 由 Measurement/Table、Tag Set、Field Set 和 Timestamp 构成。Tag 描述用于过滤或分组的维度,Field 保存被观测的数值或状态,Timestamp 定位发生时间。
weather,site=hf,room=101 temperature=26.3,humidity=61i 1787212800000000000
└表/测量 └────Tag Set────┘ └────────Field Set─────────┘ └Timestamp┘核心概念
| 概念 | 作用 | 设计重点 |
|---|---|---|
| Measurement / Table | 同类时序数据集合 | 不要按每台设备创建独立表 |
| Tag | 可索引或用于分组的维度 | 值集合应相对稳定并控制基数 |
| Field | 实际观测值 | 类型必须稳定,适合数值和状态 |
| Timestamp | 数据发生时间 | 明确精度、时区和迟到数据策略 |
| Series | Measurement 与 Tag Set 的唯一组合 | 1.x/2.x 中高基数尤其重要 |
这些概念的包含关系如下:
Database、Bucket 与 Retention Policy
最外层的数据容器随产品版本不同:
| 产品 | 数据容器 | 说明 |
|---|---|---|
| InfluxDB 1.x | Database + Retention Policy | Retention Policy 决定数据保留时间 |
| InfluxDB 2.x | Organization + Bucket | Bucket 组合了数据容器与 Retention 语义 |
| InfluxDB 3 | Database | 包含多个 Table,保留能力按具体产品配置 |
例如 iot Database 中可以包含 weather、power_usage 和 device_status。Database 主要用于数据隔离、权限和生命周期管理,不宜只因为站点不同就创建大量 Database。若合肥和上海的数据需要一起聚合,通常应将 site 设计成 Tag。
Table 与 Measurement
InfluxDB 1.x/2.x 使用 Measurement,InfluxDB 3 常称 Table,二者都表示同一类时序观测的集合:
weather 温度、湿度等环境观测
cpu CPU 使用率等主机指标
http_request 请求数量、延迟和状态码Table 应按观测类型划分,而不是按设备、日期或站点动态拆分:
# 不推荐
weather_hefei_room_101 temperature=26.3
weather_hefei_room_102 temperature=25.9
# 推荐
weather,site=hefei,room=101 temperature=26.3
weather,site=hefei,room=102 temperature=25.9同一 Table 的 Point 应具有相近含义和相对一致的 Schema。把 CPU、订单、日志正文和设备状态塞进一个 Table,会形成大量不相关或长期为空的列。
Point
Point 是某一时刻的一条完整观测:
Point = Table + Tag Set + Field Set + Timestamp一条 Point 可以包含同一次采样得到的多个 Field:
weather,site=hefei,room=101 temperature=26.3,humidity=61.5,battery=87i 1787212800000000000Point 不需要自增 ID。InfluxDB 3 中,有序 Tag Set 与 Timestamp 共同组成行的 Primary Key,Field 不参与 Point 身份。
Tag
Tag 描述“谁、哪里、哪一类”等数据来源和上下文:
site=hefei,room=101,device_type=temperature_sensorTag Value 是字符串。Tag 通常变化较慢,并经常出现在 WHERE、GROUP BY 或 JOIN 条件中。在 InfluxDB 3 中,Tag 还与 Timestamp 共同构成 Primary Key,并影响数据的物理排序。
Tag 不是普通关系数据库中的“索引开关”。把某列设计成 Tag,不仅影响过滤方式,还会改变 Point 身份、Series 组合和 Schema。
Field
Field 保存“测到了什么、值是多少”:
temperature=26.3,humidity=61.5,status="normal",online=true,retry_count=2i| 类型 | Line Protocol 示例 |
|---|---|
| Float | temperature=26.3 |
| Integer | retry_count=2i |
| Unsigned Integer | bytes=1024u |
| String | status="normal" |
| Boolean | online=true |
Point 至少要有一个 Field。同一 Field 的类型应保持稳定,不能先写 temperature=26.3,后写 temperature="unknown"。采集失败时可省略温度 Field,并写入 status="sensor_error",避免污染数值列类型。
Timestamp
Timestamp 应表达事件或采样实际发生的时间,而不是数据到达 InfluxDB 的时间。设备在 08:00 采样、08:03 恢复网络后补传时,仍应写入 08:00 的时间。
同一时刻用不同精度表示时,数值位数不同:
| 精度 | 2026-08-20T08:00:00Z |
|---|---|
| 秒 | 1787212800 |
| 毫秒 | 1787212800000 |
| 微秒 | 1787212800000000 |
| 纳秒 | 1787212800000000000 |
写入接口的精度参数必须与 Timestamp 匹配。省略 Timestamp 时,服务端使用接收写入时的当前时间。客户端还应处理设备时钟漂移、时区、乱序和迟到数据。
Series
传统 InfluxDB 1.x/2.x TSM 模型中:
Series Key = Measurement + 完整 Tag Set以下三个 Point 属于同一 Series,因为 Table 和 Tag Set 相同:
weather,site=hefei,room=101 temperature=26.3 1787212800000000000
weather,site=hefei,room=101 temperature=27.0 1787213100000000000
weather,site=hefei,room=101 temperature=27.5 1787213400000000000把 room 改成 102,就形成另一个身份组合。InfluxDB 3 更常从 Table、Tag Columns 和 Primary Key 理解数据,但“同一组稳定维度随时间形成序列”仍是重要的建模思路。
Cardinality
Series Cardinality 是不同 Series 身份的数量。若有 10 个站点、每站 100 个房间、每个房间 2 种传感器,实际组合全部存在时约有:
10 × 100 × 2 = 2,000 Series若再把几乎每条 Point 都不同的 Request ID 作为 Tag,Series 数量可能接近 Point 数量。InfluxDB 1.x/2.x 中这会显著增加索引和内存压力。InfluxDB 3 重新设计了高基数处理方式,但大量离散值、过宽 Primary Key、宽表和无边界查询仍有成本。
Schema-on-write
InfluxDB 可以根据第一次 Line Protocol 写入创建 Table 和列:
weather,site=hefei,room=101 temperature=26.3,online=true这次写入同时确定 site、room 是 Tag,temperature 是 Float Field,online 是 Boolean Field。后续写入必须遵守已形成的列角色和类型。
Schema-on-write 不表示没有 Schema,只是部分建表动作发生在写入阶段。生产环境仍应提前设计 Tag、Field、类型和核心查询,避免同名 Tag/Field、类型漂移、宽表和稀疏表。
Tag 与 Field
| 数据 | 更适合 Tag | 更适合 Field |
|---|---|---|
| 地区、机房、设备类型 | 是 | 通常否 |
| 温度、CPU 使用率、请求耗时 | 否 | 是 |
| Request ID、Trace ID | 通常否 | 可作为 Field,或放入专用日志/追踪系统 |
| 用户 ID | 取决于规模 | 高基数系统通常避免作为传统 Series Tag |
| 状态码 | 常用于分组时可作 Tag | 只作为观测值时可作 Field |
Tag 不是越多越好。把每次请求都不同的值写成 Tag,会使 Series 数量接近 Point 数量,在 TSM/TSI 产品线上造成显著索引和内存压力。InfluxDB 3 的基数约束机制有所变化,但无界字符串维度仍会影响 Schema、查询和存储成本。
时间与重复点
时间戳应表达事件发生时间,而不是数据库接收时间,除非业务明确只关心接收时刻。客户端时钟漂移、不同精度、重试写入和迟到事件都会影响窗口聚合。
同一个 Measurement/Table、完整 Tag Set 和 Timestamp 共同确定 Point 身份。InfluxDB 1.x/2.x TSM 中,重复 Point 的 Field Set 通常会合并,同名 Field 使用新值;InfluxDB 3 Core 不应依赖覆盖结果,查询或持久化可能出现任一版本。需要可靠维护最新状态时,应追加一个更晚 Timestamp 的 Point,再查询最新值。
Schema 设计示例
不推荐按设备拆 Measurement:
temperature_device_1001 value=26.3
temperature_device_1002 value=25.9更适合统一 Measurement 并用 Tag 表达维度:
temperature,device_id=1001,site=hf value=26.3
temperature,device_id=1002,site=hf value=25.9这样查询、保留策略和聚合逻辑可以围绕统一 Schema 工作。