TDengine使用文档

Posted henry19971211

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TDengine使用文档相关的知识,希望对你有一定的参考价值。

TDengine使用文档

版本号时间更新内容作者
1.02023.02.27初次提交韩立楠

官网地址

数据模型和基本概念

采集量

采集量是指传感器、设备或其他类型采集点采集的物理量,比如电流、电压、温度、压力、GPS 位置等,是随时间变化的(硬件设备采集的参数和数据)

标签

标签是指传感器、设备或其他类型采集点的静态属性,不是随时间变化的,比如设备型号、颜色、设备的所在地等

数据采集点

数据采集点是指按照预设时间周期或受事件触发采集物理量的硬件或软件。一个数据采集点可以采集一个或多个采集量,但这些采集量都是同一时刻采集的,具有相同的时间戳。(硬件设备)

超级表

超级表用来代表一组相同类型的数据采集点集合(一种产品一张超级表,超级表有tag列)

子表

通过超级表创建的表称之为子表(一个设备一张子表,子表没有tag列)

超级表和子表的关系

  1. 一张超级表包含有多张子表,这些子表具有相同的采集量 Schema,但带有不同的标签值。
  2. 不能通过子表调整数据或标签的模式,对于超级表的数据模式修改立即对所有的子表生效。
  3. 超级表只定义一个模板,自身不存储任何数据或标签信息。因此,不能向一个超级表写入数据,只能将数据写入子表中。
  4. 查询既可以在子表上进行,也可以在超级表上进行。

docker安装步骤

拉取镜像(最新镜像为3.0版本)

docker pull tdengine/tdengine:latest

运行容器

docker run -d -p 6030:6030 -p 6041:6041 -p 6043-6049:6043-6049 -p 6043-6049:6043-6049/udp tdengine/tdengine

注:

  1. 默认用户名密码 root taosdata

  2. TDengine 3.0 服务端仅使用 6030 TCP 端口。6041 为 taosAdapter 所使用提供 REST 服务端口。6043-6049 为 taosAdapter 提供第三方应用接入所使用端口,可根据需要选择是否打开。

开发指南

建立连接

  1. 如果选择原生连接,而且应用程序不在 TDengine 同一台服务器上运行,你需要先安装客户端驱动,否则可以跳过此一步。为避免客户端驱动和服务端不兼容,请使用一致的版本

  2. 在 cmd 下进入到 C:\\TDengine 目录下直接执行 taos.exe,连接到 TDengine 服务,进入到 TDengine CLI 界面。执行 show databases; 看到 Query OK 即安装成功。

数据建模

创建数据库

CREATE DATABASE power KEEP 365 DURATION 10 BUFFER 16 WAL_LEVEL 1;
USE power;

注: 上述语句将创建一个名为 power 的库,这个库的数据将保留 365 天(超过 365 天将被自动删除),每 10 天一个数据文件,每个 VNode 的写入内存池的大小为 16 MB,对该数据库入会写 WAL 但不执行 FSYNC。(详细语法参见官网

创建超级表

CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAGS (location binary(64), groupId int);

注: 第一列必须为时间戳(示例中为 ts),其他列为采集的物理量(示例中为 current, voltage, phase)。除此之外,还需要提供标签的 Schema (示例中为 location, groupId)

创建子表

CREATE TABLE d1001 USING meters TAGS ("California.SanFrancisco", 2);

注: 创建时,需要使用超级表做模板,同时指定标签的具体值。

自动建表

INSERT INTO d1001 USING meters TAGS ("California.SanFrancisco", 2) VALUES (NOW, 10.2, 219, 0.32);

写入数据

一次写入一条

INSERT INTO d1001 VALUES (ts1, 10.3, 219, 0.31);

一次写入多条

INSERT INTO d1001 VALUES (ts1, 10.2, 220, 0.23) (ts2, 10.3, 218, 0.25);

一次写入多表

INSERT INTO d1001 VALUES (ts1, 10.3, 219, 0.31) (ts2, 12.6, 218, 0.33) d1002 VALUES (ts3, 12.3, 221, 0.31);

代码示例

pom依赖

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

创建超级表

service层
public void createSuperTable() 
        List<FieldsVo> schemaFields = new ArrayList<>();
        FieldsVo ts = new FieldsVo();
        ts.setFieldName("ts");
        ts.setDataType(DataTypeEnum.TIMESTAMP.getDataType());
        FieldsVo payload = new FieldsVo();
        payload.setFieldName("payload");
        payload.setDataType(DataTypeEnum.NCHAR.getDataType());
        payload.setSize(2000);
        FieldsVo topic = new FieldsVo();
        topic.setFieldName("tp");
        topic.setDataType(DataTypeEnum.NCHAR.getDataType());
        topic.setSize(500);
        FieldsVo func = new FieldsVo();
        func.setFieldName("func");
        func.setDataType(DataTypeEnum.NCHAR.getDataType());
        func.setSize(100);
        FieldsVo channel = new FieldsVo();
        channel.setFieldName("channel");
        channel.setDataType(DataTypeEnum.NCHAR.getDataType());
        channel.setSize(100);
        schemaFields.add(ts);
        schemaFields.add(payload);
        schemaFields.add(topic);
        schemaFields.add(func);
        schemaFields.add(channel);
        List<FieldsVo> tagsFields = new ArrayList<>();
        FieldsVo tag1 = new FieldsVo();
        tag1.setFieldName("channel_code");
        tag1.setDataType(DataTypeEnum.NCHAR.getDataType());
        tag1.setSize(100);
        FieldsVo tag2 = new FieldsVo();
        tag2.setFieldName("product_code");
        tag2.setDataType(DataTypeEnum.NCHAR.getDataType());
        tag2.setSize(100);
        FieldsVo tag3 = new FieldsVo();
        tag3.setFieldName("client_id");
        tag3.setDataType(DataTypeEnum.NCHAR.getDataType());
        tag3.setSize(100);

        tagsFields.add(tag1);
        tagsFields.add(tag2);
        tagsFields.add(tag3);
        tdEngineMapper.createSuperTable(schemaFields,tagsFields,DATABASE_NAME_PREFIX+active,SUPER_TABLE_NAME);
    
mapper层
void createSuperTable(@Param("schemaFields") List<FieldsVo> schemaFields,
                          @Param("tagsFields") List<FieldsVo> tagsFields,
                          @Param("dataBaseName") String dataBaseName,
                          @Param("superTableName") String superTableName);
xml文件

注:$用于替换数据库名称、表名、字段名 (#前后会有单引号,所以不能用#),
#用于替换字段值

<update id="createSuperTable">
        create stable if not exists $dataBaseName.$superTableName
        <foreach item="item" collection="schemaFields" separator=","
                 open="(" close=")" index="">
            <if test="item.fieldName != null || item.fieldName != ''">
                $item.fieldName
            </if>
            <if test="item.dataType != null || item.dataType != ''">
                <choose>
                    <when test="item.dataType == 'timestamp'">
                        timestamp
                    </when>
                    <when test="item.dataType == 'tinyint'">
                        tinyint
                    </when>
                    <when test="item.dataType == 'smallint'">
                        smallint
                    </when>
                    <when test="item.dataType == 'int'">
                        int
                    </when>
                    <when test="item.dataType == 'bigint'">
                        bigint
                    </when>
                    <when test="item.dataType == 'float'">
                        float
                    </when>
                    <when test="item.dataType == 'double'">
                        double
                    </when>
                    <when test="item.dataType == 'binary'">
                        binary
                    </when>
                    <when test="item.dataType == 'nchar'">
                        nchar
                    </when>
                    <when test="item.dataType == 'bool'">
                        bool
                    </when>
                    <when test="item.dataType == 'json'">
                        json
                    </when>
                </choose>
            </if>
            <if test="item.size != null">
                ($item.size)
            </if>
        </foreach>
        tags
        <!--tdEngine不支持动态tags里的数据类型,只能使用choose标签比对-->
        <foreach item="item" collection="tagsFields" separator=","
                 open="(" close=")" index="">
            <if test="item.fieldName != null || item.fieldName != ''">
                $item.fieldName
            </if>
            <if test="item.dataType != null || item.dataType != ''">
                <choose>
                    <when test="item.dataType == 'timestamp'">
                        timestamp
                    </when>
                    <when test="item.dataType == 'tinyint'">
                        tinyint
                    </when>
                    <when test="item.dataType == 'smallint'">
                        smallint
                    </when>
                    <when test="item.dataType == 'int'">
                        int
                    </when>
                    <when test="item.dataType == 'bigint'">
                        bigint
                    </when>
                    <when test="item.dataType == 'float'">
                        float
                    </when>
                    <when test="item.dataType == 'double'">
                        double
                    </when>
                    <when test="item.dataType == 'binary'">
                        binary
                    </when>
                    <when test="item.dataType == 'nchar'">
                        nchar
                    </when>
                    <when test="item.dataType == 'bool'">
                        bool
                    </when>
                    <when test="item.dataType == 'json'">
                        json
                    </when>
                </choose>
            </if>
            <if test="item.size != null">
                ($item.size)
            </if>
        </foreach>
    </update>

创建子表

注:因为自动建表的sql存在,所以不需要提前创建子表

自动建表

注:新增数据也用自动建表的语句,减去了新增前判断子表是否存在的麻烦

service层
public void insertData(String channelCode, String productCode,String clientId, String payload, String topic,String func,String channel) 
        TableDto tableData = new TableDto();

        List<Fields> schemas = new ArrayList<>();
        // ts
        Fields schema1 = new Fields();
        schema1.setFieldName("ts");
        schema1.setFieldValue(TimestampUtils.now());
        schemas.add(schema1);
        // payload
        Fields schema2 = new Fields();
        schema2.setFieldName("payload");
        schema2.setFieldValue(payload);
        schemas.add(schema2);
        // tp
        Fields schema3 = new Fields();
        schema3.setFieldName("tp");
        schema3.setFieldValue(topic);
        schemas.add(schema3);
        // func
        Fields funcF = new Fields();
        funcF.setFieldName("func");
        funcF.setFieldValue(func);
        schemas.add(funcF);
        // channel
        Fields schema4 = new Fields();
        schema4.setFieldName("channel");
        schema4.setFieldValue(channel);
        schemas.add(schema4);
        tableData.setSchemaFieldValues(schemas);

        List<Fields> tags = new ArrayList<>();
        Fields tag1 = new Fields();
        tag1.setFieldValue(channelCode);
        Fields tag2 = new Fields();
        tag2.setFieldValue(productCode);
        Fields tag3 = new Fields();
        tag3.setFieldValue(clientId);
        tags.add(tag1);
        tags.add(tag2);
        tags.add(tag3);
        tableData.setTagsFieldValues(tags);

        tableData.setTableName(StrUtil.format(TABLE_NAME_PREFIX,channelCode,productCode,clientId));
        tableData.setDataBaseName(DATABASE_NAME_PREFIX+active);
        tableData.setSuperTableName(SUPER_TABLE_NAME);

        tdEngineMapper.insertData(tableData);
    
mapper层
void insertData(TableDto tableDto);
xml文件
<insert id="insertData">
        insert into $dataBaseName.$tableName
        <foreach item="item" collection="schemaFieldValues" separator=","
                 open="(" close=")" index="">
            $item.fieldName
        </foreach>
        using $dataBaseName.$superTableName
        tags
        <foreach item="item" collection="tagsFieldValues" separator=","
                 open="(" close=")" index="">
            #item.fieldValue
        </foreach>
        values
        <foreach item="item" collection="schemaFieldValues" separator=","
                 open="(" close=")" index="">
            #item.fieldValue
        </foreach>
    </insert>

以上是关于TDengine使用文档的主要内容,如果未能解决你的问题,请参考以下文章

TDengine的安装使用(超详细)

一篇入门物联网大数据:TDengine时序数据库

CentOS7上使用源码安装物联网大数据平台TDengine

涛思数据TDengine征稿— ❤️ TDengine 的两大技术创新详解❤️ (建议收藏)

一篇入门物联网大数据:TDengine时序数据库

TDengine:开源高效的物联网大数据平台