TDengine的数据建模?库、表、超级表是什么?怎么用?
欢迎来到物联网的数据世界
在典型的物联网场景中,一般有多种不同类型的采集设备,采集多种不同的物理量,同一种采集设备类型,往往有多个设备分布在不同的地点,系统需对各种采集的数据汇总,进行计算和分析对于同一类设备,其采集的数据都是很规则的。
本文我们以智能电表(采集量为电流、电压)为例,探讨如何在TDengine中建库、建超级表、建表。
假设每个智能电表采集电流、电压两个量,其采集的数据如下图所示。
每一条记录都有设备ID,时间戳,采集的物理量(如上图中的电流、电压),还有与每个设备相关的静态标签(如上图中的位置Location和分组groupId)。每个设备是受外界的触发,或按照设定的周期采集数据。采集的数据点是时序的,是一个数据流。
那么TDengine如何抽象这些物联网数据呢?
这里,需要提到TDengine的关键创新点——一个采集点一张表。同一类型的采集点用一个超级表来描述,也就是一个表结构Schema和静态标签Schema 。就上图来说,电表ID作为子表名(d1001, d1002, d1003, d1004等),动态采集的物理量作为各字段,静态属性(Location和groupId)作为子表标签。利用超级表作为模板,生成子表 – 对应各采集点,有了超级表,极大地方便了同类采集点的数据检索、查询、聚合。
这种设计有几大优点:
- 能保证一个采集点的数据在存储介质上是以块为单位连续存储的。如果读取一个时间段的数据,它能大幅减少随机读取操作,成数量级的提升读取和查询速度。
- 由于不同采集设备产生数据的过程完全独立,每个设备的数据源是唯一的,一张表也就只有一个写入者,这样就可采用无锁方式来写,写入速度就能大幅提升。
- 对于一个数据采集点而言,其产生的数据是时序的,因此写的操作可用追加的方式实现,进一步大幅提高数据写入速度。
如果采用传统的方式,将多个设备的数据写入一张表,由于网络延时不可控,不同设备的数据到达服务器的时序是无法保证的,写入操作是要有锁保护的,而且一个设备的数据是难以保证连续存储在一起的。采用一个数据采集点一张表的方式,能最大程度的保证单个数据采集点的插入和查询的性能是最优的。
数据建模的基本方法
TDengine采用关系型数据模型,需要建库、建表。因此对于一个具体的应用场景,需要考虑库的设计,超级表和普通表的设计。
CREATE DATABASE dbname
USE dbname
CREATE TABLE stbname (ts timestamp, other fields…) tags ( tag fields)
CREATE TABLE tbname using stbname tags(具体标签值)
INSERT INTO tbname VALUES(now, values…)
实例
INSERT INTO ${tableName} USING xm_values (groupId) TAGS (2)
VALUES
<foreach collection="paramList" item="param" separator=",">
(
#{param.time_new},
#{param.stid},
null,
#{param.value},
#{param.sblx},
#{param.time},
#{param.homeRoom},
#{param.friendlyName}
)
</foreach>
创建库
不同类型的数据采集点往往具有不同的数据特征,包括数据采集频率的高低,数据保留时间的长短,副本的数目,数据块的大小等。为让各种场景下TDengine都能最大效率的工作,建议将不同数据特征的表创建在不同的库里,因为每个库可以配置不同的存储策略。
创建一个库时,除SQL标准的选项外,应用还可以指定保留时长、副本数、内存块个数、时间精度、文件块里最大最小记录条数、是否压缩、一个数据文件覆盖的天数等多种参数。比如建议为数据特征相同的表创建一个库,每个库可以配置不同的存储策略。
CREATE DATABASE power KEEP 365;
上述将创建一个名为power的库,这个库的数据将保留365天。更多参数及语法见:
https://www.taosdata.com/cn/documentation20/taos-sql/
创建库之后,需要使用SQL命令USE将当前库切换过来,例如:
USE power;
将当前操作库换为power。还可使用“库名.表名”来指定操作的库、表的名字。
引入超级表
一个数据采集点一张表, 意味着1000万智能电表对应1000万张表,一个物联网系统,往往存在海量同类型的数据采集点。如何对这么多张表进行操作就是一个巨大的挑战。为方便对同类型多表的操作,TDengine引入超级表。
创建超级表时,需提供:表名、表结构Schema、标签Schema。
CREATE TABLE meters (ts timestamp, current float, voltage int) TAGS (location binary(64), groupdId int);
超级表的列分两部分:动态部分,静态部分。
动态部分是采集的数据,第一列为时间戳(ts),其他列为采集的物理量(current, voltage)。
静态部分指采集点的静态属性,一般作为标签。如采集点的地理位置、设备型号、设备组、管理员ID等。
标签可以事后增加、删除、修改。
TDengine支持以下数据类型。
深入理解超级表
同时采集同表:一张超级表里,包含的采集物理量必须是同时采集的,也就是说时间戳都是相同的。
对一个类型的设备,可能存在多组物理量,每组物理量并不是同时采集的,则需要为每组物理量单独建一个超级表。因此一个类型的设备,可能需要建立多个超级表。
系统有N个不同类型的设备,就需要建立至少N个超级表。
一个系统可以有多个DB库,一个DB库里可以有一到多个超级表。
创建表/子表
TDengine对每个数据采集点需要独立建表;因为源于超级表(meters)创建而成,也称子表(d1001);创建时,需要使用超级表做模板,同时指定标签的具体值;一个超级表,可包含若干子表,子表数量没有限制。
CREATE TABLE d1001 USING meters TAGS ("Beijing.Chaoyang", 2);
d1001是子表名,meters是超级表名,紧跟Location的标签值”Beijing.Chaoyang",groupId的标签值2。在创建表/子表时,需指定标签值,事后也可修改;建议将数据采集点的全局唯一ID作为子表名(如设备序列号)。
子表自动建表
在某些特殊场景中,用户在写数据时,并不确定某个子表是否存在。此时,可使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表
INSERT INTO d1001 USING meters TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 219);
上述SQL语句将记录(now, 10.2, 219) 插入进表d1001,如果表d1001还未创建,则使用超级表meters做模板自动创建,同时打上标签值“Beijing.Chaoyang", 2。
多列模型 vs 单列模型
TDengine既支持多列模型,也支持单列模型。
多列模型:只要物理量是同一数据采集点同时采集的,这些量就可以作为不同列放在一张超级表里。
单列模型:每个物理量都单独建表。比如电流、电压两个量,就建两张超级表。
我们建议:尽可能采用多列模型,因为插入效率以及存储效率更高;对于有些场景,一个采集点的物理量的种类经常变化,这时可采用单列模型。
新能源汽车示例
场景及建模分析
- 某车企拟对其生产、销售的新能源汽车进行追踪分析;
- 每辆车配置了远程采集终端,采集车辆状态信息:位置(经纬度)、车速、电池温度、电池电流、环境温度、轮胎胎压;
- 后台统计分析需要按:车型、销售区域、销售员、电池包容量、电机功率进行分类聚合;
- 6个采集量中前4个为同时采集,将其放入一张超级表 – vehicle_main, 其余2个测点,温度与胎压采集的频率完全不一样,分别创建2个超级表 – vehicle_temp, vehicle_tire;
- 每辆车有唯一编码VIN,采用该编码与超级表的表名前缀作为唯一表名。
SQL语句示例
CREATE DATABASE nev KEEP 3650;
USE nev;
CREATE TABLE vehicle_main (ts timestamp, longitude double, latitude double, vspeed int, btemp int, bcurrent int) TAGS (vin binary(30), model binary(20), szone binary(30), sales int, bcapacity float, mpower float);
CREATE TABLE vmTS8392EGV062192009 USING vehicle_main TAGS ("TS8392EGV062192009", "GTS7180", "Beijing.haidian", "10060089", 86.0, 125.5);
CREATE TABLE vehicle_temp (ts timestamp, vtemp int) TAGS (vin binary(30));
CREATE TABLE vtpTS8392EGV062192009 USING vehicle_vtemp TAGS ("TS8392EGV062192009");
CREATE TABLE vehicle_tire (ts timestamp, vpressure int) TAGS (vin binary(30));
CREATE TABLE vtrTS8392EGV062192009 USING vehicle_vtire TAGS ("TS8392EGV062192009"); //查询指定车辆最近10天的运行轨迹
SELECT ts, longtitude, latitude FROM vtrTS8392EGV062192009 where ts >now -10d //按车型查询平均车速、平均动力电池温度、平均放电电流
SELECT AVG(vspeed), AVG(btemp), AVG(bcurrent) FROM vehicle_main GROUP BY model
TDengine的数据建模?库、表、超级表是什么?怎么用?的更多相关文章
- dython:Python数据建模宝藏库
尽管已经有了scikit-learn.statsmodels.seaborn等非常优秀的数据建模库,但实际数据分析过程中常用到的一些功能场景仍然需要编写数十行以上的代码才能实现. 而今天要给大家推荐的 ...
- MySQL(一) -- MySQL学习路线、数据库的基础、关系型数据库、关键字说明、SQL、MySQL数据库、MySQL服务器对象、SQL的基本操作、库操作、表操作、数据操作、中文数据问题、 校对集问题、web乱码问题
1 MySQL学习路线 基础阶段:MySQL数据库的基本操作(增删改查),以及一些高级操作(视图.触发器.函数.存储过程等). 优化阶段:如何提高数据库的效率,如索引,分表等. 部署阶段:如何搭建真实 ...
- MySQL库操作,表操作,数据操作。
数据库服务器:本质就是一台计算机,该计算机上安装有数据库管理软件的服务端,供客户端访问使用. 1数据库管理系统RDBMS(本质就是一个C/S架构的套接字),关系型数据库管理系统. 库:(文件夹)- ...
- oracle 两个网络不通的远程数据库如何将一个库中的表数据导入到另一个库中?
1.情景展示 本地可以直接连接2个不同的远程数据库: 两个数据库由于网络不通,无法建立DBLINK完成数据传输: 将A库中C表的数据插入到B库中C表,如何快速实现? 2.解决方案 通过kettle ...
- MySQL常见的库操作,表操作,数据操作集锦及一些注意事项
一 库操作(文件夹) 1 数据库命名规则 可以由字母.数字.下划线.@.#.$ 区分大小写 唯一性 不能使用关键字如 create select 不能单独使用数字 最长128位 2 数据库相关操作 创 ...
- 第一百五十九节,封装库--JavaScript,表单序列化结合ajax提交数据
封装库--JavaScript,表单序列化结合ajax提交数据 封装库,表单序列化方法 /** xu_lie_biao_dan()方法,表单序列化方法,将自动获取指定表单里面的各项字段name值和va ...
- MySQl的库操作、表操作和数据操作
一.库操作 1.1库的增删改查 (1)系统数据库: performance_schema:用来收集数据库服务器的性能参数,记录处理查询时发生的各种事件.锁等现象 mysql:授权库,主要存储系统用户的 ...
- (六)MySQL数据、库、表的管理
目录 数据的管理 库的管理 表的管理 数据的管理 一.数据插入语句 1.语法: INSERT INTO 表名(列名,...) VALUES(值1,...); 2.案例:在beauty表中添加一条信息( ...
- Oracle 查询库中所有表名、字段名、字段名说明,查询表的数据条数、表名、中文表名、
查询所有表名:select t.table_name from user_tables t;查询所有字段名:select t.column_name from user_col_comments t; ...
随机推荐
- 第十八天python3 序列化和反序列化
思考: 内存中的字典.列表.集合以及各种对象,如何保存到一个文件中? 如果是自己定义的类的实例,如何保存到一个文件中? 如何从文件中读取数据,并让它们在内存中再次变成自己对应的类的实例? 要设计一套协 ...
- OpenSSF的开源软件风险评估工具:Scorecards
对于IT从业者来说,Marc Andreessen 十年前提出"软件吞噬世界"的观点早已耳熟能详.无论是私人生活还是公共领域,软件为现代社会的方方面面提供动力,对现代经济和国家安全 ...
- 基于UiAutomator2+PageObject模式开展APP自动化测试实战
前言 在上一篇<APP自动化测试框架-UiAutomator2基础>中,重点介绍了uiautomator2的项目组成.运行原理.环境搭建及元素定位等基础入门知识,本篇将介绍如何基于uiau ...
- 长篇图解java反射机制及其应用场景
一.什么是java反射? 在java的面向对象编程过程中,通常我们需要先知道一个Class类,然后new 类名()方式来获取该类的对象.也就是说我们需要在写代码的时候(编译期或者编译期之前)就知道我们 ...
- mongo数据库-mongo角色权限
Built-In Roles(内置角色): 1. 数据库用户角色:read.readWrite; 2. 数据库管理角色:dbAdmin.dbOwner.userAdmin: 3. 集群管理角色:clu ...
- rcu stall 导致的hung 记录
synchronize_sched 也会在wait_rcu_gp 的长时间等待导致进入hung ,假设rcu没有及时执行的话, 另外,如果rcu积累到一定程度,内存自然就不足了,可能会oom. rcu ...
- NOI2022游记,Au
前言 8.19: 说实话,我在这里说几句话还不如水群, 新番把我心态搞炸了,我现在急需快乐 所以像游记这种吹水+回忆的文章让我现在非常痛苦. Day -1 (8.19) 上午是信心赛,太好辣,坐等D3 ...
- ABC206 F - Interval Game 2 (区间DP,博弈论,SG函数)
题面 题意很简单 A l i c e \tt Alice Alice 和 B o b \tt Bob Bob 在博弈.摆在他们面前有 N \rm N N 个区间 [ l i , r i ) \rm[l ...
- 修改窗体的Title
直接上代码 /// <summary> /// 获取窗体的名称 /// </summary> /// <param name="hWnd">&l ...
- QtCreator像C# region一样折叠代码
C# #region "comment" [code] #endregion 就可以在VS中实现代码折叠了 QtCreator #pragma region "comme ...