在Golang中集成ClickHouse,推荐使用官方的ClickHouse Go驱动,它性能优秀且功能完善。以下是完整的集成方案:
1. 安装驱动
go get github.com/ClickHouse/clickhouse-go/v2
2. 基础连接配置
package main
import (
"context"
"database/sql"
"fmt"
"log"
"time"
_ "github.com/ClickHouse/clickhouse-go/v2"
)
func main() {
// 连接配置
conn := clickhouse.OpenDB(&clickhouse.Options{
Addr: []string{"localhost:9000"},
Auth: clickhouse.Auth{
Database: "default",
Username: "default",
Password: "",
},
DialTimeout: 5 * time.Second,
})
// 测试连接
if err := conn.Ping(); err != nil {
log.Fatal(err)
}
fmt.Println("Connected to ClickHouse")
}
3. 数据操作示例
创建表
func createTable(conn *sql.DB) error {
query := `
CREATE TABLE IF NOT EXISTS user_events (
user_id UInt64,
event_type String,
event_time DateTime,
properties String
) ENGINE = MergeTree()
ORDER BY (user_id, event_time)
`
_, err := conn.Exec(query)
return err
}
插入数据(批量)
func insertBatch(conn *sql.DB) error {
tx, err := conn.Begin()
if err != nil {
return err
}
stmt, err := tx.Prepare(`
INSERT INTO user_events (user_id, event_type, event_time, properties)
VALUES (?, ?, ?, ?)
`)
if err != nil {
return err
}
defer stmt.Close()
// 批量插入
for i := 1; i <= 1000; i++ {
_, err = stmt.Exec(
i,
"click",
time.Now(),
fmt.Sprintf(`{"page": "home", "click_count": %d}`, i),
)
if err != nil {
return err
}
}
return tx.Commit()
}
查询数据
func queryData(conn *sql.DB) error {
rows, err := conn.Query(`
SELECT user_id, event_type, event_time, properties
FROM user_events
WHERE event_time > ?
ORDER BY event_time DESC
LIMIT 10
`, time.Now().Add(-24*time.Hour))
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
var (
userID uint64
eventType string
eventTime time.Time
properties string
)
if err := rows.Scan(&userID, &eventType, &eventTime, &properties); err != nil {
return err
}
fmt.Printf("User: %d, Event: %s, Time: %s\n", userID, eventType, eventTime)
}
return rows.Err()
}
4. 高级配置
连接池配置
func getConnectionPool() *sql.DB {
conn := clickhouse.OpenDB(&clickhouse.Options{
Addr: []string{"localhost:9000"},
Auth: clickhouse.Auth{
Database: "default",
Username: "default",
},
DialTimeout: 10 * time.Second,
MaxOpenConns: 10,
MaxIdleConns: 5,
ConnMaxLifetime: time.Hour,
})
conn.SetMaxOpenConns(10)
conn.SetMaxIdleConns(5)
conn.SetConnMaxLifetime(time.Hour)
return conn
}
5. 最佳实践
- 使用连接池:合理配置连接数,避免频繁创建连接
- 批量插入:ClickHouse适合批量写入,单条插入性能较差
- 数据分区:根据时间字段合理分区提升查询性能
- 错误处理:始终检查数据库操作的错误
- 连接健康检查:定期检查连接状态
这个方案提供了完整的ClickHouse集成,包括连接管理、CRUD操作和性能优化建议。