InfluxDB 模式设计建议
使用以下指南来设计您的 模式,以实现更简单和更高效的查询。
InfluxDB 数据结构
InfluxDB 集群数据模型将时间序列数据组织到数据库和表中。一个数据库可以包含多个表。表包含多个标签和字段。
数据库:存储时间序列数据的命名位置。在 InfluxDB 集群中,数据库与 InfluxDB 云无服务器和 InfluxDB TSM 实现中的桶同义。
一个数据库可以包含多个 表。
- 表:时间序列数据的逻辑分组。在 InfluxDB 集群中,表与 InfluxDB 云无服务器和 InfluxDB TSM 实现中的度量同义。给定表中所有的点应该有相同的标签。表包含多个标签和字段。
- 标签:键值对,用于存储每个点的元数据字符串值,例如,用于标识或区分数据源或上下文的值——例如,主机、位置、站点等。标签值可能为空。
- 字段:键值对,用于存储每个点的数据,例如,温度、压力、股票价格等。字段值可能为空,但在任何给定的行上至少有一个字段值不为空。
- 时间戳:与数据相关联的时间戳。当存储在磁盘上并被查询时,所有数据都按时间顺序排列。在InfluxDB中,时间戳是一个以纳秒为单位的Unix时间戳,使用UTC。时间戳永远不会为null。
- 表:时间序列数据的逻辑分组。在 InfluxDB 集群中,表与 InfluxDB 云无服务器和 InfluxDB TSM 实现中的度量同义。给定表中所有的点应该有相同的标签。表包含多个标签和字段。
桶和度量标准发生了什么变化?
如果您来自InfluxDB Cloud Serverless或由TSM存储引擎驱动的InfluxDB,您可能熟悉桶和度量标准这两个概念。在TSM或InfluxDB Cloud Serverless中,桶等同于InfluxDB Clustered中的数据库。在TSM或InfluxDB Cloud Serverless中,度量标准等同于InfluxDB Clustered中的表。
主键
在时间序列数据中,一行数据的键通常是时间戳和其他唯一标识每个数据点的属性的组合。在InfluxDB中,行的主要键是点的时间戳和标签集——点的标签键和标签值的集合。一行的主要键标签集不包括具有null值的标签。
标签与字段
在设计InfluxDB的模式时,一个常见的问题是:“什么应该是标签,什么应该是字段?”以下指南应有助于您在设计模式时回答该问题。
- 使用标签来存储有关数据来源或上下文的元数据或标识信息。
- 使用字段来存储测量的值。
- 标签值只能是字符串。
- 字段值可以是以下数据类型之一
- 整数
- 无符号整数
- 浮点数
- 字符串函数
- 布尔值
InfluxDB Clustered对标签键、字段键和其他元数据进行索引以优化性能。它不对标签值或字段值进行索引。
InfluxDB v3存储引擎支持无限的标签值和系列基数。与由TSM存储引擎支持的InfluxDB不同,标签值的基数不会影响数据库的整体性能。
模式限制
不要为标签和字段使用重复的名称
在同一个表中,为标签和字段使用唯一的名称。InfluxDB Clustered将标签和字段作为唯一的列存储在表示磁盘上表的表中。如果您尝试写入包含具有相同名称的标签或字段的表,则写入会因列冲突而失败。
每张表的最大列数
表有一个最大列数。每行必须包含一个时间列。因此,表可以有以下内容
- 一个时间列
- 字段和标签列,最多配置的最大数量
如果您尝试向表写入并超出列限制,则写入请求将失败,InfluxDB将返回错误。
InfluxData将默认最大值确定为维护系统性能和稳定性的安全限制。超过此阈值可能导致宽模式,这可能会根据您的查询、模式的形状和模式中的数据类型对性能和资源使用产生负面影响。
为性能设计
您在表内如何构建模式会影响资源使用和针对该表的查询性能。
以下指南有助于优化查询性能
避免宽模式
宽模式是指具有大量列(标签和字段)的模式。
宽模式可能导致以下问题
- 在摄取数据期间持久化和压缩数据时增加资源使用。
- 由于具有太多标签的复杂主键,排序性能降低。
- 当选择太多列时,查询性能降低。
为了防止宽模式问题,限制存储在表中的标签和字段数量。如果您需要存储超过最大列数的数据,考虑将字段分割到单独的表中。
避免使用过多的标签
InfluxDB中,行的主键是由点的时间戳和标签集(即点上的标签键和标签值集合)的组合组成的。包含更多标签的点具有更复杂的主键,如果使用主键的所有部分进行排序,可能会影响排序性能。
避免稀疏模式
稀疏模式是指对于许多行,列包含null值。
这通常源于以下原因:
稀疏模式需要InfluxDB查询引擎评估许多null列,给存储和查询数据增加了不必要的开销。
例如,查看以下稀疏非同质模式示例。
使用不同时间戳写入单个字段
在不同时间使用不同时间戳报告字段会创建包含null值的独立行——例如
您报告带有tagset
的fieldA
,然后报告带有相同tagset
的field B
,但时间戳不同。结果是两个行:一个行中field A有null值,另一个行中field B有null值。
相比之下,如果您在相同的时间戳和标签集下报告不同时间的字段,现有行将被更新。这需要在摄入时间消耗更多资源,但在持久化时间或压缩时间得到解决,并避免稀疏模式。
表模式应该是同质的
存储在表中的数据应该是“同质的”,意味着每行应该有相同的标签和字段键。存储在表中的所有行共享相同的列,但如果点没有为列提供值,则列值为null。满载null值的表具有“稀疏”模式。
使用最适合您的数据的数据类型
在向字段写入数据时,使用最适合您数据的数据类型——将整数写入为整数,将小数写入为浮点数,将布尔值写入为布尔值。对存储整数的数据进行的查询优于对字符串数据进行的查询;在许多长字符串值上查询可能会影响性能。
为查询简单性设计
表、标签键和字段键的命名约定可以简化或复杂化编写数据查询的过程。以下指南有助于确保编写数据查询尽可能简单。
保持表名、标签和字段简单
为每个数据属性使用一个标签或一个字段。如果源数据在单个参数中包含多个数据属性,则将每个属性拆分到其自己的标签或字段中。
表名、标签键和字段键应简洁准确地描述其包含的内容。保持名称不包含数据。命名约定复杂的最常见原因是试图将数据属性“嵌入”到表名、标签键或字段键中。
当每个键和值代表数据的一个属性(而不是多个连接的属性)时,您将减少查询中对正则表达式的需求。没有正则表达式,您的查询将更容易编写且性能更高。
不推荐
例如,考虑以下以下行协议,它将多个属性(位置、型号和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
使用此架构查询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'
这个页面有用吗?
感谢您的反馈!