Tdengine的时序数据库简介、单机部署、操作语句及java应用

Tdengine的时序数据库简介、单机部署、操作语句及java应用

     本文介绍了Tdengine的功能特点、应用场景、超级表和子表等概念,讲述了Tdengine2.6.0.34的单机部署,并介绍了taos数据库的常见使用方法及特色窗口查询方法,最后介绍了在java中的应用。

一、tdengine简要介绍及应用场景

1、简要介绍

TDengine是涛思数据专为物联网、车联网、工业互联网、IT运维等设计和优化的大数据平台是一款优秀的时序数据库

2、应用场景

  • 公共安全:上网记录、通话记录、个体追踪、区间筛选
  • 电力行业:智能电表、电网、发电设备的集中监测
  • 通讯行业:话费详单、用户行为、基站/通讯设备监测
  • 金融行业:交易记录、存取记录、ATM、POS 机监测
  • 出行工具:火车/汽车/出租/飞机/自行车的实时监测
  • 交通行业:实时路况,路口流量监测,卡口数据;
  • 石油石化:油井、运输管线、运输车队的实时监测
  • 互联网: 服务器/应用监测、用户访问日志、广告点击日志
  • 物流行业:车辆、集装箱的追踪监测
  • 环境监测:天气、空气、水文、地质环境等监测;
  • 物联网: 电梯、锅炉、机械、水表、气表等各种联网设备
  • 军工行业:各种军事装备的数据采集、存储
  • 制造业: 生产过程管控,流程数据、供应链数据采集与分析

  如果采用传统的方式,将多个设备的数据写入一张表,由于网络延时不可控,不同设备的数据到达服务器的时序是无法保证的,写入操作是要有锁保护的,而且一个设备的数据是难以保证连续存储在一起的。采用一个数据采集点一张表的方式,能最大程度的保证单个数据采集点的插入和查询的性能是最优的。

二、tdengine功能特点

1、相比mysql可以查询快10倍以上

2、提供缓存、数据订阅、流式计算等功能

3、提供了独有的按时间自动划分窗口并执行查询的能力

4、自动按照时间戳建立索引,但对采集的物理量不建任何索引。数据用列式存储方式保存。

三、tdengine技术概念(超级表和子表)

        1、引入超级表和子表概念,并提供窗口查询。taos数据库常用于具有时序的大量数据存储,能够快速查询并定时清除历史数据。诸如能源系统的电表、水表、气表等,通过mqtt采集后的实时数据,存储在tdengine中,对于每一类的采集设备或者采集数据,有着相似的数据结构,便建立“超级表”定义表结构,设置tags标签用于建立,超级表下的子表,通常每一个上报数据的设备建立一个子表。

        超级表有效用于聚合查询等数据分析,子表用于单设备节点的实时数据分析,超级表和子表的查询有连接的地方。

       2、 超级表是指某一特定类型的数据采集点的集合。同一类型的数据采集点,其表的结构是完全一样的,但每个表(数据采集点)的静态属性(标签)是不一样的。

        能源管理系统中数据量最大的就是各个智能抄表、传感器上报的数据。这些智能抄表的上报数据要进行长期记录,并定期查询、统计生成报表;在系统中,也需要在用户点击查看具体设备时,显示出该设备的实时读数以及历史变化曲线等。

        随着公司业务的不断扩大,所有客户的数据我们还需要一个总的平台来监测存储,传统的关系型数据库已经不足以支撑业务量,因此针对抄表数据时序结构化的特点选择合适的数据库变得非常重要。 

        子表用来代表一个具体的数据采集点,超级表用来代表一组相同类型的数据采集点集合

四、单机版tdengine部署

1、下载TDengine离线rpm安装包

​
wget https://www.taosdata.com/assets-download/TDengine-server-2.6.0.34-Linux-x64.rpm​

2、安装离线包

sudo yum install TDengine-server-2.6.0.34-Linux-x64.rpm –y

3、启动tdengine

sudo systemctl start taosdsystemctl start taosadapter

taos

alter user root pass 'admin123';

五、tdengine创建

1、创建数据库

#命令行执行,登陆taos数据库

taos

# 创建数据库ems

create database if not exists ems;

# 查看所有的数据库

show databases;

# 切换到数据库ems

use ems;

2、超级表和子表的结构与表名设计

超级表为某一类的数据结构,相当于表结构声明;子表为单节点的数据表,继承超级表的表结构,tag标签用于区分该类设备/数据的单节点。在java应用中,为便于查询,常将部分tag标签用于组建子表名。

    如下设计为电表的表结构,electric_meter_ui为超级表,通过定义标签location和sn创建子表,并将tag标签用于子表的命名。

超级表:electric_meter_ui

ts

Ua

Ub

Uc

typestatues

子表:electric_meter_ui_${location}${sn}

ts

Ua

Ub

Uc

typestatues

location

sn

(tag)

(tag)

3、超级表创建和结构修改

(1)超级表创建

# 创建超级表

CREATE STABLE `electric_data` (`ts`  TIMESTAMP,  `Ua` FLOAT , `Ub` FLOAT , `Uc`  FLOAT ) TAGS ( `location` NCHAR(100), `sn` NCHAR(100));

# 查看超级表

show stables;

# 查看超级表结构

DESCRIBE electric_data;

2)超级表结构修改-列删除
ALTER TABLE electric_data DROP COLUMN typestatues;
(3)超级表结构修改-列增加
ALTER TABLE electric_data ADD COLUMN typestatues INT;
(4)超级表结构修改-列修改
ALTER TABLE electric_data MODIFY COLUMN typestatues INT;

4、子表创建和数据新增

(1)子表创建

# 创建子表

create table electric_data_beijing_SN001 using electric_data tags("beijing",'SN001');create table electric_data_beijing_SN002 using electric_data tags("beijing",'SN002');create table electric_data_jinan_SN002 using electric_data tags("jinan",'SN002');create table electric_data_shenzhen_SN005 using electric_data tags("shenzhen",'SN005');

# 查看子表结构

DESCRIBE electric_data_shenzhen_SN005;
(2)新增数据
taos> INSERT INTO electric_data_beijing_SN001 VALUES ('2024-06-08 00:05:12.272', 10.2, 200, 1);Query OK, 1 row(s) affected (0.000859s)taos> INSERT INTO electric_data_beijing_SN001 VALUES ('2024-06-08 01:05:12.272', 20.2, 210, 2);Query OK, 1 row(s) affected (0.000272s)taos> INSERT INTO electric_data_beijing_SN001 VALUES ('2024-06-08 02:05:12.272', 10.2, 220, 3);Query OK, 1 row(s) affected (0.000233s)taos> INSERT INTO electric_data_beijing_SN001 VALUES ('2024-06-08 03:05:12.272', 20.2, 200, 2);Query OK, 1 row(s) affected (0.000385s)taos> INSERT INTO electric_data_jinan_SN002 VALUES ('2024-06-08 12:04:12.272', 10.2, 200, 1);Query OK, 1 row(s) affected (0.000696s)taos> INSERT INTO electric_data_jinan_SN002 VALUES ('2024-06-08 13:05:12.272', 20.2, 210, 2);Query OK, 1 row(s) affected (0.000346s)taos> INSERT INTO electric_data_jinan_SN002 VALUES ('2024-06-08 14:05:12.272', 10.2, 220, 3);Query OK, 1 row(s) affected (0.000305s)taos> INSERT INTO electric_data_jinan_SN002 VALUES ('2024-06-08 15:05:12.272', 20.2, 200, 2);Query OK, 1 row(s) affected (0.000299s)taos> INSERT INTO electric_data_shenzhen_SN005 VALUES ('2024-06-08 15:09:12.272', 20.2, 200, 2);Query OK, 1 row(s) affected (0.000327s)taos> create table electric_data_beijing_SN002 using electric_data tags("beijing",'SN002');Query OK, 0 row(s) affected (0.004323s)taos> INSERT INTO electric_data_shenzhen_SN005 VALUES ('2024-06-08 15:09:12.272', 20.2, 200, 2);Query OK, 1 row(s) affected (0.000352s)

(3)子表删除
drop table electric_data_beijing_SN001;

六、查询操作

主要示例数据:

INSERT INTO electric_data_beijing_SN001 VALUES ('2024-06-08 00:05:12.272', 10.2, 200, 1,1);INSERT INTO electric_data_beijing_SN001 VALUES ('2024-06-08 01:05:12.272', 20.2, 210, 2,1);INSERT INTO electric_data_beijing_SN001 VALUES ('2024-06-08 02:05:12.272', 10.2, 220, 3,1);INSERT INTO electric_data_beijing_SN001 VALUES ('2024-06-08 03:05:12.272', 20.2, 200, 2,0);INSERT INTO electric_data_beijing_SN001 VALUES ('2024-06-08 03:31:12.272', 20.2, 210, 2,0);INSERT INTO electric_data_beijing_SN001 VALUES ('2024-06-08 05:05:12.272', 10.2, 200, 3,1);INSERT INTO electric_data_beijing_SN001 VALUES ('2024-06-08 05:55:12.272', 10.2, 220, 3,1);INSERT INTO electric_data_beijing_SN001 VALUES ('2024-06-08 06:55:12.272', 10.2, 210, 3,0);

 1、过滤查询

select count(*) from  `ems`.`electric_data` where `location` = 'beijing' ;

超级表的筛选条件可以是静态字段或者tag, 当筛选条件为所有tag时,等同于查询对应的子表,如下两个查询语句有相同结果:

select count(*) from  `ems`.`electric_data` where `location` = 'beijing' and `sn` = '001';select COUNT(*) from  electric_data_beijing_SN001;

2、聚合查询

直接对超级表聚合查询<==>子表数据聚合查询

SELECT AVG(`Ua`), `location` FROM `ems`.`electric_data` GROUP BY `location`;

3、时间窗口查询(interval)

时间窗口通过对数据按时间顺序划分切割,实现数据的降采样,在时间窗口内的数据可以avg/max/min等聚合运算或时长计算,并提供了滑动窗口sliding以及自动填充方案FILL。

(1)interval等时间间隔窗口

如下是等时间间隔窗口示意图,未声明滑动窗口,则滑动窗口sliding=interval,时间窗口数据无重叠:

(2)sliding 滑动窗口

如下是等时间间隔窗口示意图,声明滑动窗口,则滑动窗口sliding<interval,时间窗口数据有重叠[t0s-t0e]和[t1s-t1e]:

(3)fill填充

FILL 语句指定某一窗口区间数据缺失的情况下的填充模式。填充模式包括以下几种:

不进行填充:NONE(默认填充模式)。

VALUE 填充:固定值填充,此时需要指定填充的数值。例如:FILL(VALUE, 1.23)。

PREV 填充:使用前一个非 NULL 值填充数据。例如:FILL(PREV)。

NULL 填充:使用 NULL 填充数据。例如:FILL(NULL)。

LINEAR 填充:根据前后距离最近的非 NULL 值做线性插值填充。例如:FILL(LINEAR)。

NEXT 填充:使用下一个非 NULL 值填充数据。例如:FILL(NEXT)。

(4)示例1(无滑动窗口)

# 从2024-06-08 00:00:00.000开始,每间隔1h的Ub平均值,如果区间的1h没数据,使用前一个非 NULL 值填充。

#查询结果有24条

SELECT avg(`Ub`) as Ub FROM electric_data_beijing_SN001 where  `ts` > '2024-06-08 00:00:00.000' and `ts` < '2024-06-09 00:00:00.000' interval(1h)

(5)示例2(有滑动窗口)

# 从2024-06-08 00:00:00.000开始,每间隔30min, 时长区间未1h的Ub平均值,如果区间的1h没数据,使用前一个非 NULL 值填充。

#查询结果有49条

SELECT avg(`Ub`) as Ub FROM electric_data_beijing_SN001 where  `ts` > '2024-06-08 00:00:00.000' and `ts` < '2024-06-09 00:00:00.000' interval(1h) sliding(30m) FILL(PREV);

4、状态窗口查询(state_window)

状态窗口让用户可以按照某个整型/字符串型的采集量(一般是表征状态的值,如设备工作模式等)的值来划分窗口,将该状态值连续不变的记录划入同一个窗口。然后对每个窗口内的采集值进行avg/max/min等统计聚合、或计算状态持续时间等。

(1)示例1 state_window

# typestatues连续不变的总共有4段,划分四个窗口,对窗口内的数据计算记录条数和持续时长。

select first(`ts`) as ts, `typestatues` as status,count(*) as record_count,spread(`ts`)/1000 as "duration(s)" from electric_data_beijing_SN001 where  `ts` > '2024-06-08 00:00:00.000' and `ts` <'2024-06-09 00:00:00.000' state_window(`typestatues`);

5、会话窗口查询(session)

会话窗口让用户可以按照上报记录的时间连续性来划分窗口,即相邻两条记录时间间隔不超过某一阈值,则划归同一窗口;超过该阈值,则老窗口结束,新窗口开始;然后对每个窗口进行诸如持续时间等统计,或对窗口内的原始采集数据进行各种聚合计算,可以是 avg/max/min/count 或其他用户自定义函数。

用于物联网中,上设备连续上报数据时表名在线,如果间隔时间过长,表明不在线,我们对数据基于间隔时间最大阈值进行划分,更有效的分析数据。

(1)示例1 session

# 上报数据间隔时间超过1h的,作为窗口切分的边缘;

# 结果分为划分为两个窗口,对窗口内的数据计算记录条数和持续时长。

select last(`ts`) as session_endtime, spread(ts)/1000 as 'duration(s)',count(*) as record_count from `ems`.electric_data_beijing_SN001 session(ts,1h);


七、java下的tdengine操作

1、通过HttpUtils网址调用

// 拼接子表表名String sqls = "select last_row(*) from electric_data_".concat(location.toString()).concat("_").concat(sn);
// 查询
JSONObject Json = JSONObject.parseObject(httpUtil.postTDengine(sqls));

Urs = jdbc:TAOS-RS://47.95.215.167:6041/ems

   public String postTDengine(String sqls) {CloseableHttpResponse response = null;BufferedReader in = null;String result = "";try {HttpPost httpPost = new HttpPost(url);RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).setConnectionRequestTimeout(30000).setSocketTimeout(30000).build();httpPost.setConfig(requestConfig);httpPost.setConfig(requestConfig);httpPost.addHeader("Content-type", "text/plain; charset=utf-8");httpPost.addHeader("Authorization", "Basic " + authorizationToken);httpPost.setHeader("Accept", "*/*");httpPost.setEntity(new StringEntity(sqls, Charset.forName("UTF-8")));response = httpClient.execute(httpPost);in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));StringBuffer sb = new StringBuffer();String line = "";String NL = System.getProperty("line.separator");while ((line = in.readLine()) != null) {sb.append(line + NL);}in.close();result = sb.toString();} catch (IOException e) {e.printStackTrace();} finally {try {if (null != response) {response.close();}} catch (IOException e) {e.printStackTrace();}}return result;}

2、通过mapper接口层调用

<dependency><groupId>com.taosdata.jdbc</groupId><artifactId>taos-jdbcdriver</artifactId><version>3.0.4</version>
</dependency>

username: root
password: taosdata
url: jdbc:TAOS-RS://47.95.215.167:6041/ems
driver-class-name: com.taosdata.jdbc.rs.RestfulDriver

主要参考网站

按窗口切分聚合 | TDengine 文档 | 涛思数据

https://www.sohu.com/a/602180065_121276745

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/26050.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【差分数组】1674. 使数组互补的最少操作次数

本文涉及知识点 差分数组 LeetCode1674. 使数组互补的最少操作次数 给你一个长度为 偶数 n 的整数数组 nums 和一个整数 limit 。每一次操作&#xff0c;你可以将 nums 中的任何整数替换为 1 到 limit 之间的另一个整数。 如果对于所有下标 i&#xff08;下标从 0 开始&…

详解 Flink 的容错机制

一、检查点 Checkpoint 1. 介绍 有状态流应用中的检查点&#xff08;checkpoint&#xff09;&#xff0c;其实就是所有任务的状态在某个时间点的一个快照&#xff08;一份拷贝&#xff09;&#xff0c;这个时间点应该是所有任务都恰好处理完一个相同的输入数据的时刻。在一个流…

C++ | Leetcode C++题解之第144题二叉树的前序遍历

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> preorderTraversal(TreeNode *root) {vector<int> res;if (root nullptr) {return res;}TreeNode *p1 root, *p2 nullptr;while (p1 ! nullptr) {p2 p1->left;if (p2 ! nullptr) {…

linux centos如何安装python3版本但不能影响默认python2版本

在CentOS上安装Python3而不影响系统默认的Python2,具有如何安装呢? 1. 更新系统包 首先,确保系统包是最新的: sudo yum update -y2. 安装EPEL存储库 EPEL(Extra Packages for Enterprise Linux)存储库包含许多额外的软件包,包括Python3: sudo yum install epel-rel…

MATLAB基础应用精讲-【数模应用】二元Logit分析

目录 算法原理 数学模型 极大似然法 Newton牛顿迭代法 logit回归分析步骤 一、二元logit分析 1.基本说明 2.数据处理 3.SPSSAU上传数据 4.分析前提示 5.SPSSAU分析 6.其它说明 二、多分类logit分析 1.基本说明 2.数据要求与处理 3.SPSSAU上传数据 4.SPSSAU分析…

QT获取最小化,最大化,关闭窗口事件

QT获取最小化&#xff0c;最大化&#xff0c;关闭窗口事件 主程序头文件&#xff1a; 实现&#xff1a; changeEvent&#xff0c;状态改变事件 closeEvent触发点击窗口关闭按钮事件 其代码它参考&#xff1a; /*重写该函数*/ void MainWindow::changeEvent(QEvent *event) {…

计算机毕业设计hadoop+spark+hive舆情分析系统 微博数据分析可视化大屏 微博情感分析 微博爬虫 微博大数据 微博推荐系统 微博预测系统

本 科 毕 业 论 文 论文题目&#xff1a;基于Hadoop的热点舆情数据分析与可视化 姓名&#xff1a; 金泓羽 学号&#xff1a; 20200804050115 导师&#xff1a; 关英 职称&…

matlab演示银河系转动动画

代码 function GalaxyRotationSimulation()% 参数设置num_stars 1000; % 恒星数量galaxy_radius 1; % 银河系半径rotation_speed 0.05; % 旋转速度% 生成银河系中的恒星分布theta 2 * pi * rand(num_stars, 1); % 角度r galaxy_radius * sqrt(rand(num_stars, 1)); % 半径…

XUbuntu24.04之制作ISO镜像启动盘(二百四十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

【html】如何利用HTML+CSS制作自己的印章

大家有没有尝试过用HTML和CSS制作自己的印章. 首先印章具有两个最基本的特点就是它是圆形的并且有边框 当然它还有一些其他的属性吗&#xff0c;废话不多说我们直接上源码&#xff1a; 效果图&#xff1a; 源码&#xff1a; html&#xff1a; <!DOCTYPE html> <h…

51单片机STC89C52RC——1.1点亮一个LED

目录 STC单片机模块 LED模块 创建Keil项目 代码 效果 STC单片机模块 我们程序中要点亮的LED灯的位置如下图。 我们程序要用到的针脚如下图 LED模块 电路图如下 8个LED&#xff0c;全部点亮 每一bit位 都需要设置为0 二进制是0000 0000 。如果只点亮D1一个&#xff…

Docker高级篇之Docker-compose容器编排

文章目录 1. Docker-compse介绍2. Docker-compse下载3. Docker-compse核心概念4. Docker-compse使用案例 1. Docker-compse介绍 Docker-compose时Docker官方的一个开源的项目&#xff0c;负责对Docker容器集群的快速编排。Docker-compose可以管理多个Docker容器组成一个应用&a…

Golang:使用时会遇到的错误及解决方法详解

Go语言使用时常常会遇到的一些错误及解决方法&#xff0c;文中的示例代码讲解详细&#xff0c;感兴趣的小伙伴可以了解一下 1、go: go.mod file not found in current directory or any parent directory go mod init name 2、Failed to build the application: main.go:4:2:…

【深度学习驱动流体力学】Python流体力学Ansys Fluent

1、PyFluent&#xff1a;Python Ansys Fluent 的结合 PyFluent 是一个将 Python 编程语言与 Ansys Fluent 流体动力学 (CFD) 仿真软件集成的工具。它允许用户通过 Python 脚本来控制和自动化 Fluent 中的仿真任务&#xff0c;实现从预处理、求解到后处理的全流程控制。PyFlue…

字符串拼接之char实现

目录 一、前言 二、memcpy函数用法 三、代码实现 一、前言 c中想到字符串拼接&#xff0c;我们都知道可以用c库中std::string的字符串中的简单加法进行拼接。示例&#xff1a; int main() {std::string str1 "hello";std::string str2 "World";std::…

差动放大器

差动器的出现是为了解决直接耦合电路存在的零点漂移问题&#xff0c;另外&#xff0c;差动放大器还有灵活的输入&#xff0c;输出方式。 一&#xff0c;基本差动放大器 差动放大器在电路结构上具有对称性&#xff0c;三极管VT1&#xff0c;VT2同型号&#xff0c;R1R2,R3R4,R5…

每天写java到期末考试(6.10)--java小项目01

实现项目任务 java类 package java1;import java.util.ArrayList; import java.util.Scanner;public class Test {public static void main(String[] args) {//8.创建一个集合&#xff0c;用于存放相同个体&#xff0c;一个个添加&#xff0c;注意作用范围&#xff0c;将数组放…

Java从入门到放弃

线程池的主要作用 线程池的设计主要是为了管理线程&#xff0c;为了让用户不需要再关系线程的创建和销毁&#xff0c;只需要使用线程池中的线程即可。 同时线程池的出现也为性能的提升做出了很多贡献&#xff1a; 降低了资源的消耗&#xff1a;不会频繁的创建、销毁线程&…

LeetCode 算法:缺失的第一个正数c++

原题链接&#x1f517;&#xff1a;缺失的第一个正数 难度&#xff1a;困难⭐️⭐️⭐️ 题目 给你一个未排序的整数数组 nums &#xff0c;请你找出其中没有出现的最小的正整数。 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。 示例 1&#xff1a; 输…

域内攻击 ----> DCSync

其实严格意义上来说DCSync这个技术&#xff0c;并不是一种横向得技术&#xff0c;而是更偏向于权限维持吧&#xff01; 但是其实也是可以用来横向&#xff08;配合NTLM Realy&#xff09;&#xff0c;如果不牵强说得话&#xff01; 那么下面&#xff0c;我们就来看看这个DCSyn…