快照视图
松果时序数据库为每个数据表提供一个快照视图,快照视图包含该表中每个设备最新的一条数据。若某个设备未添加过数据,则不会出现在快照视图中;快照视图名为表名后加”.snapshot”,例如:表tab01的快照视图为tab01.snapshot
注意:目前快照视图不支持聚合查询!
快照视图使用实例:
- 创建表
CREATE TABLE testSnap
(
devid bigint,
tstamp datetime,
val01 bool,
val02 bigint
)
- 添加设备
INSERT INTO sys_dev(tabname, devid, devname)
VALUES('testSnap', 1, 'device 1'),
('testSnap', 2, 'device 2'),
('testsnap', 3, 'device 3')
- 插入数据
INSERT INTO testSnap(devid, tstamp, val01, val02)VALUES(1, now(), true, 101),(2, now(), false, 201)
- 查询快照
SELECT * FrOM testSnap.snapshot
查询结果
从查询结果可知,设备3未添加过数据,故不会出现在快照视图中。
- 继续插入数据
INSERT INTO testSnap(devid, tstamp, val01, val02)
VALUES(2, now(), true, 202),(3, now(), false, 301)
- 查询快照
SELECT * FROM testSnap.snapshot
查询结果
从上面测试可知,每个设备只有最新的一条数据存在于快照视图中。
下面是利用快照视图提供的一些功能,使用上例中testSnap表:
- 查询快照中满足某些条件的设备
SELECT *
FROM testSnap.snapshot
WHERE devid in (1, 3, 5) AND val01 = true
- 查询5分钟之内未上传新数据的设备:
SELECT devid
FROM testSnap.snapshot
WHERE tstamp < datetimeadd(now(),-5m)
LIMIT 1000
在松果时序数据库中,每次查询最多获取10000条数据,以查询离线设备为例:若要查询的设备超过10000条,则需要多次查询,如果简单使用LIMIT子句查询,两次查询之间可能有一些数据插入会导致某些数据无法查询到。
为了不让测试表中已有的数据影响,可以删除已有的设备
测试步骤如下:
- 准备环境,为了不让表testSnap中已有数据影响查询结果,我们先删除表中所有设备
DELETE FROM sys_dev WHERE tabname='testSnap'
- 创建设备
INSERT INTO sys_dev(tabname, devid, devname)
VALUES('testSnap', 101, 'device 101'),
('testSnap', 102, 'device 102'),
('testSnap', 103, 'device 103'),
('testSnap', 104, 'device 104'),
('testSnap', 105, 'device 105'),
('testSnap', 106, 'device 106')
- 插入数据,以5分钟离线为例,插入数据的时间是当前时间减10分钟,故:所有设备都已离线
INSERT INTO testSnap(devid, tstamp, val01, val02)
VALUES(101, datetimeadd(now(), -10m), true, 1001),
(102, datetimeadd(now(), -10m), true, 2001),
(103, datetimeadd(now(), -10m), true, 3001),
(104, datetimeadd(now(), -10m), true, 4001),
(105, datetimeadd(now(), -10m), true, 5001),
(106, datetimeadd(now(), -10m), true, 6001)
3.查询离线数据,每次查询3条
3.1第一次查询
SELECT * FROM testSnap.snapshot
WHERE tstamp < datetimeadd(now(), -5m)
LIMIT 0,3
查询到的设备为:101,102,103
3.2第二次查询
SELECT * FROM testSnap.snapshot
WHERE tstamp < datetimeadd(now(), -5m)
LIMIT 3,3
查询到的设备为:104,105,106
在这个测试中,虽然我们查询出了所有离线的设备,若3.1和3.2之间其他客户端插入了设备101的数据,如下示例:
4.查询过程中,其他客户端插入了已查询过设备的数据
4.1 第一次查询
SELECT * FROM testSnap.snapshot
WHERE tstamp < datetimeadd(now(), -5m)
LIMIT 0,3
查询到的设备为:101,102,103
4.2 插入101设备的数据
INSERT INTO testSnap(devid, tstamp, val01, val02)
VALUES(101, now(), false, 1002)
4.3第二次查询
SELECT * FROM testSnap.snapshot
WHERE tstamp < datetimeadd(now(), -5m)
LIMIT 3,3
查询到的设备为:105,106
设备104未被查询到,故:直接使用LIMIT子句多次查询可能会少查询到数据,正确的方式应该如下:
5.多次查询快照数据的正确方式(等5分钟让已有数据都离线,再测试)
5.1 第一次查询
SELECT * FROM testSnap.snapshot
WHERE tstamp < datetimeadd(now(), -5m)
LIMIT 0,3
查询到的设备为:101,102,103
5.2 插入101设备的数据
INSERT INTO testSnap(devid, tstamp, val01, val02)
VALUES(101, now(), false, 1002)
5.3 第二次查询,添加查询条件,devid > 103
SELECT * FROM testSnap.snapshot
WHERE tstamp < datetimeadd(now(), -5m) AND devid > 103
LIMIT 0,3
查询到的设备为:104,105,106
从第二次开始每次查询限定查询的设备ID大于上一次最大的设备ID,不但能保证查询的数据正确性,还能提高查询性能。