型変換
Append/AppendRow) と読み取り時 (Scan 経由) に分けて考えることができます。特定の変換のサポートが必要な場合は、issue を作成してください。
標準の database/sql インターフェイスでは、ClickHouse API と同じ型がサポートされるはずです。いくつか例外はありますが、主に複雑な型に関するもので、以下のセクションで説明しています。ClickHouse API と同様に、このクライアントは、挿入時とレスポンスのマーシャリング時の両方で、できるだけ柔軟にさまざまな変数型を受け入れられるよう設計されています。
複合型
Date/DateTime
Date、Date32、DateTime、DateTime64 の日付/日時型をサポートしています。日付は、2006-01-02 フォーマットの文字列、または Go ネイティブの time.Time{} や sql.NullTime を使って挿入できます。DateTime でも同様にこれらの型をサポートしていますが、文字列を渡す場合は 2006-01-02 15:04:05 フォーマットを使用し、必要に応じてタイムゾーンオフセット (例: 2006-01-02 15:04:05 +08:00) を付ける必要があります。読み取り時も time.Time{} と sql.NullTime の両方がサポートされており、sql.Scanner インターフェイスを実装した任意の型も利用できます。
タイムゾーン情報の扱いは、ClickHouse の型と、値を挿入する場合か読み取る場合かによって異なります。
- DateTime/DateTime64
- insert 時には、値は UNIX timestamp フォーマットで ClickHouse に送信されます。タイムゾーンが指定されていない場合、クライアントはクライアントのローカルタイムゾーンを使用します。
time.Time{}またはsql.NullTimeも、それに応じて epoch に変換されます。 - select 時には、
time.Time値を返す際、設定されていればカラムのタイムゾーンが使用されます。設定されていない場合は、server のタイムゾーンが使用されます。
- insert 時には、値は UNIX timestamp フォーマットで ClickHouse に送信されます。タイムゾーンが指定されていない場合、クライアントはクライアントのローカルタイムゾーンを使用します。
- Date/Date32
- insert 時には、日付を unix timestamp に変換する際に、その日付のタイムゾーンが考慮されます。つまり、Date 型は ClickHouse ではロケールを持たないため、日付として保存される前にタイムゾーン分のオフセットが適用されます。文字列の値でこれが指定されていない場合は、ローカルタイムゾーンが使用されます。
- select 時には、
time.Time{}またはsql.NullTime{}のインスタンスにスキャンされた日付は、タイムゾーン情報なしで返されます。
Time/Time64 型
Time と Time64 のカラム型は、日付部分を含まない時刻の値を格納します。どちらも Go の time.Duration にマッピングされます。
Timeは時刻を秒精度で格納します。Time64(precision)は (DateTime64と同様に) 秒未満の精度をサポートし、precision は 0〜9 の範囲です。
Array
Map
database/sql API を使用する場合、Map の値は厳密に型指定する必要があり、値の型として interface{} は使用できません。たとえば、Map(String,String) フィールドには map[string]interface{} を渡せないため、代わりに map[string]string を使用する必要があります。一方、interface{} 型の変数は常に互換性があるため、より複雑な構造にも使用できます。完全な例タプル
Nested
map[string]interface{} である必要があります。現在、値は厳密には型付けされていません。
flatten_tested=0
flatten_nested にデフォルト値の 1 を使用すると、ネストされたカラムはそれぞれ別個の Array にフラット化されます。そのため、挿入と取得にはネストしたスライスを使用する必要があります。任意の深さのネストでも動作する可能性はありますが、これは公式にはサポートされていません。
flatten_nested=1
注: Nested カラムは同じ次元である必要があります。たとえば、上記の例では、Col_2_2 と Col_2_1 は同じ数の要素を持つ必要があります。
インターフェイスがよりシンプルで、ネストも公式にサポートされているため、flatten_nested=0 を推奨します。
Geo 型
UUID
sql.Scanner または Stringify を実装した任意の型として扱うこともできます。
Decimal
サードパーティの依存関係を避けるために、代わりに Float を使いたくなるかもしれません。ただし、正確な値が必要な場合、ClickHouse の Float 型は推奨されません ので注意してください。それでもクライアント側で Go の組み込み Float 型を使う場合は、ClickHouse のクエリ内で toFloat64() 関数 または そのバリアント を使用して、Decimal を明示的に Float に変換する必要があります。この変換によって精度が失われる可能性がある点に注意してください。
Nullable
Nil は、ClickHouse の NULL を表します。これは、フィールドが Nullable として宣言されている場合に使用できます。insert 時には、通常のカラムと Nullable カラムの両方に Nil を渡せます。前者では、その型のデフォルト値が保存されます。たとえば、string であれば空文字列です。Nullable 版では、ClickHouse に NULL 値 が格納されます。
scan 時には、Nullable フィールドの nil 値を表現するために、ユーザーは nil を扱える型へのポインタ (たとえば *string) を渡す必要があります。以下の例では、Nullable(String) である col1 は、そのため **string を受け取ります。これにより nil を表現できます。
sql.NullInt64 などの sql.Null* 型にも対応しています。これらは対応する ClickHouse の型と互換性があります。
Big Ints
BFloat16
BFloat16 は、機械学習のワークロードで使用される 16 ビットの brain float 型です。Go では、BFloat16 の値は float32 として挿入および読み取りが行われます。Nullable バリアントでは sql.NullFloat64 を使用します。
QBit
QBit は、ベクトル埋め込みをビットスライス形式で格納するための実験的なカラム型で、ベクトル類似度検索向けに最適化されています。使用するには、allow_experimental_qbit_type 設定を有効にする必要があります。
Go では、QBit(Float32, N) カラムは []float32 として挿入およびスキャンされます。N はベクトルの次元です。