在sqlite3中存储具有标识符的时间序列数据的最佳方法

问题描述

让我们说说有很多不同的传感器,它们在测量数据时会将所有数据保存在数据库中,每个传感器可以有更多的条目。我正在寻找保存此数据的最佳方法,以便以后可以尽可能快地完成选择查询

"CREATE TABLE IF NOT EXISTS DataTable (sensor_id TEXT,measured_value REAL,time_of_measuring REAL)"

基本上可以工作,但是我认为选择起来不是很快。我知道主键,但是它们可以防止重复,因此我不能仅仅将sensor_id用作主键。我基本上是在寻找等效于保存这样的数据的sqlite,但是在一个表中并且一个度量是一行:

data = {"sensor1":[x1,x2,x3],"sensor2":[z1,z2,z3]...}

我想像ˇˇ这样的东西可以为每个传感器插入多个值,但这对选择有帮助吗?

"CREATE TABLE IF NOT EXISTS DataTable (sensor_id TEXT NOT NULL,time_of_measuring REAL NOT NULL,PRIMARY KEY(sensor_id,time_of_measuring ))"

解决方法

对于此时间序列数据,相关的主(或唯一)密钥可能是(time_of_measuring,sensor_id)。这与问题末尾的建议很接近,但各列的顺序相反。

从技术上讲,这可以防止传感器在同一时间点记录两个度量,这似乎是与数据相关的业务规则。

关于查询速度:高度取决于查询本身。假设您有以下查询:

select sensor_id,measured_val,time_of_measuring
from data_table
where 
    sensor_id = ? 
    and time_of_measuring >= ?
    and time_of_measuring <  ?
order by sensor_id,time_of_measuring
    

此查询将利用主键索引,因为这些列与whereorder by子句的列相同。您可以将measured_val添加到索引中以使查询更加高效:

create index data_table_idx1 
    on data_table(sensor_id,time_of_measuring,measured_val);
    

作为另一个示例,请考虑以下where子句:

where time_of_measuring >= ? and time_of_measuring <  ?

sensor_id上没有谓词,但是time_of_measuring是索引中的第一列,因此可以使用主键索引。

作为典型的反例,以下where子句不会使索引受益:

where sensor_id = ?                         -- need an index where `sensor_id` is first
where sensor_id = ? and measured_val >= ?   -- needs an index on "(sensor_id,measured_val)"