InfluxDB 模式设计建议
使用以下指南来设计您的 schema,以实现更简单、更高效的查询。
InfluxDB 数据结构
InfluxDB 3 Core 数据模型将时间序列数据组织到数据库和表中。一个数据库可以包含多个表。表包含多个标签和字段。
数据库:存储时间序列数据的命名位置。在 InfluxDB 3 Core 中,database(数据库)与 InfluxDB Cloud Serverless 和 InfluxDB TSM 实现中的 bucket(存储桶)同义。
一个数据库可以包含多个表。
- 表:时间序列数据的逻辑分组。在 InfluxDB 3 Core 中,table(表)与 InfluxDB Cloud Serverless 和 InfluxDB TSM 实现中的 measurement(测量值)同义。给定表中的所有点应具有相同的标签。一个表包含多个标签和字段。
- 标签:键值对,用于存储每个点的元数据字符串值——例如,标识或区分数据源或上下文的值——例如,主机、位置、站点等。标签值可以为 null。
- 字段:键值对,用于存储每个点的数据——例如,温度、压力、股票价格等。字段值可以为 null,但在任何给定行中,至少有一个字段值不是 null。
- 时间戳:与数据关联的时间戳。在磁盘存储和查询时,所有数据都按时间排序。在 InfluxDB 中,时间戳是 UTC 下的纳秒级 Unix 时间戳。时间戳绝不会为 null。
- 表:时间序列数据的逻辑分组。在 InfluxDB 3 Core 中,table(表)与 InfluxDB Cloud Serverless 和 InfluxDB TSM 实现中的 measurement(测量值)同义。给定表中的所有点应具有相同的标签。一个表包含多个标签和字段。
Buckets 和 Measurements 去哪儿了?
如果您来自早期版本的 InfluxDB、InfluxDB Cloud (TSM) 或 InfluxDB Cloud Serverless,您可能熟悉 bucket 和 measurement 的概念。
- InfluxDB v2 或 InfluxDB Cloud Serverless 中的Bucket与 InfluxDB 3 Core 中的database同义。
- InfluxDB v1、v2 或 InfluxDB Cloud Serverless 中的Measurement与 InfluxDB 3 Core 中的table同义。
主键
在时间序列数据中,一行数据的**主键**通常是时间戳和其他属性的组合,这些属性唯一标识每个数据点。在 InfluxDB 3 Core 中,一行数据的**主键**是该点的时间戳和标签集的组合——即该点上标签键和标签值的集合。行的主键标签集不包括值为 null 的标签。
标签 (Tags) 与字段 (Fields) 的区别
在为 InfluxDB 设计 Schema 时,一个常见问题是:“什么应该是标签,什么应该是字段?” 以下指南应有助于您在设计 Schema 时回答这个问题。
- 使用标签存储数据的来源或上下文的元数据或标识信息。
- 使用字段存储测量值。
- 标签值只能是字符串。
- 字段值可以是以下任何数据类型:
- 整数
- 无符号整数
- 浮点数
- 字符串
- 布尔值
InfluxDB 3 存储引擎支持无限的标签值和序列基数。与早期版本的 InfluxDB 不同,**标签值**的基数不会影响数据库的整体性能。
Schema 限制
不要为标签和字段使用重复的名称
在同一个表中,为标签和字段使用唯一的名称。InfluxDB 3 Core 将标签和字段存储为表中的唯一列。如果您尝试写入包含同名标签或字段的表,写入将因列冲突而失败。
每个表的列最大数量
一个表有最大列数。每行必须包含一个时间列。因此,一个表可以包含以下内容:
- 一个时间列
- 最多配置最大数量的字段和标签列
如果您尝试写入一个表并超出列限制,则写入请求将失败,InfluxDB 将返回错误。
InfluxData 将列限制确定为维持系统性能和稳定性的安全限制。超出此阈值可能会导致宽泛的 Schema,这会因您的查询、Schema 的形状以及 Schema 中的数据类型而对性能和资源使用产生负面影响。
为性能而设计
您在表内如何组织 Schema 会影响资源使用和该表的查询性能。
以下指南有助于优化查询性能:
按查询优先级排序标签
InfluxDB 3 Core 中对表进行的第一次写入决定了存储中的物理列顺序,而该顺序直接影响查询性能。在查询执行期间,较早出现的列通常在过滤和访问时更快。
在对表进行初始写入时,按查询优先级对标签进行排序。将最常查询的标签放在前面——您经常在 WHERE 子句或 join 中使用的标签——其次是查询频率较低的标签。例如,如果您的绝大多数查询都按 region 过滤,然后按 host 过滤,请按 region 在 host 之前的顺序组织您的第一次写入。
列顺序在第一次写入时确定,之后无法更改。第一次写入后添加的标签会排在列排序顺序的最后。请在设计 Schema 时考虑您的查询工作负载,以确保最佳的长期性能。
避免宽泛的 Schema
宽泛的 Schema 指的是具有大量列(标签和字段)的 Schema。
宽泛的 Schema 可能导致以下问题:
- 在摄取期间持久化数据时,资源使用量增加。
- 由于具有过多标签的复杂主键,排序性能下降。
- 选择过多列时,查询性能下降。
为防止宽泛 Schema 问题,请限制表中存储的标签和字段的数量。如果您需要存储的数量超过最大列数,请考虑将您的字段分割到单独的表中。
避免过多标签
在 InfluxDB 3 Core 中,一行数据的**主键**是该点的时间戳和标签集的组合——即该点上标签键和标签值的集合。包含更多标签的点具有更复杂的主键,如果您使用键的所有部分进行排序,这可能会影响排序性能。
避免稀疏的 Schema
稀疏的 Schema 是指许多行的列包含 null 值。
这些通常源于以下原因:
稀疏的 Schema 要求 InfluxDB 查询引擎评估许多 null 列,为存储和查询数据增加了不必要的开销。
有关稀疏 Schema 的示例,请查看下面的非同质 Schema 示例。
以不同时间写入单个字段
以不同时间报告字段,并使用不同的时间戳,会创建包含 null 值的独立行——例如:
您使用 tagset 报告 fieldA,然后使用相同的 tagset 报告 field B,但时间戳不同。结果是两行:一行中 field A 的值为 null,另一行中 field B 的值为 null。
相反,如果您在不同时间报告字段,同时使用相同的 tagset 和时间戳,则现有行将被更新。这在摄取时需要更多资源,但在持久化或合并时会得到解决,并避免了稀疏 Schema。
表 Schema 应保持同质性
存储在表中的数据应该是“同质的”,这意味着每一行都应该具有相同的标签和字段键。存储在表中的所有行共享相同的列,但如果一个点不包含某个列的值,则该列的值为null。充满null值的表具有“稀疏” Schema。
为数据使用最佳数据类型
在写入字段数据时,请为您的数据使用最合适数据类型——将整数写为整数,小数写为浮点数,布尔值写为布尔值。查询存储整数的字段比查询字符串数据性能更好;查询许多长字符串值会严重影响性能。
为查询简洁性而设计
表名、标签键和字段键的命名约定可以简化或复杂化您为数据编写查询的过程。以下指南有助于确保为数据编写查询尽可能简单。
保持表名、标签和字段的简洁
为每个数据属性使用一个标签或一个字段。如果您的源数据在一个参数中包含多个数据属性,请将每个属性拆分为其自己的标签或字段。
表名、标签键和字段键应简洁并准确描述它们包含的内容。保持名称的纯粹性。命名约定复杂的最常见原因是您尝试将数据属性“嵌入”到表名、标签键或字段键中。
当每个键值代表您数据的一个属性(而不是多个串联的属性)时,您将减少在查询中对正则表达式的需求。没有正则表达式,您的查询将更容易编写,性能也更好。
不推荐
例如,考虑以下行协议,它将多个属性(位置、型号和 ID)嵌入到 sensor 标签值中:
home,sensor=loc-kitchen.model-A612.id-1726ZA temp=72.1
home,sensor=loc-bath.model-A612.id-2635YB temp=71.8要查询 ID 为 1726ZA 的传感器的数据,您必须使用 SQL 模式匹配或正则表达式来评估 sensor 标签。
SELECT * FROM home WHERE sensor LIKE '%id-1726ZA%'SELECT * FROM home WHERE sensor =~ /id-1726ZA/SQL 模式匹配和正则表达式都使查询复杂化,并且性能不如简单的相等表达式。
推荐
更好的方法是将每个传感器属性作为单独的标签写入:
home,location=kitchen,sensor_model=A612,sensor_id=1726ZA temp=72.1
home,location=bath,sensor_model=A612,sensor_id=2635YB temp=71.8要使用此 Schema 查询 ID 为 1726ZA 的传感器的数据,您可以使用简单的相等表达式:
SELECT * FROM home WHERE sensor_id = '1726ZA'此查询比使用模式匹配或正则表达式更容易编写且性能更好。
避免使用关键字和特殊字符
为了简化查询编写,请避免在表名、标签键和字段键中使用保留关键字或特殊字符。
在使用 SQL 或 InfluxQL 查询带有特殊字符或关键字的表、标签和字段时,您必须将这些标识符用**双引号**括起来。
SELECT
"example-field", "tag@1-23"
FROM
"example-table"
WHERE
"tag@1-23" = 'ABC'此页面是否有帮助?
感谢您的反馈!
支持和反馈
感谢您成为我们社区的一员!我们欢迎并鼓励您对 InfluxDB 3 Core 和本文档提供反馈和错误报告。要获得支持,请使用以下资源
具有年度合同或支持合同的客户可以 联系 InfluxData 支持。