美文网首页
GO操作Taos数据库

GO操作Taos数据库

作者: 水车 | 来源:发表于2021-06-07 11:59 被阅读0次

    前言

    go 语言操作 TDengine 可以说是非常简单了,今天我们就记录一下操作流程

    其实操作基本都是使用 原生SQL 在操作。

    代码

    package TDengine
    
    import (
        "database/sql"
        "fmt"
        _ "mydt/taosSql"
        "strconv"
        "time"
    )
    
    func InitTaos()  {
        url := fmt.Sprintf("%s:%s@/tcp(%s:%d)/%s?interpolateParams=true", "root", "taosdata", "127.0.0.1", 6030, "log")
    
        db, err := sql.Open("taosSql", url)
        if err != nil {
            fmt.Printf("error on:  sql.open %s", err.Error())
            return
        }
        defer db.Close()
    
        dropDatabase(db, "mydt")
        createDatabase(db, "mydt")
        createSTable(db, "mydt", "scamera")
        // dropSTable(db,"mydt", "scamera")
        createTableUseS(db, "mydt", "scamera", "camera")
        //insertData(db, "mydt", "camera")
        for i := 0; i < 12; i++ {
            go insertDataTest(i, "mydt", "camera")
        }
        time.Sleep(10 * time.Minute)
        return
    }
    
    // dropDatabase 删除数据库
    /*
    DROP DATABASE [IF EXISTS] db_name;
    */
    func dropDatabase(db *sql.DB, dbName string)  {
        sqlStr := "drop database if exists " + dbName+";"
        _, err := db.Exec(sqlStr)
        checkErr(err, sqlStr)
    }
    
    // createDatabase 创建数据库
    /*
    CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [DAYS days] [UPDATE 1];
    KEEP是该数据库的数据保留多长天数,缺省是3650天(10年),数据库会自动删除超过时限的数据;
    DAYS: (个人理解)未来最大时间,例如存储未来10天以内的时间,超过的删除掉
    UPDATE 标志数据库支持更新相同时间戳数据;
    */
    func createDatabase(db *sql.DB, dbName string)  {
        // 创建数据库
        sqlStr := "create database " + dbName + " keep " + strconv.Itoa(365 * 20) + " days " + strconv.Itoa(30)+";"
        _, err := db.Exec(sqlStr)
        checkErr(err, sqlStr)
    }
    
    // createSTable 创建超级表
    /*
    CREATE STABLE [IF NOT EXISTS] stb_name (timestamp_field_name TIMESTAMP, field1_name data_type1 [, field2_name data_type2 ...]) TAGS (tag1_name tag_type1, tag2_name tag_type2 [, tag3_name tag_type3]);
    1) TAGS 列的数据类型不能是 timestamp 类型;
    2) TAGS 列名不能与其他列名相同;
    3) TAGS 列名不能为预留关键字;
    4) TAGS 最多允许 128 个,至少 1 个,总长度不超过 16 KB。
    */
    func createSTable(db *sql.DB, dbName, supTblName string){
        // 这一指令中的 STABLE 关键字,在 2.0.15 之前的版本中需写作 TABLE 。
        sqlStr := "create stable if not exists " + dbName + "." + supTblName + " (ts timestamp, name BINARY(32), age INT, isAlarm BOOL) tags(location nchar(64), groupId int);"
        _, err := db.Exec(sqlStr)
        checkErr(err, sqlStr)
    }
    
    // dropSTable 删除超级表
    /*
    DROP STABLE [IF EXISTS] stb_name;
    删除 STable 会自动删除通过 STable 创建的子表
    */
    func dropSTable(db *sql.DB, dbName, supTblName string)  {
        // TODO is exists 依然会报错
        sqlStr := "drop stable if exists " + dbName + "." + supTblName + ";"
        fmt.Printf("sqlStr: %s \n", sqlStr)
        _, err := db.Exec(sqlStr)
        checkErr(err, sqlStr)
    }
    
    // createTable 以超级表为模板创建数据表
    /*
    // 使用超级表的所有tag
    CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...);
    // 使用超级表的部分tag
    CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...);
    */
    func createTableUseS(db *sql.DB, dbName, sTableName, tableName string){
        sqlStr := "create table if not exists " + dbName + "." + tableName + " using " + dbName + "." + sTableName +" tags('location', 2);"
        //fmt.Printf("sqlStr:               %v\n", sqlStr)
        _, err := db.Exec(sqlStr)
        checkErr(err, sqlStr)
    }
    
    // createTable 创建普通表
    /*
    CREATE TABLE [IF NOT EXISTS] tb_name (timestamp_field_name TIMESTAMP, field1_name data_type1 [, field2_name data_type2 ...]);
    1) 表的第一个字段必须是 TIMESTAMP,并且系统自动将其设为主键;
    2) 表名最大长度为 192;
    3) 表的每行长度不能超过 16k 个字符;(注意:每个 BINARY/NCHAR 类型的列还会额外占用 2 个字节的存储位置)
    4) 子表名只能由字母、数字和下划线组成,且不能以数字开头
    5) 使用数据类型 binary 或 nchar,需指定其最长的字节数,如 binary(20),表示 20 字节;
    */
    func createTable(db *sql.DB, dbName, tableName string)  {
        sqlStr := "create table if not exists " + dbName + "." + tableName + " (id TIMESTAMP, name BINARY(32), age INT, isAlarm BOOL);"
        //fmt.Printf("sqlStr:               %v\n", sqlStr)
        _, err := db.Exec(sqlStr)
        checkErr(err, sqlStr)
    }
    
    // dropTable 删除数据表
    /*
    DROP TABLE [IF EXISTS] tb_name;
    */
    func dropTable(db *sql.DB, dbName, tableName string)  {
        sqlStr := "drop table if exists " + dbName + "." + tableName +";"
        //fmt.Printf("sqlStr:               %v\n", sqlStr)
        _, err := db.Exec(sqlStr)
        checkErr(err, sqlStr)
    }
    
    // insertData 插入数据
    /*
    INSERT INTO tb_name VALUES (field_value, ...);
    INSERT INTO tb_name (field1_name, ...) VALUES (field1_value1, ...);
    INSERT INTO tb_name 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_value2, ...) ...
                tb2_name (tb2_field1_name, ...) VALUES (field1_value1, ...) (field1_value2, ...) ...;
    
    */
    func insertData(db *sql.DB, dbName, tableName string)  {
        timestamp := time.Now().Unix() *1000
    
        sqlStr := "insert into " + dbName + "." + tableName + " values (" + strconv.FormatInt(timestamp, 10) + ", 'zzx', 28, true);"
        //fmt.Printf("sqlStr:               %v\n", sqlStr)
        _, err := db.Exec(sqlStr)
        checkErr(err, sqlStr)
    }
    // 插入速度测试
    func insertDataTest(goi int, dbName, tableName string)  {
        url := fmt.Sprintf("%s:%s@/tcp(%s:%d)/%s?interpolateParams=true", "root", "taosdata", "127.0.0.1", 6030, "log")
    
        db, err := sql.Open("taosSql", url)
        if err != nil {
            fmt.Printf("error on:  sql.open %s", err.Error())
            return
        }
        defer db.Close()
        num := 10000
        timestamp := time.Now().Unix() *1000 - int64((goi+1) * num * 2)
        //var err error
        start := time.Now() // 获取当前时间
        for i := 0; i < num; i++ {
            if i%(num/10) == 0 {
                fmt.Printf("insert: %v 条;time= %v\n", i, time.Now().Format("15:04:05"))
            }
            timestamp++
            sqlStr := "insert into " + dbName + "." + tableName + " values (" + strconv.FormatInt(timestamp, 10) + ", 'zzx', 28, true);"
            //fmt.Printf("sqlStr:               %v\n", sqlStr)
            _, _ = db.Exec(sqlStr)
            //checkErr(err, sqlStr)
        }
        elapsed := time.Since(start)
        fmt.Printf("携程%v完成耗时:%v \n",goi, elapsed)
    }
    
    // 查询数据数量
    /*
    SELECT COUNT(*) FROM DBNAME;
    */
    func count(db *sql.DB, dbName, tableName string)  {
        sqlStr := "select count(*) from " + dbName + "." + tableName +";"
        //fmt.Printf("sqlStr:               %v\n", sqlStr)
        _, err := db.Exec(sqlStr)
        checkErr(err, sqlStr)
    }
    
    func checkErr(err error, prompt string) {
        fmt.Printf("sqlStr:  %s\n", prompt)
        if err != nil {
            panic(err)
        }
    }
    

    后记

    上面记录了 taos 数据库的基本操作,也有一些更复杂的操作,我们可以查看官网学习。

    体会

    taos数据库的性能还是不错的,特别是物联网情景下,包括数据库的设计也是非常合理的。值得体验一下。

    相关文章

      网友评论

          本文标题:GO操作Taos数据库

          本文链接:https://www.haomeiwen.com/subject/nehosltx.html