ClickHouseのドキュメントを雑に翻訳してみた(Data types)

以下、 https://clickhouse.yandex/docs/en/data_types/ の雑な翻訳。Google翻訳に頼りっきりなので品質は期待しないでください。(でも、誤訳などのフィードバックは歓迎)

文章中の (?) 部分は **特に** 翻訳が怪しいものになります。

# Data types

ClickHouseは、様々な種類のデータをテーブルのカラムに格納できます。

このセクションでは、サポートされているデータタイプと、その際に考慮すべき事について説明します。

## Int8, Int16, Int32, Int64

整数型。

* Int8 - [-128 : 127]
* Int16 - [-32768 : 32767]
* Int32 - [-2147483648 : 2147483647]
* Int64 - [-9223372036854775808 : 9223372036854775807]

## UInt8, UInt16, UInt32, UInt64

符号無し整数型。

* UInt8 - [0 : 255]
* UInt16 - [0 : 65535]
* UInt32 - [0 : 4294967295]
* UInt64 - [0 : 18446744073709551615]

## Float32, Float64

浮動小数点型。それぞれC言語のfloat, doubleに相当する。
しかし、可能であれば、整数型のデータで保存する事をおすすめします。
例えば固定精度の数値、金額やページ読み込み時間(ミリ秒単位)などは整数値で取り扱う用が有用です。
浮動小数点型は、その性質上丸め誤差が発生し得ます。

```
:) SELECT 1 - 0.9

┌───────minus(1, 0.9)─┐
│ 0.09999999999999998 │
└─────────────────────┘
```

* 計算結果は、計算方法によって異なります。(コンピュータシステムのプロセッサ、アーキテクチャによる)
* 浮動小数点計算では、無限大(Inf)や非数(not-a-number)等の数値を返す場合があります。これらは計算結果として考慮する必要があります。
* (テーブルの)行から浮動小数点を読み取る場合、結果は計算機で表現可能な数値では無い可能性があります。

## Boolean

Boolean専用の型はありません。UInt8型を使用し、0または1で表現されます。

## String

任意の長さの文字列型。文字列の長さに制限はありません。値にはNULLを含む任意のバイト情報を含める事が出来ます。文字列型は、他のデータベースのVARCHAR,　BLOB, CLOB などの型から置き換え出来ます。

エンコーディングについて:

ClickHouseにはエンコーディングの概念はありません。文字列には任意のバイトを格納し、そのまま出力されます。テキストを保存する場合、UTF-8エンコードの使用をお勧めします。少なくとも、あなたの端末がUTF-8を使用するならば、何の変換も無しに読み書きする事が出来ます。
同様に、文字列操作をする特定の関数には、エンコーディングにUTF-8の使用を前提とされています。例えば、length関数は文字列の長さをバイト単位で計算し、lengthUTF8関数は値がUTF-8でエンコーディングされている事を前提として文字数を計算します。

## FixedString(N)

Nバイトの固定長文字列型(文字またはコードポイントでは無い)。Nは正の自然数でなければなりません。ClickHouseがより少ないバイト数を含む文字列を読み取るとき、固定長文字列型のデータ右側にNULLを埋めこみます。Nバイトより長いデータを扱う場合、エラーメッセージを返します。(以下略)

固定長文字列型では文字列型よりも提供されている関数が少ないため、便利な型ではありません。

## Date

日付型。1970/01/01からの日数を2バイトで格納します。Unixエポック秒の開始直後からコンパイル段階で定数として定義された上限閾値までの値を格納します。(現段階で、これは2106年までですが、最終的にサポートされるのは2015年までです)。最小値は0000/00/00として出力されます。

日付型はタイムゾーン無しで保存されます。

## DateTime

日時型。符号無しのUNIXタイムスタンプとして4バイトで格納されます。Date型と同じ範囲の値として格納できるようにします。(？) 値の最小値は、0000-00-00 00:00:00です。日時型は最小1秒(閏秒無し)の精度で保存されます。

## Enum8, Enum16

列挙型。String型よりも効率的に特定の文字列を格納できる。

例:

```
Enum8('hello' = 1, 'world' = 2)
// データ型は 'hello', 'world'の2種類を指定可能
```

Enum8の場合、-128~127、Enum16の場合は-32768~32767の範囲の数値を割当可能です。文字列と数値の組は全て異なる必要があります。空の文字列を割り当てる事も可能です。この型が(テーブル定義で)指定されている場合、数値は任意の順序で指定できます。指定の順番は特に何かに影響する事はありません。

メモリー上では、このタイプの列は、対応する数値のInt8,Int16と同じ方法で格納されます。テキストを読み込む場合、ClickHouseはテキストから対応するEnumの数値を検索します。Enumの定義に無い文字列が与えられた場合、例外を投げます。文字列を書き込むと、対応する文字列の数値が格納されます。Enumで定義されてない文字列である場合、例外を投げます。バイナリ形式で読み書きする場合、Int8及びInt16データ型と同じフォーマットとして動作します。暗黙のデフォルト値は、定義された中で最も小さな値です。

`ORDER BY`, `GROUP BY`, `IN`, `DISTINCT` 等で使われた場合、列挙型はInt8, Int16であるかのように振る舞います。例えば、 `ORDER BY` は数値としてソートします。等価演算子と比較演算子の場合もInt8,Int16であるかのように振る舞います。

列挙型は数値と比較する事は出来ません。(定義されたものと同じ)文字列と比較できます。比較する文字列がEnumで定義されてない場合、例外を投げます。 `IN` 演算子は左側のEnumと右側の文字列でサポートされています。文字列は定義されたEnumの値に限ります。

ほとんどの数値演算、文字列演算はEnum値に対して適用できません。列挙型に数値を追加するか、文字列を列挙型に連結します。(?) Enumには、文字列型に変換するtoString関数があります。

列挙型の値は、toT関数を使用して数値型に変換する事も出来ます。ここでのTは数値型です。Tが列挙型の元となる数値型に対応する場合、この変換はゼロコストです。列挙型のセットを変更する場合、ALTERを使用してコスト無しに変更できます。(削除する場合、削除する値がテーブルで使用されてない場合のみ安全です)セーフガードとして、以前定義されたEnumの数値を変更すると例外を投げます。

ALTERを使用するとEnum8をEnum16に変更したり、Enum16をEnum8に変更できます。


## Array(T)

配列型。配列には任意の型を用いる事が出来ます。多次元配列はサポートが不十分なので、利用は推奨しません。(例えば、MergeTreeエンジンのテーブルに多次元配列を格納する事は出来ません。)


## AggregateFunction(name, types_of_arguments...)

aggregate関数の中間状態。それを得るには、 '-State' サフィックスのある aggregate関数を使う必要があります。より詳しい情報は、 "AggregatingMergeTree" の項を参照。

## Tuple(T1,T2,...)

タプルは(MemoryTable以外の)テーブルに書き込む事は出来ません。これらは、一時な列のグループ化に使用されます。 `IN` 式がクエリで使用されるとき、及びラムダ関数の特定の仮パラメータを指定するときに、列をグループ化できます。より詳しい情報は、 "IN operators" と "Higher order functions" を参照してください。

クエリーの実行結果としてタプルを出力する事が出来ます。この場合、JSON以外のテキスト形式の場合、値はカンマで区切られます。JSON形式では、タプルは配列として出力されます。

## Nested(Name1 Type1, Name2 Type2, ...)

ネストされたデータ構造。省略。

## Expression

高次関数でのラムダ式の表現に使用されます。

## Set

`IN` 式の右側で使用されます。