连接
default 访问。
请注意,我们使用默认的原生端口进行连接。
conn 变量。
执行
Exec 方法执行任意语句。这适用于 DDL 和简单语句。不建议将其用于较大的插入操作或查询结果迭代。
批次插入
Send() 方法发送。在执行 Send 之前,批次数据会一直保存在内存中。
建议对批次调用 Close,以避免连接泄漏。这可以在准备完批次后通过 defer 关键字实现。如果始终没有调用 Send,它会负责清理连接。请注意,如果没有追加任何行,查询日志中会显示 0 行插入记录。
临时列
查询行
QueryRow 方法查询单行,也可以通过 Query 获取用于遍历结果集的游标。前者接受一个目标端,用于将数据序列化到其中;而后者则需要对每一行调用 Scan。
SELECT 语句中指定的顺序传入;如果使用如上所示的 SELECT *,默认会采用列声明顺序。
与插入类似,Scan 方法要求目标变量具有合适的类型。这里同样尽量保持灵活性:在不会造成精度损失的前提下,会尽可能进行类型转换。例如,上面的示例展示了将 UUID 列读取到字符串变量中。有关每种列类型支持的完整 Go 类型列表,请参阅类型转换。
最后,请注意,Query 和 QueryRow 方法支持传入 Context。这可用于设置查询级别的参数;更多详情请参阅使用 Context。
异步插入
列式插入
使用结构体
配合序列化使用 Select
扫描结构体
ScanStruct 可将查询返回的单行数据映射到结构体中。
追加结构体
AppendStruct 允许将结构体追加到现有批次中,并将其视为完整的一行。这要求结构体中的列在名称和类型上都与表一致。虽然所有列都必须有对应的结构体字段,但某些结构体字段可能没有对应的列表达形式。这些字段会被忽略。
参数绑定
Exec、Query 和 QueryRow 方法中绑定参数。如下面的示例所示,支持命名参数、编号参数和位置参数。下文将分别给出示例。
特殊情况
[ ] 包裹的值,应使用 ArraySet。
如果需要组/元组,并且要用 ( ) 包裹,例如用于 IN 运算符,可以使用 GroupSet。这在需要多个组的场景中尤其有用,如下例所示。
最后,DateTime64 字段需要指定精度,才能确保参数被正确渲染。不过,客户端并不知道该字段的精度 level,因此必须由用户提供。为简化这一操作,我们提供了 DateNamed 参数。
使用上下文
withDeadline 创建的上下文后,可以为查询设置执行时间限制。请注意,这是一个绝对时间;超时后只会释放连接并向 ClickHouse 发送取消信号。或者,也可以使用 WithCancel 显式取消查询。
辅助函数 clickhouse.WithQueryID 和 clickhouse.WithQuotaKey 可用于指定 Query id 和配额键。Query id 可用于在日志中跟踪查询以及执行取消操作。配额键可用于基于唯一键值对 ClickHouse 的使用施加限制,更多详情请参见配额管理。
你还可以使用上下文,确保某项设置仅应用于特定查询,而不是像连接设置中所示那样应用于整个连接。
最后,你可以通过 clickhouse.WithBlockSize 控制块缓冲区的大小。它会覆盖连接级别的设置 BlockBufferSize,并控制任意时刻解码并保存在内存中的最大块数。更大的值可能意味着更高的并行度,但代价是占用更多内存。
上述内容的示例如下。
Progress、profile 和日志信息
动态扫描
外部表
SELECT 查询时将数据发送到 ClickHouse。这些数据会被放入临时表中,并可在查询本身中用于求值。
要随查询发送外部数据,用户必须先通过 ext.NewTable 构建外部表,然后再通过上下文传递它。
OpenTelemetry
clickhouse.WithSpan 通过上下文将 span 附加到查询。
HTTP 传输限制虽然 ClickHouse server 接受标准的
traceparent / tracestate HTTP 请求头,但 clickhouse-go 的 HTTP 传输目前不会发送这些请求头,因此 WithSpan 在 HTTP 下不起作用。作为变通方案,你可以通过连接选项中的 HttpHeaders 手动设置请求头。