TDengine有三个模块。一个是客户端模块taosc
。另外两个是服务端模块,一个是管理节点模块MGMT
,一个是数据节点模块DNODE
。客户端模块把请求交给管理节点模块,通过TCP/UDP的方式,在配置文件中通过mgmtShellPort
来配置端口,默认端口是6030
。客户端模块也会和数据节点模块打交道,也通过TCP/UDP的方式,默认端口是6035
。
所有的元数据、存储和查询都会首先和管理节点模块打交道,会有缓存。元数据包括用户、数据库、表。
在数据节点模块中的一个最重要的概念是虚拟节点vnode
.一个库可以有很多vnode
。一个表只会在一个vnode
里,不会跨vnode
存在。在写数据的时候里面有一个预写日志
机制,就是把数据先放在缓存里,如果遇到突然断电的情况也没关系,因为当电力恢复之后缓存的数据还会进入硬盘,专业术语叫做落盘
。落盘有两种方式。一种是时间驱动落盘
,就是每隔一段时间缓存数据就会进入硬盘,默认为1小时,在taos.cfg
中的commitTime
字段配置;另外一种是数据驱动落盘
,当缓存数据达到一定规模数据会进入硬盘,并且刷新日志文件。关键几个配置如下:
数据保存位置:
默认放在了/var/lib/taos/目录中,通过dataDir设置。
数据分片:
默认vnode中表数据按10天切片,通过daysPerFile设置。
保存时间:
默认是3650天,系统自动删除,通过daysToKeep设置。
数据块:
按列存储。
数据文件种类:
-data文件
-head文件
-last文件
最佳实践
now-2h
,a表示毫秒,s表示秒,m表示分钟,h表示小时,d表示天,w表示周,n表示月,y表示年。比如select * from t1 where ts > now-2w and ts <=now-1w
enableMicrosecond
\'
。\'
,nchar(10)表示最多存储10个nchar字符,占用40bytes空间。如果字符串超出声明长度将被自动截断。SQL语句中的英文字符默认不区分大小写,统一自动转换为小写执行。如果有大小写敏感,需要使用单引号把大写字母引用起来。
CREATE DATABASE MYDB
,默认数据库数据保存10年USE MYDB
DROP DATABASE MYDB
SHOW DATABASES
CREATE TABLE tb_name (timestamp_field_name TIMESTAMP, field1_name data_type1)
表的第一个字段必须是TIMESTAMP
类型,系统会自动将其设置为主键。表的每行的长度不能超过托4096个字节。使用数据类型binary或nchar需要制定最长的字节数,比如binary(20)DROP TABLE tb_name
SHOW TABLES
,可以使用like过滤,比如SHOW TABLES LIKE ...
,%匹配0到任意个字符,_表示匹配一个字符DESCRIBE
ALTER TABLE tb_name ADD COLUMN field_name data_type
ALTER TABLE tb_name DROP COLUMN filed_name
注意:
use db_name
操作后操作当前数据库下的表demo.tb1
来表示INSERT INTO tb_name VALUES (field_value, ...)
INSERT INTO tb_name(field1_name,...) VALUES(field1_value)
,语句中没有出现的列,数据库将自动填充为NULLINSERT INTO tb_names VALUES (field1_value1, ...) (field1_value2,...)
INSERT INTO tb_name(field1_name,...) VALUES(field1_value1,...)(field1_value2,...)
INSERT INTO tb1_name VALUES (field1_value1,...)(field1_value2,...)... tb2_name VALUES (field1_value1,...)(field1_value2,...)...
INSERT INTO tb1_name (tb1_field1_name,...) VALUES(field1_value1,...)(field1_value1,...)
tb2_name (tb2_field1_name,...) VALUES(field1_value1,...)(field1_value2,...)
注意:
SELECT {* | expr_list} FROM tb_name
[WHERRE wehre_condition]
[ORDER BY _c0 {DESC | ASC}]
[LIMIT limit, [, OFFSET offset]]
[>> export_file]
SELECT function_list FROM tb_name
[WHERE where_condition]
[LIMIT limit [, OFFSET offset]]
[>> export_file]
_c0
表示首列的时间戳过滤操作:同时使用多个字段过滤需要使用AND
,暂时不支持OR
。针对同一字段的过滤条件必须单一,例如Value>20 and value <30
是合法的,Value<20 AND Value <> 5
是非法的。
>
适用于timestamp 和 numeric types<
适用于timestamp 和 numeric types>=
适用于 timestamp 和 numeric types<=
适用于 timestamp 和 numeric types=
适用于所有类型<>
适用于所有类型%
适用于 binary 和 nchar_
适用于 binary 和 ncharCOUNT
SELECT COUNT([*|field_name]) FROM tb_name [WHERE clause]
返回行数或某列的非空值数量
返回类型为INT64
应用于全部字段,表和超级表
AVG
SELECT AVG(field_name) FROM tb_name [WHERE clause]
返回统计表或超级表中某列的平均值,返回结果类型为double,不能应用在timestamp, binary, nchar, bool字段
WAVG
SELECT WAVG(field_name) FROM tb_name WHERE clause
加权平均,返回sdouble,不能用在timestamp, binary, nchar, bool类型,适用于表和超级表
SUM
SELECT SUM(field_name) FROM tb_name [WHERE clause]
统计表或超级表某列的和,返回double或int64,不能用在timestamp, binary, nchar, bool
STDDEV
SELECT STDDEV(field_name) FROM tb_name [WHERE clause]
统计某列的均方差,返回double,不能用在timestamp, binary, nchar, bool
LEASTSQUARES
SELECT LEASTSQUARES(field_name) FROM tb_name [WHERE clause]
返回表中某列值是主键(时间戳)的拟合直线方程,返回结果是字符串(斜率,截距),不能应用在timestamp, binary, nchar, bool,自变量是时间戳,因变量是该列的值,适用于表
MIN
SELECT MIN(field_name) FROM {tb_name | stb_name} [WHERE clause]
不能用在timestamp, binary, ncahr, bool
MAX
SELECT MAX(field_name) FROM {tb_name | stb_name} [WHERE clause]
FIRST
SELECT FIRST(field_name) FROM {tb_name | stb_name} [WHERE clause]
表或超级表中某列值最先写入的非NULL值,适用于所有字段,各个列FIRST(*),如果结果集中的某列全部为NULL,该列的返回结果也是NULL,如果结果集中所有列全部为NULL值则不返回结果
LAST
SELECT LAST(field_name) FROM {tb_name | stb_name} [WHERE clause]
表或超级表中某列的值最后写入的非NULL值,所有字段,如果返回各个列LAST(*),如果结果集中某列全部为NULL值则该列返回的结果也是NULL,如果结果集中所有列全部为NULL则不返回结果。
TOP
SELECT TOP(field_name, K) FROM {tb_name | stb_name} [WHERE clause]
统计表或超级表中某列的值最大k个非null值,不能用在timestamp, binary, ncahr, bool,k的取值范围在[1,100]
BOTTOM
SELECT BOTTOM(field_name, K) FROM {tb_name | stb_name} [WHERE clause]
PERCENTILE
SELECT PERCENTILE(field_name, P) FROM {tb_name | stb_name} [WHERE clause]
表中某列值的百分比分位数,返回double, 不能用在timestamp, binary, ncahr, bool,k的范围0和100之间,0时候等同于MIN,100的时候等同于MAX
LAST_ROW
SELECT LAST_ROW(field_name) FROM {tb_name | stb_name}
返回表或超级表的最后一条记录,与last函数不同,last_row不支持时间范围限制,强制返回最后一条记录
DIFF
SELECT DIFF(field_name) FROM tb_name [WHERE clause]
统计表中某列的值与前一行对应值的差,不能应用在timestamp, binary, nchar, bool类型
SPREAD
SELECT SPREAD(field_namne) FROM {tb_name | stb_name}[WHERE clause]
统计超级表或表中某列的最大值和最小值之差,返回double,不能用在binary, nchar, bool类型,可用于TIEMSTAMP字段表示记录的时间覆盖范围
四则运算
SELECT field_name [+|-|*|/|%][value | field_name] from {tb_name | stb_name} [WHERE clause]
统计表或超级表中某列或多列的计算,不能用在timestamp, binary, nchar, bool类型,支持两列或多列之间计算,使用括号表示优先级,Null字段不参与计算,如果参与计算的某行中保包含null,改行的结果是Null
CREATE TABLE tb1(ts timestamp, col1 int, col2 float, col3 binary(50))
SELECT * FROM tb1 WHERE ts >= NOW - 1h
SELECT * FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' AND ts <= '2018-06-02 08:00:00.000' AND col3 LIKE `%nny` ORDER BY ts DESC
SELECT (col1 + col2) AS `complex` FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' AND col2 > 1.2 LIMIT 10 OFFSET 5
SELECT COUNT(*) FROM tb1 WHERE ts >= NOW - 10m AND col2 > 3.14 >> /home/testoutpu.csv
按照时间切割再聚合,比如温度传感器每秒采集一次数据,徐查询每隔10分钟温度的平均值。
SELECT function_list FROM tb_name
[WHERE where_condition]
INTERVAL(interval)
[FILL ({None | VALUE | PREV | NULL | LINEAR})]
SELECT function_list FROM stb_name
[WHERE where_condition]
[GTOUP BY tags]
[FILL ({VALUE | PREV | NULL | LINEAR})]
create table sensor(ts timestamp, degree double, pm25 smallint)
SLECT AVG(degree), MAX(degree), LEASTSQUARES(degree), PERCENTILE(degree, 50) FROM sensor
WHERE TS>=now -1d //过去20小时
INTERVAL(10M) //以10分钟为一个阶段
FILL(PREV);
对单个采集点单独建表导致表数量增加,如何对这些表进行聚合、统计呢?引入STable。
什么是超级表STable
create table thermometer (ts timestamp, degree float) tags (location binary(20), type int)
create table t1 using thermometer tags ('beijing', 10)
超级表管理
CREATE TABLE <stable_name> (<field_name> TIMESTAMP, field_name1 field_type,...) TAGS (tag_name tag_type)
,TAGS的总长度不能超过512字节,数据类型不能是timestamp和nchar,不能与其它列名想听,不能为预留关键字show stables;
DROP TABLE <stable_name>
,删除超级表的前提要求先删除所有的子表SELECT TBNAME,[TAG_NAME,…] FROM <stable_name> WHERE <tag_name> <[=|=<|>=|<>] values..> ([AND|OR] …)
SELECT COUNT(TBNAME) FROM <stable_name> WHERE <tag_name> <[=|=<|>=|<>] values..> ([AND|OR] …)
写数据时自动创建子表
当定义好了超级表,在写数据的时候并不知道某个设备是否存在,可以采用自动创建子表,需要注意的是超级表是不能创建的。
INSERT INTO <tb_name> USING <stb_name> TAGS (<tag1_value>,...) VALUES (field_value,...)(field_value,...)...
对多个超级表下的子表创建。
INSERT INTO <tb1_name> USING <stb1_name> TAGS (<tag1_value1>, ...) VALUES (<field1_value1>,...)(<field1_value2>,...)...<tb_name2> USING <stb_name2> TAGS(<tag1_value2>,...) VALUES (<field1_value1>,...)
TAG管理
ALTER TABLE <stable_name> ADD TAG <new_tag_name> <TYPE>
,标签总数不能超过6个ALTER TABLE <stable_name> DROP TAG <tag_name>
,第一列标签不能删除,至少保留一个标签,从超级表删除某个标签后,其下的所有子表也会自动删除标签ALTER TABLE <stable_name> CHANGE TAG <old_tag_name> <new_tag_name>
,其下所有子表的标签名也会改变ALTER TABLE <table_name> SET TAG <tag_name>=<new_tag_value>
多表聚合
通过TAG值进行条件过滤,暂不支持针对binary类型的模糊匹配过滤。
SELECT function<field_name>,…
FROM <stable_name>
WHERE <tag_name> <[=|<=|>=|<>] values..> ([AND|OR] …)
INTERVAL (<time range>)
GROUP BY <tag_name>, <tag_name>…
ORDER BY <tag_name> <asc|desc>
SLIMIT <group_limit>
SOFFSET <group_offset>
LIMIT <record_limit>
OFFSET <record_offset>
ORDER BY _c0 ASC | DESC
对时间戳升序或降序举例
创建超级表:
CREATE TABLE thermometer (ts timestamp, degree double) TAGS(location binary(20), type int)
每个采集点一张表:
CREATE TABLE term1 USING thermometer TAGS('beijing',1);
CREATE TABLE therm2 USING thermometer TAGS('beijing',2);
CREATE TABLE therm3 USING thermometer TAGS('tianjin',1);
CREATE TABLE therm4 USING thermometer TAGS('shanghai',3);
写入数据
INSERT INTO therm1 VALUES ('2018-01-01 00:00:00.000',20);
INSERT INTO therm2 VALUES ('2018-01-01 00:00:00.000',21);
INSERT INTO therm3 VALUES ('2018-01-01 00:00:00.000',22);
INSERT INTO therm4 VALUES ('2018-01-01 00:00:00.000',23);
按标签聚合查询
SELECT COUNT(*),AVG(degree), MAX(degree), MIN(degree)
FROM thermoter
WHERE location='beijing' or location='tianjing'
GROUP BY location, type
按时间周期聚合查询
SELECT COUNT(*),AVG(degree), MAX(degree), MIN(degree)
FROM thermometer
WHERE name<>'beijing' and ts>now-1d
INTEERVAL(10M)
GROUPBY location,type
连续查询Continuoous Query
SELECT COUNT(*)
FROM FOO_TABLE
INTERVAL(1M) SLIDING(30S)
每一分钟统计一次,前向滑动的时间是30秒。
SELECT COUNT(*)
FROM FOO_TABLE
INTERVAL(1M)
每一分钟统计一次,前向滑动的时间是一分钟
注意:
前向滑动时间不能大于时间窗口的范围,如果大于了,系统将强制设置为时间窗口的范围。
将连续查询的结果写回到数据库中:
CREATE TABLE QUERY_RES
AS
SELECT COUNT(*)
FROM FOO_TABLE
INTERVAL(1M) SLIDING(30S)
默认如果不输入结束时间,连续查询会一直进行下去。还可以指定结束时间:
CREATE TABLE QUERY_RES
AS
SELECT COUNT(*)
FROM FOO_TABLE
WHERE TS > NOW AND TS <= NOW + 1H
INTERVAL(1M) SLIDING(30S)
查看系统中全部运行的连续查询
show streams
杀掉对应的连续查询
kill stream
在写回模式中,如果把写回的表删除,连续查询也会自动停止。
数据订阅Publisher/Subscriber
启动订阅服务:
TAOS_SUB *taos_subscribe(char *host, char *user, char *pass, char *db, char *table, int64_t time, int mseconds)
--host: 主机ip地址
--user: 数据库登录用户名
--pass: 密码
--db: 数据库名称
--table: 超级表或表的名称
--time: 启动时间,Unix Epoch,单位为毫秒,从1970年1月1日起计算的毫秒数,如果设置为0表示从当前时间开始订阅
--mseconds: 查询数据库更新的时间间隔,单位为毫秒,一般设置为1000毫秒。返回值为指向TDengine_SUB结构的指针,如果返回为空,表示失败
获取订阅结果。用户应用程序置于一个无限循环语句,如果数据库表有新纪录到达,该API将放回最新的记录,如果没有新的记录该API将阻塞,如果返回值为空说明系统出错。
TASOS_ROW taos_consume(TAOS_SUB *tsub)
--tsub: taos_subscribe的结构体指针
取消订阅。应用程序退出时,务必调用此函数以避免资源泄露。
void taos_unsubscribe(TAOS_SUB *tsub)
获取返回的一行记录中数据包含多少列。
int taos_num_subfields(TAOS_SUB *tsub)
获取每列数据的属性(数据类型、名字、长度)。
TAOS_FIELD *taos_fetch_subfields(TASO_SUB *tsub)
缓存Cache
获取一张表或超级表的最后一条记录
select last_row(degree) from thermometer where location='beijing'
通过HTTP方式进行。
http://<ip>:<PORT>/rest/sql
http://192.168.0.1:6020/rest/sql
-- IP: 集群中的任一台主机
-- PORT:配置文件中的httpPort,默认值是6020
-- Headler里带身份认证信息,单机版仅致辞Basic认证机制
-- BODY里是一个完整的SQL语句,SQL语句中的数据表应该提供数据库前缀,否则系统会返回错误
请求:
curl -H 'Authorization:Basic <TOKEN>' -d '<SQL>' <ip>:<PORT>/rest/sql
或
curl -u username:password -d '<SQL>' <ip>:<PORT>/
TOKEN为{username}:{password}经过Base64编码之后的字符串
返回格式:
{
"status": "succ",
"head": ["column1","column2", …],
"data": [
["2017-12-12 23:44:25.730", 1],
["2017-12-12 22:44:25.728", 4]
],
"rows": 2
}
练手
根用户
-- 进入根用户: sudo su
-- 退出根用户: exit
根目录
--来到根目录: cd /
--退出控制台:exit
vi练习
--列出目录:ls
--进入test目录: cd test
--vi打开文件:vi hello.txt
--决定光标的位置:
方向:h,j,k,l
行首:b
行尾:w
下面一行:o
上面一行:O
段首:{
段尾:}
--决定插入的位置:
选择光标前后插入:i,a
选择光标所在行行首行尾插入:i,A
--退出编辑:esc
--保存并退出::wq!
--不保存并退出::q!
文件目录结构
/etc/taos/taos.cfg 配置文件
-- cd /
-- cd etc/taos
/usr/local/taos/driver 动态链接库目录
-- cd /
-- cd usr/local/taos/driver
/var/lib/taos 数据文件默认目录
--cd /
--cd var/lib/taos
/var/log/taos 日志文件目录
--cd /
--cd var/log/taos
/usr/local/taos/bin 可执行文件目录
--cd /
--cd usr/local/taos/bin
taos:shell可执行文件
taosd:服务端可执行文件
taosdump:数据导出工具
rmtaos:卸载
服务端配置
在/etc/taos/taos.cfg配置,配置完成后需要重启taosd服务才能生效。
指定配置文件的目录:
taosd -c /home/user
查看taos.cfg文件:
-- cd /
-- cd etc/taos
-- ls
-- cat taos.cfg
配置详解:
创建数据库:
create database demo days 10 cache 16000 ablocks 4
客户端配置
在/etc/taos/taos.cfg配置,与taosd应用程序共享配置文件。启动taos时,也可以从命令行指定IP地址、端口号、用户名和密码,否则从taos.cfg读取。
为客户端程序taos指定配置文件目录:
taos -c /home/cfg
参数详解:
用户管理
CREATE USER user_name PASS 'password'
DROP USER user_name
,root用户使用ALTER USER user_name PASS 'password'
SHOW USERS
数据导入
insert into tb1 file a.csv b.csv tb2 c.csv ...
import into tb1 file a.csv b.csv tb2 c.csv ...
数据导出
按表导出csv文件,如果用户需要到处一个表或者一个STable表中的数据,可在shell中运行
select * from <tb_name> >> a.csv
用taosdump导出数据,通过taosdump --help
获取更详细的用法说明
--导出数据库中一张或多张表:taosdump [OPTION...] dbname tbname ...
--导出一个或多个数据库:taosdump [OPTION...] --database dbname...
--导出所有数据库(不含监控数据库): taosdump [OPTION...] --all-databases
系统连接、任务查询关系
正在进行的查询、流式计算,查看连接:
SHOW CONNECTIONS
强制关闭数据库连接:
KILL CONNECTION <connection-id>
显示数据查询:
SHOW QUERIES
强制关闭数据查询:
KILL QUERY <query-id>
显示流式计算:
KILL STREAM <stream-id>
系统监控