SpringBoot操作InfluxDb数据库
一、InfluxDb数据库简介
InfluxDb用Go语言编写的一个开源分布式时序、事件和指标数据库,和传统是数据库相比有不少不同的地方。
类似的数据库有Elasticsearch、Graphite等。
1.提供了Http接口的API来操作数据
2.提供了类似sql的数据库语句
3.不支持数组保存
4.influxdb中的一条记录point,主要可以分为三类,必须存在的time(时间),string类型的tag,以及其他成员field;而series则是一个measurement中保存策略和tag集构成,Measurement相当于关系型数据的表。
二、InfluxDb保存策略
1、默认是不删除,保存策略永久
> SHOW RETENTION POLICIES ON telegraf
name duration shardGroupDuration replicaN default
default 0 168h0m0s 1 true
可以看到,telegraf只有一个策略,各字段的含义如下:
name--名称,此示例名称为 default
duration--持续时间,0代表无限制
shardGroupDuration--shardGroup的存储时间,shardGroup是InfluxDB的一个基本储存结构,应该大于这个时间的数据在查询效率上应该有所降低。
replicaN--全称是REPLICATION,副本个数
default--是否是默认策略
- 可以新建策略
CREATE RETENTION POLICY "2_hours" ON "telegraf" DURATION 2h REPLICATION 1 DEFAULT
> SHOW RETENTION POLICIES ON telegraf
name duration shardGroupDuration replicaN default
default 0 168h0m0s 1 false
2_hours 2h0m0s 1h0m0s 1 true
- 修改策略
> ALTER RETENTION POLICY "2_hours" ON "telegraf" DURATION 4h DEFAULT
> show retention POLICIES on telegraf
name duration shardGroupDuration replicaN default
default 0 168h0m0s 1 false
2_hours 4h0m0s 1h0m0s 1 true
- 删除策略
> drop retention POLICY "2_hours" ON "telegraf"
> show retention POLICIES on telegraf
name duration shardGroupDuration replicaN default
default 0 168h0m0s 1 false
- 测试结果
插入数据测试工具:https://github.com/influxdata/influx-stress
读取数据测试工具:https://github.com/influxdata/influxdb-comparisons
分页查询语句: SELECT time,Field列 FROM measurement WHERE 时间范围 LIMIT rows OFFSET (page - 1)*rows
查询性能:平均每秒执行600次。
插入性能:平均每秒10w次。
- Java代码
1.maven的jar包依赖
<dependency>
<groupId>org.influx
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
<version>2.15</version>
</dependency>
r2.properties文件配置
spring.influx.url=http://127.0.0.1:8086
spring.influx.user=root
spring.influx.password=root
3.插入代码
经个人测试,InfluxDB的列的排列顺序是按照英文字母先后顺序排列的,time除外,time排第一位,其他按照英文字母先后顺序依次排列
Point.Builder b
3.uilder = Point.measurement("testDatas");
builder.time(Sys
@GetMapping(value = "addTestDatas")
public void insert() {
Point.Builder builder = Point.measurement("testDatas");
builder.time(System.currentTimeMillis(),TimeUnit.MICROSECONDS);
builder.addField("label","测试标签");
builder.addField("type",2);
builder.addField("data","东经30度,北纬38度,天气晴");
builder.addField("equipmentId", UUID.randomUUID().toString());
builder.addField("alarm", false);
StringBuilder sb = new StringBuilder(UUID.randomUUID().toString());
for (int i = 0; i < 30; i++) {
sb.append(UUID.randomUUID().toString()).append(",");
}
builder.addField("systemModelIds", sb.toString().substring(0, sb.toString().length() - 1));
builder.tag("cpuid","666888");
builder.tag("cputype","F");
Point point = builder.build();
influxDB.setDatabase("testdb").write(point);
}
t4.查询代码
SString command = "select * from testDatas";
Query query = new Query(command,"testdb");
// QueryResul
@GetMapping("/queryTestData")
public String testQuery() {
String command = "select * from testDatas";
Query query = new Query(command,"testdb");
// QueryResult queryResult = influxDB.query(query);
QueryResult queryResult = influxDB.query(query, TimeUnit.MILLISECONDS);
List<QueryResult.Result> results = queryResult.getResults();
if (results == null) {
return null;
}
// 多个sql用分号隔开,因本次查询只有一个sql,所以取第一个就行
QueryResult.Result result = results.get(0);
List<QueryResult.Series> seriesList = result.getSeries();
List<MeasuringPointData> tests = new LinkedList<>();
for (QueryResult.Series series : seriesList) {
if (series == null) {
return null;
}
System.out.println("colums ==>> " + JSON.toJSON(series.getColumns()));
System.out.println("tags ==>> " + JSON.toJSON(series.getTags()));
System.out.println("name ==>> " + JSON.toJSON(series.getName()));
System.out.println("values ==>> " + JSON.toJSON(series.getValues()));
System.out.println("查询总数为: ==>> " + (series.getValues() == null ? 0 : series.getValues().size()));
List<MeasuringPointData> dataVos = new LinkedList<>();
series.getValues().forEach(testData -> {
MeasuringPointData dataVo = new MeasuringPointData();
// 直接查询出来的是科学计数法,需要转换为Long类型的数据
BigDecimal decimalTime = new BigDecimal(testData.get(0).toString());
dataVo.setTime(decimalTime.longValue());
dataVo.setAlarm((boolean) testData.get(1));
dataVo.setData(testData.get(4).toString());
dataVo.setEquipmentId(testData.get(5).toString());
dataVo.setLabel(testData.get(6).toString());
System.out.println("长度信息==>> " + testData.get(7).toString().length());
dataVo.setSystemModelIds(Arrays.asList(StringUtils.split(testData.get(7).toString(), "\\,")));
dataVo.setType(Double.valueOf(testData.get(8).toString()).intValue());
System.out.println("数组长度==>> " +dataVo.getSystemModelIds().size());
dataVos.add(dataVo);
});
System.out.println("最终结果为: " + JSON.toJSON(dataVos));
tests = dataVos;
}
return JSON.toJSONString(tests);
}
t queryResult = influxDB.query(query);
文档地址
https://docs.influxdata.com/influxdb/v1.7/troubleshooting/frequently-asked-questions/
- 插入及查询语句
- 查询语句:
InfluxDb语句类传统数据库语句,支持order by, limit分页查询及where语句等。
以下是模糊查询示例(包含某个信息)
SELECT * FROM "testDatas" WHERE systemModelIds =~ /e2703312-49ec-4285-9efd-3e30fe8ad8e0/
①.实现查询以给定字段开始的数据
select fieldName from measurementName where fieldName=~/^给定字段/
②.实现查询以给定字段结束的数据
select fieldName from measurementName where fieldName=~/给定字段$/
③.实现查询包含给定字段数据
select fieldName from measurementName where fieldName=~/给定字段/
上一篇: java注释是什么?
下一篇: PHP如何随机读取数据库一条记录?