You need to enable JavaScript to run this app.
ByteHouse云数仓版

ByteHouse云数仓版

复制全文
Golang
MySQL Go Driver
复制全文
MySQL Go Driver

本文介绍如何在 Go 开发环境连接并访问 ByteHouse 云数仓。

环境要求

驱动

已验证版本

Mysql Go 驱动

1.8.1+,驱动下载链接

Go

Golang 1.20+

使用限制
  • 不支持 ByteHouse 的 JSONB 和 Bitmap64 的数据类型。
  • 当前 ByteHouse MySQL 协议不支持 ComPrepare 协议,因此 insert batch 逻辑无法使用 MySQL Go 中的 prepare,只能拼接 SQL。
  • 当前不支持数据库账号的认证。
  • 不支持设置 query ID。
  • 不支持在连接层面(sql.Open)设置计算组。
  • 如果您在使用过程中遇到其他未知限制,请联系 ByteHouse 团队处理。

安装依赖程序

您可以在 程序Github 主页 获取最新的文档和发布版本信息。

go get -u github.com/go-sql-driver/mysql

-- 以下为依赖程序
go get -u github.com/stretchr/testify

安装完成后,在 Go 程序代码的 import 中插入以下内容。

import (
        "database/sql"

        _ "github.com/go-sql-driver/mysql"
)

获取 ByteHouse 连接信息

ByteHouse 支持通过 IAM 用户连接,所需连接信息获取方式如下。更多连接操作请参考步骤三:获取 ByteHouse 连接串信息

参数

配置说明

host

配置为 ByteHouse 的公网/私网域名,您可以在 ByteHouse 控制台的租户管理 > 基本信息 > 网络信息中查看并复制网络信息。详情请参见步骤二:配置网络信息

port

配置为固定值 3306。

user & password

使用 API Key 作为 user 和 password。详情请参见获取 API Key

  • user:为 API Key 的前半部分,比如获取的 API Key 为 xxxx.yyyy,则 User 需填写 xxxx
  • password:为 API Key 的前半部分,比如获取的 API Key 为 xxxx.yyyy,则 User 需填写 yyyy

database

配置为连接 ByteHouse 的数据库名称。

基本用法

您可以使用以下代码连接至 ByteHouse,并开始使用标准语句开发 ByteHouse,用于查询、写入和读取数据。

  • 超时时间配置:timeout 默认为 0s、readTimeout 默认为 0s、writeTimeout 默认为 0s。
  • 默认支持 keepAlive,可以复用连接和避免短链接。

连接至 ByteHouse

可参考下面代码样例填写 ByteHouse 连接信息,注意根据中获取的信息填写其中的 {Host}{Password}{User}{Database}{VIRTUAL_WAREHOUSE_ID} 等字段的值,获取方式请参见获取 ByteHouse 连接信息

host := "{Host}"
port := 3306
password := "{Password}"
user := "{User}"
database := "{Database}"
virtual_warehouse_id := "{VIRTUAL_WAREHOUSE_ID}"

db, err := sql.Open(
   "mysql", 
   fmt.Sprintf("%v:%v@(%v:%v)/%v", user, password, host, port, database),
)
if err != nil {
   log.Fatal(err)
}

设置特定计算组(连接级别)

通过创建每一个连接(connection)后设置计算组配置。

_, err = conn.ExecContext(ctx, fmt.Sprintf("set virtual_warehouse = '%v'", virtual_warehouse_id))
    if err != nil {
        log.Fatal(err)
    }

基本用法示例

package main

import (
    "context"
    "database/sql"
    "fmt"
    "github.com/go-sql-driver/mysql"
    _ "github.com/go-sql-driver/mysql"
    "github.com/google/uuid"
    "log"
    "strconv"
    "strings"
    "time"
)

func main() {
    host := "{Host}"
    port := 3306
    password := "{Password}"
    user := "{User}"
    database := "{Database}"
    virtual_warehouse_id := "{VIRTUAL_WAREHOUSE_ID}"

    db, err := sql.Open(
       "mysql", 
       fmt.Sprintf("%v:%v@(%v:%v)/%v", user, password, host, port, database),
    )
    if err != nil {
       log.Fatal(err)
    }

    if err := db.Ping(); err != nil {
       log.Fatal(err)
    }
    ctx := context.Background()
    conn, err := db.Conn(context.Background())
    if err != nil {
       log.Fatal(err)
    }
    defer conn.Close()
    defer db.Close()
    
    _, err = conn.ExecContext(ctx, fmt.Sprintf("set virtual_warehouse = '%v'", virtual_warehouse_id))
    if err != nil {
        log.Fatal(err)
    }
    
    _, err = conn.ExecContext(ctx, "DROP DATABASE IF EXISTS bhgotest")
    if err != nil {
       log.Fatal(err)
    }

    _, err = conn.ExecContext(ctx, "CREATE DATABASE IF NOT EXISTS bhgotest")
    if err != nil {
       log.Fatal(err)
    }

    _, err = conn.ExecContext(ctx, `
CREATE TABLE IF NOT EXISTS bhgotest.example (
        Col1 UInt8
    , Col2 String
    , Col3 FixedString(3)
    , Col4 UUID
    , Col5 Map(String, UInt8)
    , Col6 Array(String)
    , Col7 Tuple(String, UInt8, Array(Map(String, String))) KV
    , Col8 DateTime
) Engine = CnchMergeTree() ORDER BY tuple()
`)
    if err != nil {
       log.Fatal(err)
    }

    values_list := make([]string, 0)
    for i := 0; i < 1000; i++ {
       value := fmt.Sprintf("(%v,%v,%v,'%v',%v,%v,%v,'%v')", uint8(42),
          "'ClickHouse'", "'Inc'",
          uuid.New(),
          "{'key': 1}",                     // Map(String, UInt8)
          "['Q', 'W', 'E', 'R', 'T', 'Y']", // Array(String)
          "('String Value', 5, [{'key': 'value'},{'key': 'value'},{'key': 'value'}])",
          time.Now().Format("2006-01-02 15:04:05"))
       values_list = append(values_list, value)
    }

    sql := fmt.Sprintf("INSERT INTO bhgotest.example VALUES %s",
       strings.Join(values_list, ", "))
    _, err = conn.ExecContext(ctx, sql)
    if err != nil {
       log.Fatal(err)
    }

    row := conn.QueryRowContext(ctx, "SELECT * FROM bhgotest.example  limit 1")
    var (
       col1             uint8
       col2, col3, col4 string
       col5             string
       col6             string
       col7             string
       col8             string
    )
    if err := row.Scan(&col1, &col2, &col3, &col4, &col5, &col6, &col7, &col8); err != nil {
       log.Fatal(err)
    }
    print(col1, col2, col3, col4, col5, col6, col7, col8)

    conn.ExecContext(ctx, "DROP TABLE IF EXISTS bhgotest.example")

}
最近更新时间:2025.10.22 19:18:53
这个页面对您有帮助吗?
有用
有用
无用
无用