最近在寻找时序数据库,想应用在公司的项目上。
上一篇文章实验了InfluxDB:windows上使用influx2.7学习,还学习了flux语言,最后发现宽表查询比较困难,就放弃了,于是决定试试国产时序数据库TDengine
参考
官方文档:https://docs.taosdata.com/
windows安装TDengine
从3.0.71版本之后,TDengine就不提供Server版本的安装包了:
那就安装3.0.71
版本吧,下载地址:https://www.taosdata.com/assets-download/3.0/TDengine-server-3.0.7.1-Windows-x64.exe
下载之后,点击安装,会默认安装到C:\TDengine
目录下:
点击taosd.exe
即可运行TDengine数据库服务
2000万示例数据
我准备了一个csv数据,可百度网盘下载:链接:https://pan.baidu.com/s/1FlcFkh8cF1WEAOMrmrb9JQ?pwd=o579
提取码:o579,有4G多(解压后的csv文件),大概有19610118
条数据,最后全部写入到tdengine,只占500M不到,非常节省空间
创建数据库
打开taos.exe
,输入如下命令,创建一个名称叫tony
的数据库
create database tony precision 'ns'
注意1:precision 'ns'
这一句是让数据库支持纳秒,不加这句的话默认是毫秒。需要支持纳秒的原因:因为在读取data.csv的行的时候,生成sql语句的ts
字段用的是DateTime.Now
,需要数据库支持纳秒来区分时间,否则插入的ts有可能一样,会被当做更新行。
注意2:最新版本的TDengine(截止到写文章的时候,是3.2.3.0
)的linux安装包版本使用precision 'ns'
无效,亲测,可能是自己的使用方式不对,所以想跟着本文章学习,最好使用3.0.71
版本
编写C#程序写入数据
使用C#,将data.csv
中的19610118
条数据写入到数据库
创建一个控制台程序,引用Nuget:
<PackageReference Include="TDengine.Connector" Version="3.1.2" />
编写代码如下(包含自动创建表):
// See https://aka.ms/new-console-template for more information
using System.Diagnostics;
using TDengine.Driver;
using TDengine.Driver.Client;Console.WriteLine("Hello, World!");var builder = new ConnectionStringBuilder("host=localhost;port=6030;username=root;password=taosdata");
using (var client = DbDriver.Open(builder))
{Console.WriteLine("connected");var affectRow = client.Exec(@"create TABLE IF NOT exists tony.batinfo(ts timestamp,batcode varchar(50),logintime varchar(50),devicecode varchar(20),processid int,flowid int,batterypos int,capacity1 float ,capacity2 float ,voltage1 float ,voltage2 float ,current1 float ,current2 float ,ocv1 float ,ocv2 float ,ir1 float ,ir2 float,batid float);");if (affectRow > 0){Console.WriteLine("create table success!");}string csvPath = "G:\\BatInfo_2021\\data.csv";//写入Stopwatch stopwatch = Stopwatch.StartNew();using (var stream = new StreamReader(csvPath)){int count = 0;int totalCount = 0;while (true){var line = await stream.ReadLineAsync();if (line == null) break;count++;totalCount++;if (totalCount == 1) continue;//第1行舍弃var strs = line.Split(',');if (count >= 10000){count = 0;Console.WriteLine($"has read {totalCount} lines,ellapse time {stopwatch.ElapsedMilliseconds / (double)1000} seconds");}var batCodeStr = strs[0];var loginTimeStr = strs[1];var deviceCodeStr = strs[2];var processIdStr = strs[3];var flowIdStr = strs[4];var batteryPos = strs[7];var capacity1Str = strs[12];var capacity2Str = strs[13];var voltage1Str = strs[18];var voltage2Str = strs[19];var current1Str = strs[24];var current2Str = strs[25];var ocv1Str = strs[28];var ocv2Str = strs[29];var ir1Str = strs[33];var ir2Str = strs[34];var batIdStr = strs[71];var sql = @$"insert into tony.batinfo values('{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffffff")}','{batCodeStr}','{loginTimeStr}','{deviceCodeStr}',{ConvertToDouble(processIdStr, 0)},{ConvertToDouble(flowIdStr, 0)},{ConvertToDouble(batteryPos, 0)},{ConvertToDouble(capacity1Str, 0)},{ConvertToDouble(capacity2Str, 0)},{ConvertToDouble(voltage1Str, 0)},{ConvertToDouble(voltage2Str, 0)},{ConvertToDouble(current1Str, 0)},{ConvertToDouble(current2Str, 0)},{ConvertToDouble(ocv1Str, 0)},{ConvertToDouble(ocv2Str, 0)},{ConvertToDouble(ir1Str, 0)},{ConvertToDouble(ir2Str, 0)},{ConvertToDouble(batIdStr, 0)})";try{affectRow = client.Exec(sql);if (affectRow <= 0) { Console.WriteLine($"affect row:{affectRow}"); }}catch (Exception e){Console.WriteLine($"Error:{e.Message}");}}}Console.WriteLine($"finish,ellapse total seconds:{stopwatch.ElapsedMilliseconds / (double)1000}");
}double ConvertToDouble(string str, double defalutValue)
{if (double.TryParse(str, out var v)) return v;return defalutValue;
}
运行完成后,数据插入成功。
数据查询体验
点击taos.exe
即可开启查询。
注意:TDengine以上都没有给任何列添加索引!!!
查询数据总量
使用tdengine查询数据总量耗时0.03s
相同数据量的SQL SERVER查询,耗时0.63s
查询电压平均值
计算将近2千万数字的平均值大概时间为0.04s
查询电压大于3500小于3600的记录最多10条
耗时0.2s
查询BatCode='111’的数据有多少条
耗时1.88s