InfluxDB模式设计
为更简单、更高效的查询设计模式。遵循设计指南以使模式易于查询。了解这些指南如何导致更高效的查询。
良好的模式设计可以防止高系列基数,从而提高查询性能。如果您注意到数据读取和写入速度减慢或想了解基数如何影响性能,请参阅如何解决高基数。
设计以查询
测量 | 标签键 | 标签键 | 字段键 | 字段键 |
---|---|---|---|---|
airSensor | sensorId | station | humidity | temperature |
waterQualitySensor | sensorId | station | pH | temperature |
airSensor
和waterQualitySensor
模式说明了以下指南
- 每个测量都是一个简单的名称,用于描述模式。
- 键在模式中不重复。
- 键不使用保留关键字或特殊字符。
- 标签(
sensorId
和station
)存储多个数据点的元数据。 - 字段(
humidity
、pH
和temperature
)存储数值数据。 - 字段存储唯一或高度可变的数据。
- 测量和键不包含数据;标签值和字段值将存储数据。
以下点(格式化为行协议)使用了airSensor
和waterQualitySensor
模式
airSensor,sensorId=A0100,station=Harbor humidity=35.0658,temperature=21.667 1636729543000000000
waterQualitySensor,sensorId=W0101,station=Harbor pH=6.1,temperature=16.103 1472515200000000000
保持测量和键简单
将数据存储在标签值或字段值中,而不是在标签键、字段键或测量中。如果您将模式设计为在标签和字段值中存储数据,则查询将更容易编写且更高效。
比较模式
比较以下由行协议表示的有效模式。
推荐:以下模式将元数据存储在单独的crop
、plot
和region
标签中。字段temp
包含可变数值数据。
Good Measurements schema - Data encoded in tags (recommended)
-------------
weather_sensor,crop=blueberries,plot=1,region=north temp=50.1 1472515200000000000
weather_sensor,crop=blueberries,plot=2,region=midwest temp=49.8 1472515200000000000
不推荐:以下模式将多个属性(crop
、plot
和region
)连接(blueberries.plot-1.north
)在测量中,类似于Graphite度量。
Bad Measurements schema - Data encoded in the measurement (not recommended)
-------------
blueberries.plot-1.north temp=50.1 1472515200000000000
blueberries.plot-2.midwest temp=49.8 1472515200000000000
不推荐:以下模式将多个属性(crop
、plot
和region
)连接(blueberries.plot-1.north
)在字段键中。
Bad Keys schema - Data encoded in field keys (not recommended)
-------------
weather_sensor blueberries.plot-1.north.temp=50.1 1472515200000000000
weather_sensor blueberries.plot-2.midwest.temp=49.8 1472515200000000000
比较查询
比较以下良好测量和不良测量方案的查询。良好测量查询计算北地区蓝莓的平均temp
。
查询简单:良好测量数据可以通过region
标签值轻松过滤,如下例所示。
// Query *Good Measurements*, data stored in separate tags (recommended)
from(bucket:"example-bucket")
|> range(start:2016-08-30T00:00:00Z)
|> filter(fn: (r) => r._measurement == "weather_sensor" and r.region == "north" and r._field == "temp")
|> mean()
查询困难:不良测量需要正则表达式从测量中提取plot
和region
,如下例所示。
// Query *Bad Measurements*, data encoded in the measurement (not recommended)
from(bucket:"example-bucket")
|> range(start:2016-08-30T00:00:00Z)
|> filter(fn: (r) => r._measurement =~ /\.north$/ and r._field == "temp")
|> mean()
复杂的测量使得一些查询变得不可能。例如,使用不良测量方案计算两个图块的平均温度是不可能的。
保持键简单
除了保持键中没有数据之外,遵循以下额外的指南以使它们更容易查询
避免键中的关键词和特殊字符
为了简化查询编写,不要在标签和字段键中包含保留关键词或特殊字符。如果您在键中使用Flux关键词,那么您必须将键用双引号括起来。如果您在键中使用非字母数字字符,那么您必须在Flux中使用括号表示法。
避免标签和字段的重复名称
避免在同一个方案中使用相同的名称作为标签键和字段键。如果您有一个具有相同名称的标签和字段,则查询结果可能不可预测。
使用显式桶方案来强制执行方案内唯一标签和字段键。
使用标签和字段
标签值被索引,而字段值没有被索引。这意味着查询标签比查询字段性能更好。您的查询应该指导您在标签中存储什么以及在字段中存储什么。
使用字段存储唯一和数值数据
- 将唯一或经常变化的值作为字段值存储。
- 将数值作为字段值存储。(标签只存储字符串)。
使用标签提高查询性能
由于InfluxDB索引标签,查询引擎不需要扫描桶中的每个记录来定位标签值。例如,考虑一个存储关于成千上万个用户的数据的桶。如果将userId
存储在一个字段中,则查询用户abcde
需要InfluxDB扫描每一行的userId
。
from(bucket: "example-bucket")
|> range(start: -7d)
|> filter(fn: (r) => r._field == "userId" and r._value == "abcde")
为了更快地检索数据,对标签进行过滤以减少扫描的行数。标签应存储可以合理索引的数据。以下查询通过company
标签进行过滤,以减少对userId
扫描的行数。
from(bucket: "example-bucket")
|> range(start: -7d)
|> filter(fn: (r) => r.company == "Acme")
|> filter(fn: (r) => r._field == "userId" and r._value == "abcde")
保持标签简单
每个数据属性使用一个标签。如果源数据在一个参数中包含多个数据属性,请将每个属性拆分到自己的标签中。当每个标签代表您数据的一个属性(不是多个连接的属性)时,您将减少查询中正则表达式的需求。没有正则表达式,您的查询将更容易编写且性能更优。
比较模式
比较以下由行协议表示的有效模式。
推荐:以下模式将位置数据拆分为plot
和region
标签。
Good Tags schema - Data encoded in multiple tags
-------------
weather_sensor,crop=blueberries,plot=1,region=north temp=50.1 1472515200000000000
weather_sensor,crop=blueberries,plot=2,region=midwest temp=49.8 1472515200000000000
不推荐:以下模式将多个属性(plot
和region
)连接在location
标签值中(plot-1.north
)。
Bad Tags schema - Multiple data encoded in a single tag
-------------
weather_sensor,crop=blueberries,location=plot-1.north temp=50.1 1472515200000000000
weather_sensor,crop=blueberries,location=plot-2.midwest temp=49.8 1472515200000000000
比较查询
比较良好标签和不良标签模式下的查询。Flux查询计算北区域蓝莓的平均temp
。
易于查询:如以下示例所示,良好标签数据可以很容易地通过region
标签值进行筛选。
// Query *Good Tags* schema, data encoded in multiple tags
from(bucket:"example-bucket")
|> range(start:2016-08-30T00:00:00Z)
|> filter(fn: (r) => r._measurement == "weather_sensor" and r.region == "north" and r._field == "temp")
|> mean()
难以查询:不良标签需要使用正则表达式解析复杂的location
值,如以下示例所示。
// Query *Bad Tags* schema, multiple data encoded in a single tag
from(bucket:"example-bucket")
|> range(start:2016-08-30T00:00:00Z)
|> filter(fn: (r) => r._measurement == "weather_sensor" and r.location =~ /\.north$/ and r._field == "temp")
|> mean()
要了解InfluxDB数据模型的概述,请观看以下视频
这个页面有帮助吗?
感谢您的反馈!