Golang处理ClickHouse Decimal类型
在使用Golang处理ClickHouse的Decimal类型时遇到一些问题。官方driver在Scan时会将Decimal转为float64,导致精度丢失。尝试过用sql.RawBytes接收,但后续处理比较麻烦。请问有没有更好的方法能完整保留Decimal的精度?或者是否有推荐的第三方库可以正确处理这种类型?
        
          2 回复
        
      
      
        使用Go处理ClickHouse的Decimal类型时,推荐使用clickhouse-go驱动。可通过sql.RawBytes接收数据,再转换为字符串或自定义结构体处理。注意精度和标度设置,避免溢出。
更多关于Golang处理ClickHouse Decimal类型的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Golang中处理ClickHouse的Decimal类型时,通常使用clickhouse-go驱动。以下是关键步骤和示例代码:
1. 安装驱动
go get github.com/ClickHouse/clickhouse-go/v2
2. 代码示例
package main
import (
	"context"
	"database/sql"
	"fmt"
	"log"
	_ "github.com/ClickHouse/clickhouse-go/v2"
)
func main() {
	// 连接ClickHouse
	conn, err := sql.Open("clickhouse", "tcp://localhost:9000?username=default&password=")
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close()
	// 创建测试表(包含Decimal字段)
	_, err = conn.Exec(`
		CREATE TABLE IF NOT EXISTS decimal_test (
			id UInt32,
			amount Decimal(18, 4)
		) ENGINE = Memory
	`)
	if err != nil {
		log.Fatal(err)
	}
	// 插入数据
	tx, _ := conn.Begin()
	stmt, _ := tx.Prepare("INSERT INTO decimal_test (id, amount) VALUES (?, ?)")
	
	// 使用字符串或float64传递Decimal值
	_, err = stmt.Exec(1, "12345.6789")  // 字符串形式
	_, err = stmt.Exec(2, 98765.4321)    // float64形式
	
	if err != nil {
		log.Fatal(err)
	}
	tx.Commit()
	// 查询数据
	rows, err := conn.Query("SELECT id, amount FROM decimal_test")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()
	for rows.Next() {
		var (
			id     uint32
			amount string // Decimal类型建议用字符串接收
		)
		if err := rows.Scan(&id, &amount); err != nil {
			log.Fatal(err)
		}
		fmt.Printf("ID: %d, Amount: %s\n", id, amount)
	}
}
3. 重要说明
- 精度定义:
Decimal(precision, scale)中precision是总位数,scale是小数位数 - 数据传递:
- 写入时支持字符串、float64或big.Int
 - 读取时建议用string接收避免精度丢失
 
 - 类型映射:
- ClickHouse Decimal → Go string/float64
 - 大数值务必使用字符串避免精度问题
 
 
4. 处理建议
- 金融等精度敏感场景始终使用字符串传输
 - 可自定义类型实现更精确的映射:
 
type Decimal string
func (d *Decimal) Scan(value interface{}) error {
    *d = Decimal(fmt.Sprint(value))
    return nil
}
使用此方案可确保Decimal数据在Golang和ClickHouse间准确传输。
        
      
                    
                    
                    
