快照视图

松果时序数据库为每个数据表提供一个快照视图,快照视图包含该表中每个设备最新的一条数据。若某个设备未添加过数据,则不会出现在快照视图中;快照视图名为表名后加”.snapshot”,例如:表tab01的快照视图为tab01.snapshot

注意:目前快照视图不支持聚合查询!
快照视图使用实例:

  1. 创建表
  1. CREATE TABLE testSnap
  2. (
  3. devid bigint,
  4. tstamp datetime,
  5. val01 bool,
  6. val02 bigint
  7. )
  1. 添加设备
  1. INSERT INTO sys_dev(tabname, devid, devname)
  2. VALUES('testSnap', 1, 'device 1'),
  3. ('testSnap', 2, 'device 2'),
  4. ('testsnap', 3, 'device 3')
  1. 插入数据
  1. INSERT INTO testSnap(devid, tstamp, val01, val02)VALUES(1, now(), true, 101),(2, now(), false, 201)
  1. 查询快照
  1. SELECT * FrOM testSnap.snapshot

查询结果

image.png

  1. 从查询结果可知,设备3未添加过数据,故不会出现在快照视图中。
  1. 继续插入数据
  1. INSERT INTO testSnap(devid, tstamp, val01, val02)
  2. VALUES(2, now(), true, 202),(3, now(), false, 301)
  1. 查询快照
  1. SELECT * FROM testSnap.snapshot

查询结果

image.png

从上面测试可知,每个设备只有最新的一条数据存在于快照视图中。

下面是利用快照视图提供的一些功能,使用上例中testSnap表:

  • 查询快照中满足某些条件的设备
  1. SELECT *
  2. FROM testSnap.snapshot
  3. WHERE devid in (1, 3, 5) AND val01 = true
  • 查询5分钟之内未上传新数据的设备:
  1. SELECT devid
  2. FROM testSnap.snapshot
  3. WHERE tstamp < datetimeadd(now(),-5m)
  4. LIMIT 1000

在松果时序数据库中,每次查询最多获取10000条数据,以查询离线设备为例:若要查询的设备超过10000条,则需要多次查询,如果简单使用LIMIT子句查询,两次查询之间可能有一些数据插入会导致某些数据无法查询到。

为了不让测试表中已有的数据影响,可以删除已有的设备

测试步骤如下:

  1. 准备环境,为了不让表testSnap中已有数据影响查询结果,我们先删除表中所有设备
  1. DELETE FROM sys_dev WHERE tabname='testSnap'
  1. 创建设备
  1. INSERT INTO sys_dev(tabname, devid, devname)
  2. VALUES('testSnap', 101, 'device 101'),
  3. ('testSnap', 102, 'device 102'),
  4. ('testSnap', 103, 'device 103'),
  5. ('testSnap', 104, 'device 104'),
  6. ('testSnap', 105, 'device 105'),
  7. ('testSnap', 106, 'device 106')
  1. 插入数据,以5分钟离线为例,插入数据的时间是当前时间减10分钟,故:所有设备都已离线
  1. INSERT INTO testSnap(devid, tstamp, val01, val02)
  2. VALUES(101, datetimeadd(now(), -10m), true, 1001),
  3. (102, datetimeadd(now(), -10m), true, 2001),
  4. (103, datetimeadd(now(), -10m), true, 3001),
  5. (104, datetimeadd(now(), -10m), true, 4001),
  6. (105, datetimeadd(now(), -10m), true, 5001),
  7. (106, datetimeadd(now(), -10m), true, 6001)

3.查询离线数据,每次查询3条

3.1第一次查询

  1. SELECT * FROM testSnap.snapshot
  2. WHERE tstamp < datetimeadd(now(), -5m)
  3. LIMIT 0,3

查询到的设备为:101,102,103

3.2第二次查询

  1. SELECT * FROM testSnap.snapshot
  2. WHERE tstamp < datetimeadd(now(), -5m)
  3. LIMIT 3,3

查询到的设备为:104,105,106

在这个测试中,虽然我们查询出了所有离线的设备,若3.1和3.2之间其他客户端插入了设备101的数据,如下示例:

4.查询过程中,其他客户端插入了已查询过设备的数据

4.1 第一次查询

  1. SELECT * FROM testSnap.snapshot
  2. WHERE tstamp < datetimeadd(now(), -5m)
  3. LIMIT 0,3

查询到的设备为:101,102,103

4.2 插入101设备的数据

  1. INSERT INTO testSnap(devid, tstamp, val01, val02)
  2. VALUES(101, now(), false, 1002)

4.3第二次查询

  1. SELECT * FROM testSnap.snapshot
  2. WHERE tstamp < datetimeadd(now(), -5m)
  3. LIMIT 3,3

查询到的设备为:105,106

设备104未被查询到,故:直接使用LIMIT子句多次查询可能会少查询到数据,正确的方式应该如下:

5.多次查询快照数据的正确方式(等5分钟让已有数据都离线,再测试)

5.1 第一次查询

  1. SELECT * FROM testSnap.snapshot
  2. WHERE tstamp < datetimeadd(now(), -5m)
  3. LIMIT 0,3

查询到的设备为:101,102,103

5.2 插入101设备的数据

  1. INSERT INTO testSnap(devid, tstamp, val01, val02)
  2. VALUES(101, now(), false, 1002)

5.3 第二次查询,添加查询条件,devid > 103

  1. SELECT * FROM testSnap.snapshot
  2. WHERE tstamp < datetimeadd(now(), -5m) AND devid > 103
  3. LIMIT 0,3

查询到的设备为:104,105,106

从第二次开始每次查询限定查询的设备ID大于上一次最大的设备ID,不但能保证查询的数据正确性,还能提高查询性能。