2020-11-20 , version 3.0
概述
本文档介绍松果时序数据库(以下又称PinusDB)3.0版本的使用。
读者对象
本文档适用于使用松果时序数据库的运维及开发工程师。
联系我们
如果您有任何疑问或建议,请提交Issue或发送邮件到 zhangqhn@foxmail.com
产品概述
随着互联网的发展,计算机硬件价格下降、体积小型化使得智能设备大量普及,例如:手环、共享单车、智能电表、环境监测设备、新能源汽车、汽车充电桩等等,这些设备在运营过程中会持续产生数据;针对这些数据的分析能为企业决策、产品升级、智能调度等提供了数据支撑,人类也将步入智能时代。由于智能设备数量巨大,这就对传统数据处理方式提出了挑战。在此背景下我们根据智能设备产生的数据特点,设计、研发了高性能的松果时序数据库,帮助客户解决海量智能设备数据的处理。
松果时序数据库(以下也称PinusDB)是一款针对物联网智能设备数据特点研发的具备高压缩比、高性能的时序数据库。广泛应用于物联网(IoT)设备、智慧城市、智慧物流、环境监测等数据处理。
PinusDB针对传感数据基于时序的特点使用特殊的方式处理、存储。解决海量物联网设备高频率数据处理,经过我们特有的压缩算法降低数据存储空间90%以上,降低企业运维、管理成本。
产品优势
名词解释
时序数据:持续产生的一系列数据。例如:监测某台电梯时,每秒采集电梯状态值而产生的一系列数据。
设备ID(devid): 某个被监测的设备,大于0的整数,唯一标识一个设备,例如:某台电梯、某个充电桩、某辆共享单车等等。
时间戳(tstamp): 数据产生的时间,取值范围1970-1-1 ~ 2999-12-31,精确到毫秒。
数据写入窗口:松果时序数据库对数据的时间戳字段(tstamp)的值设定了时间窗口,只能写入处于时间窗口之内的数据。时间窗口以系统当前时间为标准,向前后扩展指定的时间(由系统表sys_config中insertValidDay项的取值确定,单位为天,可以修改系统配置文件config.ini中insertValidDay项指定合适的值,默认为1天)。例如:当前时间为2019-10-15,系统配置中insertValidDay的值为1,则数据写入窗口为 2019-10-14 0:0:0 到 2019-10-16 23:59:59,此处以格林尼治时间为标准,在中国东八区的实际写入窗口为 2019-10-14 8:0:0 到 2019-10-17 7:59:59。
数值
整数: 使用十进制数字书写,可以在前面加负号表示负数。
浮点数: 使用点(.)做为整数和小数的分割,也可以在前面加负号表示负数。
字符串
字符串是使用单引号(')或双引号(")包含的字符序列。若使用单引号将字符串包含起来,字符串中出现单引号时,用两个连续的单引号表示一个单引号;双引号亦然。单引号包含的字符串中出现双引号时不需要处理,反之亦然。
注意:字符串仅支持UTF8编码。
示例:字符串 ab'cd"ef 的正确书写如下:
'ab''cd"ef' 或 "ab'cd""ef"
二进制
二进制数据的书写是将一个字节分为两个十六进制数表示(0~F不区分大小写),并使用x'和'包含起来。
示例:0x283C 值的书写如下: x'283C'
时间类型
表示距离 1970-1-1 0:0:0.000000 的微秒数,可以用格式 'YYYY-MM-DD HH:mm:ss.us' 表示。 时间类型使用服务器所在的时区,若需要指定其他的时区可以在时间后加时区信息。东区为+,西区为-后面加时或时分。
示例:北京时间可以表示为如下:
'2019-10-10 18:41:23.327 +08' 或 '2019-10-10 18:41:23.327 +0800'
松果时序数据库仅支持AND逻辑运算符,支持以下比较运算符:
聚合函数对一组值执行计算并返回一个值。松果时序数据库的Group By子句只能引用设备列(devid)或时间戳列(tstamp)。
聚合函数可以使用AS来指定别名。
--查询val01大于100 和 val02 大于100的条数
SELECT countif(val01 > 100), countif(val02 > 100) FROM tab01
--查询val01大于500的所有val02的平均值
SELECT avg(val01 > 500, val02) FROM tab01
松果时序数据库提供获取服务器当前时间的内置函数now,在查询或插入数据时可以使用now函数获取服务器当前时间,精确到秒,例如以下示例:
insert into tab01(devid, tstamp, ...) values(1, now(), ...)
查询示例:
select now()
--查询结果
--|2020-11-18 22:21:04
计算一个时间与另一个时间段相加,第一个参数为datetime类型,第二个参数表示微秒数,可以为负数。
例如:计算当前时间前1分钟及后一分钟(1分钟为60000000微秒)的示例如下:
SELECT datetimeadd(now(), -60000000), datetimeadd(now(), 60000000)
为了方便时间运算也可以选择使用时间符号: 秒(s),分钟(m),小时(h), 如下所示:
SELECT datetimeadd(now(), 60s), datetimeadd(now(), -1d)
计算两个时间差的微秒数,例如:
SELECT datetimediff(datetimeadd(now(), 1m), now())
时间值的向下取整,取整单位: 秒(second), 分钟(minute), 小时(hour), 天(day), 示例如下:
--获取今天的零点
SELECT datetimefloor(now(), 'day')
注意:以天为单位进行取整时,使用的是服务器的时区。
时间值的向上取整, 取整单位:秒(second), 分钟(minute), 小时(hour), 天(day), 示例如下:
SELECT datetimeceil(now(), 'minute')
加法函数,支持 tinyint, smallint, int, bigint, float, double数据类型,示例如下:
SELECT add(12, 3.5)
减法函数,支持 tinyint, smallint, int, bigint, float, double数据类型,示例如下:
SELECT sub(12.8, 8.2)
乘法函数,支持 tinyint, smallint, int, bigint, float, double数据类型,示例如下:
SELECT mul(5, 8)
除法函数,支持 tinyint, smallint, int, bigint, float, double数据类型,示例如下:
SELECT div(5, 8.0)
求模函数,支持 tinyint, smallint, int, bigint 数据类型,示例如下:
SELECT mod(5, 8)
条件函数,需要三个参数,第一个参数为条件,若条件为真返回第二个参数,若条件为假返回第三个参数,示例如下:
SELECT if(5 > 8, 'true', 'false')
注意:第二、三个参数必须具备同样的数据类型。
绝对值函数, 支持tinyint, smallint, int, bigint, float, double数据类型,示例如下:
SELECT abs(-5),abs(5)
在windows上服务配置文件config.ini与松果时序数据库执行程序处于同一目录下
在Linux上服务配置文件位于:/etc/pinusdb/config.ini
config.ini文件中server配置节下的配置项
address, 服务启动的IP地址;
port, 服务启动的端口,默认8105;
cacheSize, 数据缓存大小,单位为MB;默认为0,表示系统会根据内存大小来决定缓存大小,最小为128MB,最大不超过系统内存的5/8;
当使用默认值时:
物理内存小于8GB,缓存为物理内存的1/4
物理内存小于64GB,缓存为物理内存的1/2
物理内存大于64GB,缓存为32GB
writeCache, 写数据缓存大小,单位为MB,推荐使用默认值
默认值为0,即由系统自动设置。
当数据缓存小于24GB,写缓存为数据缓存的1/2
当数据缓存大于24GB,写缓存为12GB
queryTimeOut,查询超时时间,单位为秒,默认值:300;
insertValidDay,有效写入时间窗口,单位为天,默认为1,详细信息参考名词解释相关内容;
tabPath,表目录,存放系统中创建的数据表及表配置文件,用户配置文件。
normalDataPath,普通数据目录,存放普通数据文件。
compressDataPath,压缩数据目录,存放压缩数据文件。
commitLogPath, 数据日志目录;
sysLogPath, 系统日志目录;
logLevel, 输出日志级别,取值:debug,info,warning,error;默认为info;
compressFlag,是否启动压缩,true - 系统将超过有效写入时间窗口的数据进行压缩;false - 不进行压缩;默认为true;
注意:松果时序数据库启动前,tabPath,normalDataPath,compressDataPath,commitLogPath,sysLogPath必须配置好,否则启动失败。
服务启动时会检查tabPath目录下表配置文件(table.json)以及用户文件(user.json)是否存在,若不存在,则系统创建空的表文件以及包含管理员:sa,密码为:pinusdb 的用户文件。
用户可以通过系统表查询系统信息,松果时序数据库包含如下系统表:
sys_config 数据库系统的配置信息,表结构如下:
列名 | 类型 | 描述 |
---|---|---|
name | string | 配置项名 |
value | string | 配置值 |
系统所有配置信息如下:
列名 | 类型 |
---|---|
address | 数据库服务的IP地址 |
port | 数据库服务的端口号 |
cacheSize | 数据库缓存大小,单位为MB |
writeCache | 写数据缓存大小,单位为MB |
queryTimeOut | 查询超时时间,单位为秒 |
insertValidDay | 插入时间窗口,单位为天 |
tabPath | 表目录 |
normalDataPath | 普通数据目录 |
compressDataPath | 压缩数据目录 |
commitLogPath | 数据日志目录 |
sysLogPath | 系统日志目录 |
logLevel | 输出日志级别 |
compressFlag | 是否启动压缩 |
majorVersion | 服务主版本 |
minorVersion | 服务次版本 |
buildVersion | 服务编译版本 |
sys_user 用户信息表,包含数据库的用户信息,表结构如下:
列名 | 类型 | 描述 |
---|---|---|
username | string | 用户名 |
userrole | string | 用户角色,readOnly, writeOnly, readWrite, admin |
sys_table 表信息,包含系统中所有的表名,表结构如下:
列名 | 类型 | 描述 |
---|---|---|
tabname | string | 表名 |
sys_column 表的列信息,表结构如下:
列名 | 类型 | 描述 |
---|---|---|
tabname | string | 表名 |
colname | string | 列名 |
datatype | string | 类型名,bool,tinyint,smallint,int,bigint,datetime,double,string,blob,real2,real3,real4,real6 |
iskey | bool | 是否主键 |
sys_dataFile 数据文件列表,表结构如下:
列名 | 类型 | 描述 |
---|---|---|
tabname | string | 表名 |
filedate | string | 文件存储的数据日期 |
filetype | string | 文件类型,normal:普通文件;compress:压缩文件 |
sys_dev 设备表,表结构如下:
列名 | 类型 | 描述 |
---|---|---|
tabname | string | 表名 |
devid | bigint | 设备ID |
devname | string | 设备名 |
expand | string | 扩展信息 |
sys_connection 网络连接表,表结构如下:
列名 | 类型 | 描述 |
---|---|---|
host | string | 客户端IP |
port | bigint | 客户端端口号 |
user | string | 登录用户 |
userrole | string | 用户角色 |
conntime | datetime | 连接时间 |
松果时序数据库用户角色分为readOnly、writeOnly、readWrite以及admin。
readOnly 用户只能查询数据(不包括系统表)。
writeOnly 用户只能向数据表写入数据。
readWrite 用户可以查询并写入数据到数据表。
admin 用户可以执行所有操作。
查询系统表sys_user,表结构参考系统表对应部分。
添加用户SQL 为: ADD USER userName IDENTIFIED BY 'password'
新添加的用户权限为readOnly
添加用户testuser并设置密码为abc123,示例如下:
ADD USER testuser IDENTIFIED BY 'abc123'
修改用户权限SQL 为:SET ROLE FOR username = readonly | writeonly | readwrite | admin
设置用户testuser的角色为readonly,示例如下:
SET ROLE FOR testuser = readonly
注意:系统不允许修改sa用户的角色。
修改用户密码的SQL为: SET PASSWORD FOR testuser= PASSWORD('newPassword')
修改用户testuser, 示例如下:
SET PASSWORD FOR testuser = PASSWORD('123abc')
删除用户的SQL为: DROP USER username
删除用户testuser,示例如下:
DROP USER testuser
在松果时序数据库中,可以通过查询系统表sys_table及sys_column获取系统表和数据表的表结构。
使用 CREATE TABLE 语句创建表。每个表必须有两个固定的列:设备ID(devid)列,数据类型为bigint;时间戳(tstamp)列,数据类型为datetime;表的主键为设备ID和时间戳,创建表时不需要也不能显示指定主键,也不能修改他们的类型和顺序,一个典型的创建表语句如下所示:
CREATE TABLE tabname
(
devid bigint,
tstamp datetime,
...
)
一个创建表tab01的示例:
CREATE TABLE tab01
(
devid bigint,
tstamp datetime,
val01 bool,
val02 bigint,
val03 datetime,
val04 double,
val05 real2,
val06 real3,
val07 real4,
val08 real6,
val09 string,
val10 blob
)
使用 ALTER TABLE 语句修改表结构,设备ID(devid)和时间戳(tstamp)列不可修改。一个典型的修改表结构语句如下所示:
ALTER TABLE tabname
(
devid bigint,
tstamp datetime,
...
)
一个修改表tab01的示例:
ALTER TABLE tab01
(
devid bigint,
tstamp datetime,
val01 bool,
val02 bigint,
val03 datetime,
val04 double,
val05 string,
val06 blob
)
概念说明:
字段标识 : 使用列名(不区分大小写)和类型的组合标识一个字段。
删除字段 : 若一个字段标识在原表结构中存在,新表结构中不存在,则表示该字段被删除。
新增字段 : 若一个字段标识在原表结构中不存在,新表结构中存在,则表示该字段是新增字段。需要说名的是当修改一个字段从val01 bool 到 val01 bigint 后表示删除了字段val01 bool , 新增了字段 val01 bigint。
修改表结构 : 若修改了任何字段之间的顺序、字段名、字段类型,都将视为修改了表结构。
修改表结构后有如下影响:
当系统执行插入数据时:
当系统执行查询数据时:
删除的字段无法查询到(数据依然存在),新添加的字段在已存在的数据文件上查询时的值为null。
修改表结构的实例:
--1. 创建表
CREATE TABLE test
(
devid bigint,
tstamp datetime,
val01 bool,
val02 bigint,
val03 double,
val04 real2
)
--2. 创建设备
INSERT INTO sys_dev(tabname, devid)
VALUES('test',1)
--3. 添加数据
INSERT INTO test(devid,tstamp,val01,val02,val03)
VALUES(1, now(), true, 1, 1.1111)
--4. 查询数据
SELECT * FROM test
-- devid | tstamp | val01| val02 | val03 | val04
-- 1 | 2019-10-14 13:29:37 | true | 1 | 1.1111 | 0
--从查询结果可知,若插入数据时未指定值,则会以该字段类型默认值填充
--5. 修改表结构
ALTER TABLE test
(
devid bigint,
tstamp datetime,
val02 bigint,
val03 double,
val04 real2,
val05 string
)
--6. 查询数据
SELECT * FROM test
-- devid | tstamp | val02| val03 | val04 | val05
-- 1 | 2019-10-14 13:29:37 | 1 | 1.1111 | 0 | null
--从查询结果可知,已无法查询到列val01的数据,由于val05列是新加的列,查询结果为 null
--7. 添加数据到已存在的数据文件
INSERT INTO test(devid,tstamp,val02,val03)
VALUES(1, now(), 2, 2.222)
--执行失败,当插入到已存在的数据文件上时,数据文件与当前表结构不匹配,无法插入数据
--8. 添加数据到不存在的数据文件
INSERT INTO test(devid,tstamp,val02,val03)
VALUES(1, now(1d), 3, 3.333)
--执行成功,插入数据时使用当前表结构创建数据文件
--9. 查询数据
SELECT * FROM test
-- devid | tstamp | val02| val03 | val04 | val05
-- 1 | 2019-10-14 13:29:37 | 1 | 1.1111 | 0 | null
-- 2 | 2019-10-15 13:40:10 | 3 | 3.333 | 0 |
分离表可以将数据表从系统中移除,但是保留表的设备文件和所有数据文件。分离表可以将一个表的所有数据转移到另一台服务器。具体操作结合后面的附加表和数据文件操作。
分离表的使用方法为 DETACH TABLE tabname
分离表tab01的示例如下:
DETACH TABLE tab01
附加表可以将表添加到系统中,表的设备文件必须在系统表目录下(即:sys_config系统表中tabPath配置项),使用 ATTACH TABLE tabname 将指定的表附加到系统中。
附加表tab01的示例如下:
ATTACH TABLE tab01
注意:附加表后,表原来的数据文件不会自动附加,请根据后面数据文件管理部分手动附加数据文件。
使用DROP TABLE 语句删除数据表,删除表会删除表的设备文件和所有数据文件,请谨慎操作。
删除表tab01的示例如下:
DROP TABLE tab01
在松果时序数据库中,每条数据都属于某个设备,所以必须先添加设备后才能写入数据。目前由官方编译、发布的执行程序每个数据库服务支持的最大设备数量为10万台。
系统中的设备信息可以通过查询系统表sys_dev获取,详细信息参考系统表部分。
管理员(角色为admin的用户才能添加设备)通过向sys_dev表中写入数据来添加设备。tabname必须是系统中已存在的表。设备ID(devid)必须大于0并且在每个表中唯一。devname和expand字段可以不指定。
向数据表tab01中添加设备的示例如下:
INSERT INTO sys_dev(tabname, devid, devname)
VALUES('tab01', 1, 'device 1'),('tab01', 2, 'device 2')
管理员通过对sys_dev执行删除来删除设备,设备删除后其对应的数据并没有删除,但是无法访问。重新添加相同的设备ID后,之间的数据可以访问。
几个删除设备的示例:
DELETE FROM sys_dev WHERE tabname='tab01' AND devid = 1
DELETE FROM sys_dev WHERE tabname='tab01'
松果时序数据库为每个数据表提供一个快照视图,快照视图包含该表中每个设备最新的一条数据。若某个设备未添加过数据,则不会出现在快照视图中;快照视图名为表名后加".snapshot",例如:表tab01的快照视图为tab01.snapshot
快照视图使用实例:
--1. 创建表
CREATE TABLE testSnap
(
devid bigint,
tstamp datetime,
val01 bool,
val02 bigint
)
--2. 创建设备
INSERT INTO sys_dev(tabname, devid, devname)
VALUES('testSnap', 1, 'device 1'),
('testSnap', 2, 'device 2'),
('testsnap', 3, 'device 3')
--3. 插入数据
INSERT INTO testSnap(devid, tstamp, val01, val02)
VALUES(1, now(), true, 101),(2, now(), false, 201)
--4. 查询快照
SELECT * FrOM testSnap.snapshot
--结果集
--devid | tstamp | val01 | val02
-- 1 | 2019-10-14 15:37:41 | true | 101
-- 2 | 2019-10-14 15:37:41 | false | 201
--从查询结果可知,设备3未添加过数据,故不会出现在快照视图中
--5. 继续插入数据
INSERT INTO testSnap(devid, tstamp, val01, val02)
VALUES(2, now(), true, 202),(3, now(), false, 301)
--6. 查询快照
SELECT * FROM testSnap.snapshot
--结果集
--devid | tstamp | val01 | val02
-- 1 | 2019-10-14 15:37:41 | true | 101
-- 2 | 2019-10-14 15:42:27 | true | 202
-- 3 | 2019-10-14 15:42:27 | false | 301
--从查询结果可知,每个设备只有最新的一条数据在快照视图中
下面是利用快照视图提供的一些功能,使用上例中testSnap表:
SELECT *
FROM testSnap.snapshot
WHERE devid in (1, 3, 5) AND val01 = true
--1. 查询离线设备的总数
SELECT count(*) AS cnt
FROM testSnap.snapshot
WHERE tstamp < now(-5m)
--2. 查询离线的设备,前1000条
SELECT devid
FROM testSnap.snapshot
WHERE tstamp < now(-5m)
LIMIT 1000
在松果时序数据库中,每次查询最多获取10000条数据,以查询离线设备为例:若要查询的设备超过10000条,则需要多次查询,如果简单使用LIMIT子句查询,两次查询之间可能有一些数据插入会导致某些数据无法查询到。
--1.创建设备
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')
--2.插入数据,以5分钟离线为例,所有设备都已离线
INSERT INTO testSnap(devid, tstamp, val01, val02)
VALUES(101, now(-10m), true, 1001),
(102, now(-10m), true, 2001),
(103, now(-10m), true, 3001),
(104, now(-10m), true, 4001),
(105, now(-10m), true, 5001),
(106, now(-10m), true, 6001)
--3.查询离线数据,每次查询两条
--3.1第一次查询
SELECT * FROM testSnap.snapshot
WHERE tstamp < now(-5m)
LIMIT 0,2
--查询到设备 101,102
--3.2第二次查询
SELECT * FROM testSnap.snapshot
WHERE tstamp < now(-5m)
LIMIT 2,2
--查询到设备 103,104
--3.3第三次查询
SELECT * FROM testSnap.snapshot
WHERE tstamp < now(-5m)
LIMIT 4,2
--查询到设备 105,106
在上例中,若3.1和3.2之间其他客户端插入了设备101的数据,如下示例:
--3.1第一次查询
SELECT * FROM testSnap.snapshot
WHERE tstamp < now(-5m)
LIMIT 0,2
--查询到设备 101,102
--插入数据
INSERT INTO testSnap(devid, tstamp, val01, val02)
VALUES(101, now(), false, 1002)
--3.2第二次查询
SELECT * FROM testSnap.snapshot
WHERE tstamp < now(-5m)
LIMIT 2,2
--查询到设备 104,105
--3.3第三次查询
SELECT * FROM testSnap.snapshot
WHERE tstamp < now(-5m)
LIMIT 4,2
--查询到设备 106
设备103未被查询到,故:直接使用LIMIT子句多次查询可能会少查询到数据,正确的方式应该如下:
--1. 第一次查询
SELECT * FROM testSnap.snapshot
WHERE tstamp < now(-5m)
LIMIT 2
--查询到设备 101,102
--2. 后面的查询
SELECT * FROM testSnap.snapshot
WHERE tstamp < now(-5m) AND devid > 102
LIMIT 2
从第二次开始每次查询限定查询的设备ID大于上一次最大的设备ID,不但能保证查询的数据正确性,还能提高查询性能。
松果时序数据库将每个表每天的数据存储在一个单独的文件中(时间以格林尼治时间为标准对齐,由于中国处于东八区,实际存储时间为每天8点到次日8点前的数据,也就是文件'2019-10-10'实际存储的是'2019-10-10 8:0:0' 到 '2019-10-11 7:59:59'的数据)。
管理员可以以文件为单位对数据进行管理,包括分离、附加、删除。可以方便对数据进行转储等操作。
数据文件存储路径为:数据目录/表名/年/月/数据文件名。
系统普通数据目录由sys_config表中normalDataPath项指定。
系统压缩数据目录由sys_config表中compressDataPath项指定。
数据文件名由表名_年月日组成。
例如:
系统普通数据目录为: e:/data,表tab01 在2019-8-10的普通文件:
在目录中月和日占两个字符,若小于10在前面补0
系统压缩数据目录为:e:/compress, 表tab01 在2019-8-5的压缩文件:
管理员可以将数据文件从系统中分离,分离后无法查询到对应数据。只能分离时间早于数据写入窗口(见产品介绍>名词解释部分)的数据文件。
分离文件使用方法: DETACH DATAFILE 'date' FROM tabname
例如:分离表tab01在2019-8-10的数据文件实例如下:
DETACH DATAFILE '2019-8-10' FROM tab01
将数据文件附加在表上,可以查询到对应的数据。
附加数据文件使用方法: ATTACH DATAFILE 'date','filetype' FROM tabname
其中filetype的取值:normal 普通文件;compress 压缩文件
附加数据文件实例
--附加表tab01在2019-8-5的压缩文件
ATTACH DATAFILE '2019-8-5','compress' FROM tab01
--附加表tab01在2019-8-10的普通文件
ATTACH DATAFILE '2019-8-10','normal' FROM tab01
将数据文件删除后,无法恢复,请谨慎操作!
要删除的数据文件的日期必须早于数据写入窗口。
删除数据文件使用方法:DROP DATAFILE 'date' FROM tabname
删除表tab01在2019-8-5的数据文件实例如下
DROP DATAFILE '2019-8-5' FROM tab01
松果时序数据库支持文本协议(sql语句)和二进制协议数据写入,他们的差别如下:
松果时序数据库支持一次写入一条或多条数据,不管是文本协议还是二进制协议都必须满足下面的条件:
(1) 单次请求只能向一个表中写入数据。
(2) 单次请求写入数据的上限为1000条。
(3) 单次请求写入的数据报文大小不超过4MB。
(4) 写入数据的时间戳必须处于写入时间窗口。
写入数据时,必须指定设备Id(devid)和时间戳(tstamp)的值,其他字段若没有指定值,会以该类型的默认值填充。
松果时序数据库写入数据时,根据数据的时间戳(tstamp)的值分配到不同的数据文件。数据文件以天为单位组织,需要注意的是:天的划分以格林尼治时间为标准,用于中国位于东八区,实际的划分为每天早上八点到第二天早上八点前的数据存储在一个文件中。
若针对某个设备,写入记录的时间戳大于所处数据文件中该设备所有记录的时间戳,或大部分写入(90%以上)满足前述条件,此时认为写入是顺序写入;否则,认为写入是随机写入。
顺序写入和随机写入有以下差别:
(1) 顺序写入性能高于随机写入。
(2) 对于普通数据文件(sys_datafile中的filetype值为normal),同样的数据以顺序写入占用空间小于随机写入占用的空间。由于压缩文件(sys_datafile中filetype值为compress)不支持用户直接写入,不存在这个差别。
高频写入数据会由于数据库服务内存不能及时写入磁盘,插入数据时返回 PdbE_RETRY错误码,此时可以暂停3-5秒后重新执行。
使用松果时序数据库的SDK执行写入,传递如下数据即可:
INSERT INTO tab01(devid, tstamp, val01)
VALUES(1, now(), 101),(2, now(), 102),(3, now(), 103)
注意:以文本协议写入多条数据时,若某条数据写入失败,则中止后面的数据写入,返回对应的错误码及成功写入的数据条数。
在.Net中支持以一个DataTable写入,具体使用方式参考.Net的SDK文档。
以DataTable写入时,除了需要满足本节开头列出的条件外,还需要满足:
在Java中以PreparedStatement配合addBatch,并且每个值都必须使用参数指定。来使用二进制协议写入数据。具体细节参考JDBC的SDK文档。
注意:与以文本协议写入数据不同,当其中某条数据写入失败时,其后的数据会继续写入,最终返回对应的错误码、成功写入的数据条数以及每条数据执行的结果。具体使用方式参考对应SDK文档。
若需要更新已写入的数据,将新数据重新写入即可。需要注意的是,未指定的列将会以默认值填充。
目前松果时序数据库不支持子查询以及多表join,查询语法如下所示:
SELECT {* | expr_list}
FROM tabname
WHERE condition
ORDER BY tstamp {ASC | DESC}
GROUP BY {devid | tstamp time}
LIMIT {querycnt | offset, querycnt}
其中:WHERE、ORDER BY、GROUP BY、LIMIT 子句为可选。
支持的聚合函数以及条件参考前面对应章节。
ORDER BY 子句和GROUP BY子句不能同时存在。
若不指定LIMIT 子句,默认查询前1000条数据,一次最多查询10000条数据。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。