前言
时序数据库一般来说最常见的操作就只有2种,要么写,要么查
influx部分语法说明
特别注意:influxDB 2.0版本相对1.x版本改动较大,尤其是语法方面的改动,2.0版本的语法使用的是JavaScript,1.x使用的是sql。 这里使用的1.x的版本
进入influxdb
要操作 influxdb,首先要进行登录后才能操作,一般情况下,influxdb都是安装在linux系统中的,所以在控制台输入以下命令即可进入influxdb
# 直接登录
influx
# 通过账号密码登录
influx -username root -password 123456
用户相关
//查看用户,两列数据,一列是用户名称,一列是是否为管理员用户
show users
//创建普通户
create user "influx" with password '123456'
//创建管理员用户
create user "root" with password '123456' with all privileges
//修改用户密码
set password for root= 'root'
//通过cli操作influxdb
influx -username root -password root
权限相关
/**
* 数据库设置admin权限的两种方式(建议使用第二种)
*/
GRANT ALL PRIVILEGES ON 数据库名称 TO 用户名称
GRANT ALL PRIVILEGES TO 用户名称
/**
* 数据库撤销admin权限的两种方式(建议使用第二种)
*/
Revoke ALL PRIVILEGES ON 数据库名称 FROM 用户名称
Revoke ALL PRIVILEGES FROM 用户名称
数据库相关
1、创建数据库
create database db_name
2、查看所有数据库
show databases
3、删除库
drop database db_name
4、使用某个数据库
use db_name
表相关
influxdb中没有table(表)的概念,取而代之的是 measurements,功能与关系型数据库的中的表一致,也可以将measurements称为 influxdb中的表;
1、查看所有的表
show measurements
2、创建表
influxdb中没有建表语句,只能通过insert数据的方式来建立新表,也就是说在插入数据的时候会自动建表
3、插入数据
insert user,hostname=id value=12345678
- user: 表名
- hostname:索引字段名(tag)
- value:字段名,=后面是字段的值
注意:因为是时序数据库,当插入数据后,系统会自动追加时间戳,但也可以在添加数据时自己写入时间戳
insert user ,hostname=id value=12345678 1435362189575692182
指定多个tag
其中 table_1就是表名,host,hostname索引(tag),value=xx是记录值(field),记录值可以有多个,后面的时间戳是我们指定的,如果不指定系统自动加当前时间时间戳。
insert table_1,host=470b14f0-e869-43ed-a8e6-fd634258271f,hostname=server01 value=0.9 1651668886000000000
注意事项
当我们只有一个field时,他的值必须是数值、浮点型、boolean这三种中的其中一种,不能使用其他类型
# 以下三个命令都是可以正常执行的
insert table_4,hostname=server value=0
insert table_4,hostname=server value=false
insert table_4,hostname=server value=0.9
# 以下命令会报错,因为value是字符串类型
insert table_4,hostname=server value=abc
insert table_4,hostname=server value=woaini
insert table_4,hostname=server value=989p
而且一旦指定了类型,不能改变
# 先插入一条数据,value为数值
insert table_4,hostname=server value=0
# 在插入第二条数据,value为boolean类型, 会报错
insert table_4,hostname=server value=false
插入字符串类型的字段
# 其中,value字段为int类型, name字段为string类型
insert table_5,hostname=server value=0,name="woaini"
其中,value字段为int类型, name字段为string类型,age为string类型,xx为int类型
insert table_5,hostname=server value=0,name="w1oaini",age="woxiangni",xx=1
插入具有多个tag和多个field的数据
- 多个tag之间用逗号分割,不能有多余的字符或空格
- 多个field之间用逗号分割,不能有多余的字符或空格
- tag和field之间用空格分割,不能有多余的字符或空格
insert device_report_dp_log,device_id=G19Hkne5yQ0leOgw,dp_name=Alarm,message_id=123,rocket_message_id=123,ts=123,uuid=123 dp_event="456",dp_event_number=123,event_type=123,source=1,topic_type="1",type="1"
说明
- device_report_dp_log 是表名
- device_id 、dp_name、message_id、rocket_message_id、ts、uuid 是tag
- dp_event、dp_event_number、event_type、source、topic_type、type是field
- tag的数据类型都是string,不需要双引号,field的数据类型如果是string,需要加上双引号
4、删除表
# 如果不行就加上双引号
drop measurement table_name
drop measurement "table_name"
5、查询表
select * from table_name
6、tag(索引)
//查看表的tag
show tag keys from 表名称
7、field (字段)
//查看表的field
show field keys from 表名称
8、series
//查看表的series
show series from "表名称"
//查看当前库的series
show series
9、删除数据
influxdb没有提供删除功能,但是可以配置 数据保留策略。
数据保留策略
influxDB是没有提供直接删除数据记录的方法,但是提供数据保存策略,但是提供数据保存策略,主要用于指定数据保留时间,超过指定时间,就删除这部分数据。(数据库过期策略至少一个小时),默认保存策略为7天(168小时)
查看数据保存策略
# 查看某个库的策略
show retention policies on "数据库名称"
# 查看当前库下的策略,需要先用 use database 命令指定库名
show retention policies
查询结果如下
> SHOW RETENTION POLICIES ON telegraf
name duration shardGroupDuration replicaN default
default 0 168h0m0s 1 true
- name: 策略名称
- duration:数据保存时间,超过这个时间自动删除,0表示永久保存
- shardGroupDuration:shardGroup的存储时间,shardGroup是InfluxDB的一个基本储存结构,在这个时间内插入的数据查询较快,数据存放大于168小时查询速度降低;
- replicaN:全称是REPLICATION,副本个数
- default:是否默认策略
创建数据保留策略
# h(小时),d(天),w(星期)
//CREATE RETENTION POLICY "保留策略名称" ON "数据库名称" DURATION "该保留策略对应的数据过期时间" REPLICATION "复制因子,开源的InfluxDB单机环境永远为1" SHARD DURATION "分片组的默认时长" DEFAULT
create retention policy "testPolice" on myInfluxdb duration 72h replication 1 SHARD DURATION 1h default
//修改保留策略
alter retention policy "保留策略名称" on "数据库名称" duration 1d
//删除保留策略
drop retention policy "保留策略名称" on "数据库名称"
复杂查询
前言
表名 :device_escalation_log
表结构
字段名 | 说明 | 是否索引 | 数据类型 |
---|---|---|---|
device_id | 设备id | 是 | String |
message_id | 设备消息id | 是 | String |
rocket_message_id | mq消息id | 是 | String |
ts | 时间 | 是 | long |
uuid | 设备uuid | 是 | String |
msg | 消息内容 | 否 | String |
sources | 来源 | 否 | int |
一、普通查询
1、查询所有的 tag 和 field
SELECT * FROM device_escalation_log where uuid='123'
2、从单个measurement查询所有的field,不查tag
SELECT *::field FROM device_escalation_log
3、从单个measurement查询特定的field和tag.,注意:查询时至少要带上一个field key,如果只查询tag字段的话是查不到数据的
SELECT uuid,source FROM device_escalation_log
4、同时查询多张表
select * from device ,device_escalation_log
5、模糊查询
# 前缀匹配 ,相当于 mysql 的 like 'abc%'
select * from device_escalation_log where uuid=~/^abc/
# 后缀匹配 ,相当于 mysql 的 like '%abc'
select * from device_escalation_log where uuid=~/abc$/
# 前后匹配,相当于 mysql 的 like '%abc%'
select * from device_escalation_log where uuid=~/abc/
二、聚合函数
注意事项:
聚合函数只能对field字段进行操作,不能对tag字段操作,否则查询出来的列表是空的
如果我就要对tag字段进行聚合函数计算怎么办? 那我们可以通过子查询来实现:
select distinct(uuid) from (
select * from device_escalation_log
)
1、count() 统计
# 查询某个field字段的中的非空值数量
select count("msg") from device_escalation_log
2、DISTINCT() 去重
select DISTINCT("msg") from device_escalation_log
3、MEAN() 求平均值,这个平均值必须是数字类型
select MEAN("source") from device_escalation_log
4、MEDIAN() 求中位数,从单个字段(field)中的排序值返回中间值
select MEDIAN("source") from device_escalation_log
5、SPREAD() 返回字段的最小值和最大值之间的差值。数据的类型必须是长整型或float64
select SPREAD("source") from device_escalation_log
6、SUM() 求和
select SUM("source") from device_escalation_log
7、BOTTOM() 返回一个字段中最小的N个值。字段类型必须是长整型或float64类型。
select BOTTOM("source",6) from device_escalation_log
8、FIRST() 返回一个字段中最老的取值。(第一个插入的数据),相当于select * from table order by asc limit 1
select FIRST("source") from device_escalation_log
9、LAST() 返回一个字段中最新的取值。(最后一个插入的数据),相当于select * from table order by desclimit 1
select LAST("source") from device_escalation_log
10、MAX() 求最大值
select MAX("source") from device_escalation_log
11、PERCENTILE() 返回排序值排位为N的百分值。字段的类型必须是长整型或float64。
select PERCENTILE("source",3) from device_escalation_log
12、STDDEV() 返回一个字段中的值的标准偏差。值的类型必须是长整型或float64类型。
select STDDEV("source") from device_escalation_log
三、分组聚合
tag分组
# 根据uuid 进行分组
select * from device_escalation_log group by uuid
# 根据uuid 进行分组,若uuid为空,使用`5`进行填充
select source,uuid from device_escalation_log group by uuid fill(5)
先分组在聚合
# 分组聚合后只能查询聚合函数,不能查询字段 ,比如这个查询会报错: select count(source),uuid from device_escalation_log group by uuid fill(5)
select count(source) from device_escalation_log group by uuid fill(5)
select count(source) ,sum(source) from device_escalation_log group by uuid fill(5)
基于时间分组
# 查询所有数据,并对其划分为每200毫秒一组
select count(source) from device_escalation_log group by time(200ms)
# 查询所有数据,并对其划分为每200秒一组
select count(source) from device_escalation_log group by time(200s)
# 查询所有数据,并对其划分为每12分钟一组
select count(source) from device_escalation_log group by time(12m)
# 查询所有数据,并对其划分为每12小时一组
select count(source) from device_escalation_log group by time(12h)
# 查询所有数据,并对其划分为每12天一组
select count(source) from device_escalation_log group by time(12d)
# 查询所有数据,并对其划分为每12周一组
select count(source) from device_escalation_log group by time(12w)
四、分页查询
LIMIT 用法有2种
- limit 10:查询前10条数据
- limit size offset N: size表示每页 大小,N表示第几条记录开始查询
# 查询前10条数据
select * from device_escalation_log limit 10
# 分页,pageSize 为每页显示大小, pageIndex 为查询的页数
pageIndex = 1
pageSize = 10
SELECT * FROM device_escalation_log LIMIT pageSize OFFSET (pageIndex-1)*pageSize
五、排序
# 升序
select * from device_escalation_log order by time asc
# 降序
select * from device_escalation_log order by time desc
六、实现 in() 查询
关系型数据库可以用in关键字来查询多个值,就像这样
select * from user where user_name in ('张三','李四','王五');
但是时序数据库是没有 in 查询的,虽然in是保留的关键字,但是依然有办法解决, 还记得刚刚的模糊查询吗?没错,就是用它来解决这个问题
# 同时匹配 123 和 thing ,因为前后都机上了 ^ 和 $ ,所以这已经不是模糊查询,而是完全匹配才会查询出来
select * from device_escalation_log where uuid =~/^123$|^thing$/
六、查看执行计划
和mysql一样,在前面加上 explain 关键字即可,查询结果尚在研究中
explain select distinct("source") from device_escalation_log
七、指定时区
当我们插入influxdb时默认插入的time字段是0时区的,需要转成指定的时区可以在后面加上 ts('时区字符串')
SELECT * FROM "device_issue_log_111" WHERE time > now() - 5m tz('Asia/Shanghai')
以下是各个国家的时区列表
0 = "Africa/Abidjan"
1 = "Africa/Accra"
2 = "Africa/Addis_Ababa"
3 = "Africa/Algiers"
4 = "Africa/Asmara"
5 = "Africa/Asmera"
6 = "Africa/Bamako"
7 = "Africa/Bangui"
8 = "Africa/Banjul"
9 = "Africa/Bissau"
10 = "Africa/Blantyre"
11 = "Africa/Brazzaville"
12 = "Africa/Bujumbura"
13 = "Africa/Cairo"
14 = "Africa/Casablanca"
15 = "Africa/Ceuta"
16 = "Africa/Conakry"
17 = "Africa/Dakar"
18 = "Africa/Dar_es_Salaam"
19 = "Africa/Djibouti"
20 = "Africa/Douala"
21 = "Africa/El_Aaiun"
22 = "Africa/Freetown"
23 = "Africa/Gaborone"
24 = "Africa/Harare"
25 = "Africa/Johannesburg"
26 = "Africa/Juba"
27 = "Africa/Kampala"
28 = "Africa/Khartoum"
29 = "Africa/Kigali"
30 = "Africa/Kinshasa"
31 = "Africa/Lagos"
32 = "Africa/Libreville"
33 = "Africa/Lome"
34 = "Africa/Luanda"
35 = "Africa/Lubumbashi"
36 = "Africa/Lusaka"
37 = "Africa/Malabo"
38 = "Africa/Maputo"
39 = "Africa/Maseru"
40 = "Africa/Mbabane"
41 = "Africa/Mogadishu"
42 = "Africa/Monrovia"
43 = "Africa/Nairobi"
44 = "Africa/Ndjamena"
45 = "Africa/Niamey"
46 = "Africa/Nouakchott"
47 = "Africa/Ouagadougou"
48 = "Africa/Porto-Novo"
49 = "Africa/Sao_Tome"
50 = "Africa/Timbuktu"
51 = "Africa/Tripoli"
52 = "Africa/Tunis"
53 = "Africa/Windhoek"
54 = "America/Adak"
55 = "America/Anchorage"
56 = "America/Anguilla"
57 = "America/Antigua"
58 = "America/Araguaina"
59 = "America/Argentina/Buenos_Aires"
60 = "America/Argentina/Catamarca"
61 = "America/Argentina/ComodRivadavia"
62 = "America/Argentina/Cordoba"
63 = "America/Argentina/Jujuy"
64 = "America/Argentina/La_Rioja"
65 = "America/Argentina/Mendoza"
66 = "America/Argentina/Rio_Gallegos"
67 = "America/Argentina/Salta"
68 = "America/Argentina/San_Juan"
69 = "America/Argentina/San_Luis"
70 = "America/Argentina/Tucuman"
71 = "America/Argentina/Ushuaia"
72 = "America/Aruba"
73 = "America/Asuncion"
74 = "America/Atikokan"
75 = "America/Atka"
76 = "America/Bahia"
77 = "America/Bahia_Banderas"
78 = "America/Barbados"
79 = "America/Belem"
80 = "America/Belize"
81 = "America/Blanc-Sablon"
82 = "America/Boa_Vista"
83 = "America/Bogota"
84 = "America/Boise"
85 = "America/Buenos_Aires"
86 = "America/Cambridge_Bay"
87 = "America/Campo_Grande"
88 = "America/Cancun"
89 = "America/Caracas"
90 = "America/Catamarca"
91 = "America/Cayenne"
92 = "America/Cayman"
93 = "America/Chicago"
94 = "America/Chihuahua"
95 = "America/Coral_Harbour"
96 = "America/Cordoba"
97 = "America/Costa_Rica"
98 = "America/Creston"
99 = "America/Cuiaba"