ON CLUSTER 句によって実現されており、これについては別途説明しています。
構文の形式
明示的なスキーマを指定する場合
db が設定されている場合は db データベースに、設定されていない場合は現在のデータベースに、括弧内で指定した構造と engine エンジンを持つ table_name という名前のテーブルを作成します。
テーブルの構造は、カラム定義、セカンダリ索引、プロジェクション、および制約の一覧です。主キー が engine でサポートされている場合は、テーブルエンジンのパラメータとして示されます。
最も単純な場合、カラム定義は name type です。例: RegionID UInt32。
デフォルト値用の式も定義できます (下記を参照) 。
必要に応じて、1 つ以上のキー式を使って主キーを指定できます。
カラムおよびテーブルにコメントを追加できます。
既存テーブルのスキーマを使う場合
既存テーブルのスキーマとデータを使用する場合
db.table のすべてのパーティションがそのテーブルにアタッチされます。つまり、db.table のデータは作成時に db2.table_clone に複製されます。このクエリは、次のものと同等です。
db.table) と同じエンジンが使用されます。
Table Function から
SELECT クエリから
SELECT クエリの結果と同様の構造を持つテーブルを engine エンジンで作成し、SELECT のデータを格納します。カラム定義を明示的に指定することもできます。
テーブルがすでに存在し、IF NOT EXISTS が指定されている場合、このクエリは何も実行しません。
クエリでは、ENGINE 句の後にほかの句を続けることもできます。テーブルの作成方法の詳細については、テーブルエンジン の説明を参照してください。
例
Query
Response
NULL または NOT NULL 修飾子
NULL および NOT NULL 修飾子を付けることで、その型を Nullable にできるかどうかを指定できます。
型が Nullable ではない場合、NULL を指定すると Nullable として扱われ、NOT NULL を指定した場合はそのまま Nullable にはなりません。たとえば、INT NULL は Nullable(INT) と同じです。型が Nullable であるにもかかわらず NULL または NOT NULL 修飾子を指定すると、例外がスローされます。
関連項目: data_type_default_nullable 設定。
デフォルト値
DEFAULT expr、MATERIALIZED expr、または ALIAS expr の形式でデフォルト値の式を指定できます。例: URLDomain String DEFAULT domain(URL)。
式 expr は省略可能です。省略した場合は、カラム型を明示的に指定する必要があります。その場合のデフォルト値は、数値カラムでは 0、文字列カラムでは '' (空文字列) 、配列カラムでは [] (空の配列) 、日付カラムでは 1970-01-01、Nullable カラムでは NULL になります。
デフォルト値を持つカラムでは、カラム型を省略でき、その場合は expr の型から推論されます。たとえば、EventDate DEFAULT toDate(EventTime) というカラムの型は date になります。
データ型とデフォルト値の式の両方が指定されている場合は、式を指定された型に変換する暗黙的な型キャスト関数が挿入されます。例: Hits UInt32 DEFAULT 0 は内部的には Hits UInt32 DEFAULT toUInt32(0) として表現されます。
デフォルト値の式 expr では、任意のテーブルカラムや定数を参照できます。ClickHouse は、テーブル構造の変更によって式の計算にループが生じないことを確認します。INSERT では、式を解決可能であること、つまり式の計算に必要なすべてのカラムが渡されていることを確認します。
DEFAULT
DEFAULT expr
通常のデフォルト値です。この種のカラムでは、値が INSERT クエリで指定されていない場合、expr から計算されます。
例:
MATERIALIZED
MATERIALIZED expr
マテリアライズ式です。このようなカラムの値は、行の挿入時に、指定されたマテリアライズ式に基づいて自動的に計算されます。INSERT 時に値を明示的に指定することはできません。
また、この型のデフォルト値カラムは、SELECT * の結果に含まれません。これは、SELECT * の結果を常に INSERT を使ってテーブルにそのまま挿入し直せるという不変条件を保つためです。この動作は、setting asterisk_include_materialized_columns を使用すると無効にできます。
例:
EPHEMERAL
EPHEMERAL [expr]
一時的なカラムです。この型のカラムはテーブルに保存されず、SELECT で取得することもできません。ephemeral カラムの唯一の用途は、これらを使って他のカラムのデフォルト値式を構築することです。
カラムを明示的に指定しない INSERT では、この型のカラムはスキップされます。これは、SELECT * の結果を常に INSERT を使ってテーブルにそのまま挿入し直せるという不変条件を保つためです。
例:
ALIAS
ALIAS expr
計算カラム (同義語) です。この型のカラムはテーブルに保存されず、これらに値を INSERT することはできません。
SELECT クエリでこの型のカラムを明示的に参照すると、値はクエリ時に expr から計算されます。デフォルトでは、SELECT * には ALIAS カラムは含まれません。この動作は、設定 asterisk_include_alias_columns によって無効にできます。
ALTER クエリを使って新しいカラムを追加しても、それらのカラムについて古いデータは書き込まれません。代わりに、新しいカラムの値を持たない古いデータを読み取る際には、デフォルトで式がその場で計算されます。ただし、その式の実行にクエリ内で指定されていない別のカラムが必要な場合は、それらのカラムも追加で読み取られますが、必要なデータブロックに対してのみ行われます。
テーブルに新しいカラムを追加したあとでそのデフォルト式を変更すると、古いデータに対して使われる値も変わります (ディスクに値が保存されていないデータについて) 。バックグラウンドマージの実行時には、マージ対象のいずれかのパーツに存在しないカラムのデータは、マージ後のパーツに書き込まれる点に注意してください。
ネストされたデータ構造内の要素には、デフォルト値を設定できません。
テーブルの作成時に主キーを定義できます。主キーは、次の2つの方法で指定できます。
- カラムの一覧内
- カラムリストの外
制約
CONSTRAINT
boolean_expr_1 には任意のブール式を指定できます。テーブルに制約が定義されている場合、INSERT クエリの各行に対してそれぞれの制約がチェックされます。いずれかの制約が満たされていない場合、サーバーは制約名とチェック式を含む例外を返します。
大量の制約を追加すると、大規模な INSERT クエリのパフォーマンスに悪影響を及ぼす可能性があります。
ASSUME
ASSUME 句は、真であると仮定される table に対する CONSTRAINT を定義するために使用されます。この制約は、その後オプティマイザによって SQL queries のパフォーマンス向上に利用されます。
users_a table の作成時に ASSUME CONSTRAINT が使われている次の例を見てみましょう。
ASSUME CONSTRAINT を使って、length(name) 関数が常に name_len カラムの値と等しいことを前提としていることを示しています。つまり、クエリ内で length(name) が呼び出されるたびに、ClickHouse はそれを name_len に置き換えることができます。これにより length() 関数を呼び出さずに済むため、通常はそのほうが高速です。
そのため、クエリ SELECT name FROM users_a WHERE length(name) < 5; を実行する際、ClickHouse は ASSUME CONSTRAINT に基づいて、これを SELECT name FROM users_a WHERE name_len < 5; に最適化できます。これにより、各行ごとに name の長さを計算する必要がなくなるため、クエリの実行速度が向上する可能性があります。
ASSUME CONSTRAINT は制約を強制するものではありません。これは、その制約が成り立つことをオプティマイザに知らせるだけです。制約が実際には成り立っていない場合、クエリの結果が不正確になる可能性があります。したがって、ASSUME CONSTRAINT は、その制約が正しいと確信できる場合にのみ使用してください。
有効期限 (TTL) 式
カラム圧縮コーデック
lz4 圧縮を使用し、ClickHouse Cloud では zstd を使用します。
MergeTree エンジンファミリーでは、サーバー設定の compression セクションでデフォルトの圧縮方式を変更できます。
また、CREATE TABLE クエリで、個々のカラムごとに圧縮方式を定義することもできます。
Default コーデック は、実行時のさまざまな設定 (およびデータの特性) に応じて変わる可能性があるデフォルトの圧縮を参照するために指定できます。
例: value UInt64 CODEC(Default) — コーデック を指定しないのと同じです。
また、カラムから現在の CODEC を削除して、config.xml で設定されたデフォルトの圧縮を使用することもできます。
CODEC(Delta, Default) のように指定します。
圧縮は、次のテーブルエンジンでサポートされています。
- MergeTree ファミリー。カラム圧縮コーデックと、compression 設定によるデフォルトの圧縮方式の選択をサポートします。
- Log ファミリー。デフォルトで
lz4圧縮方式を使用し、カラム圧縮コーデックをサポートします。 - Set。デフォルトの圧縮のみをサポートします。
- Join。デフォルトの圧縮のみをサポートします。
汎用コーデック
NONE
NONE — 圧縮なし。
LZ4
LZ4 — デフォルトで使用される可逆なデータ圧縮アルゴリズムです。LZ4の高速圧縮を適用します。
LZ4HC
LZ4HC[(level)] — レベルを設定可能な LZ4 HC (高圧縮) アルゴリズム。デフォルトレベルは 9 です。level <= 0 を指定すると、デフォルトレベルが適用されます。指定可能なレベル: [1, 12]。推奨レベル範囲: [4, 9]。
ZSTD
ZSTD[(level)] — levelを設定可能なZSTD圧縮アルゴリズムです。指定可能なレベル: [1, 22]。デフォルトレベル: 1。
高い圧縮レベルは、一度圧縮して何度も展開するような非対称なシナリオで有効です。レベルが高いほど圧縮率は向上しますが、その分CPU使用量も増加します。
廃止された: ZSTD_QAT
廃止された: DEFLATE_QPL
特殊なコーデック
Delta
Delta(delta_bytes) — 最初の値を除き、元の値を隣り合う 2 つの値の差に置き換える圧縮方式です。最初の値はそのまま保持されます。delta_bytes は元の値の最大サイズで、デフォルト値は sizeof(type) です。引数として delta_bytes を指定することは非推奨であり、今後のリリースでサポートは削除される予定です。Delta はデータ準備用のコーデックであり、単独では使用できません。
DoubleDelta
DoubleDelta(bytes_size) — 差分の差分を計算し、compact バイナリ形式で書き込みます。bytes_size は、Delta コーデック の delta_bytes と同様の意味を持ちます。引数として bytes_size を指定することは非推奨であり、今後のリリースでサポートが削除される予定です。最適な圧縮率は、時系列データのように一定の刻み幅を持つ単調なシーケンスで得られます。任意の数値型で使用できます。Gorilla TSDB で使われているアルゴリズムを実装しており、64 ビット型をサポートするように拡張しています。32 ビットの差分には追加で 1 ビットを使用します。つまり、4 ビットのプレフィックスではなく 5 ビットのプレフィックスを使用します。詳細については、Gorilla: A Fast, Scalable, In-Memory Time Series Database の Compressing Time Stamps を参照してください。DoubleDelta はデータ準備用の コーデック であるため、単体では使用できません。
GCD
GCD() - - カラム内の値の最大公約数 (GCD) を計算し、各値をその GCD で割ります。整数、小数、日付/時刻のカラムで使用できます。この コーデック は、値が GCD の倍数単位で変化 (増加または減少) するカラム (例: 24, 28, 16, 24, 8, 24 (GCD = 4) ) に適しています。GCD はデータ準備用の コーデック であり、単独では使用できません。
Gorilla
Gorilla(bytes_size) — 現在の浮動小数点値と直前の値との XOR を計算し、それをコンパクトなバイナリ形式で書き込みます。連続する値同士の差が小さいほど、つまり時系列の値の変化が緩やかなほど、圧縮率は高くなります。Gorilla TSDB で使用されているアルゴリズムを実装しており、64 ビット型をサポートするように拡張されています。bytes_size に指定できる値は 1、2、4、8 です。sizeof(type) が 1、2、4、8 のいずれかであれば、デフォルト値は sizeof(type) になります。それ以外の場合は 1 です。詳細については、Gorilla: A Fast, Scalable, In-Memory Time Series Database の 4.1 節を参照してください。
ALP
ALP() — 小数のスケーリングに基づく、浮動小数点データ向けの適応型可逆圧縮です。ALP は各値を 10 のべき乗による正確なスケーリング済み整数として表現し、得られた整数を Frame-of-Reference とビットパッキングで圧縮します。正確に表現できない値は、生の例外値として保存されます。小数に由来する数値 (例: 測定値、通貨) で特に効果を発揮します。Float32 と Float64 をサポートします。詳細は、ALP: Adaptive lossless floating-point compression を参照してください。
この コーデック は Experimental であり、使用するには
SET allow_experimental_codecs = 1 の設定が必要です。FPC
FPC(level, float_size) - 2 種類の予測器のうち、より適した方を使ってシーケンス内の次の浮動小数点値を繰り返し予測し、実際の値と予測値の XOR を取り、その結果に対して先頭のゼロを圧縮します。Gorilla と同様に、変化が緩やかな一連の浮動小数点値を格納する場合に効率的です。64 ビット値 (double) では FPC は Gorilla より高速ですが、32 ビット値では結果が異なる場合があります。指定可能な level の値は 1~28 で、デフォルト値は 12 です。指定可能な float_size の値は 4、8 で、type が Float の場合のデフォルト値は sizeof(type) です。それ以外のすべての場合は 4 です。アルゴリズムの詳細については、High Throughput Compression of Double-Precision Floating-Point Data を参照してください。
T64
T64 — 整数データ型 (Enum、Date、DateTime を含む) において、値の未使用の上位ビットを削る圧縮方式です。アルゴリズムの各ステップで、このコーデックは 64 個の値からなる block を取り、それらを 64x64 ビットの行列に配置して転置し、値の未使用ビットを削ったうえで、残りをシーケンスとして返します。未使用ビットとは、この圧縮の適用対象である data part 全体において、最大値と最小値の間で差が生じないビットのことです。
DoubleDelta と Gorilla コーデックは、Gorilla TSDB の圧縮アルゴリズムの構成要素として使用されています。Gorilla の方式は、timestamp を伴う、緩やかに変化する値のシーケンスがある場合に効果的です。timestamp は DoubleDelta コーデックによって効率よく圧縮され、値は Gorilla コーデックによって効率よく圧縮されます。たとえば、効率よく格納できる table を得るには、次の構成で作成できます。
暗号化コーデック
AES_128_GCM_SIV
CODEC('AES-128-GCM-SIV') — RFC 8452 の GCM-SIV モードを使用して、AES-128 でデータを暗号化します。
AES-256-GCM-SIV
CODEC('AES-256-GCM-SIV') — AES-256 を GCM-SIV モードで使用してデータを暗号化します。
これらのコーデックは固定ノンスを使用するため、暗号化は決定論的です。このため、ReplicatedMergeTree のような重複排除を行うエンジンと互換性がありますが、弱点もあります。同じデータブロックを 2 回暗号化すると、生成される暗号文はまったく同一になります。そのため、ディスクを読み取れる攻撃者は、その 2 つが同じであることを見分けられます (内容そのものは分からず、同一性だけが分かります) 。
“*MergeTree” ファミリーを含むほとんどのエンジンでは、コーデックを適用せずにディスク上へ索引ファイルが作成されます。つまり、暗号化されたカラムに索引がある場合、平文がディスク上に現れます。
暗号化されたカラム内の特定の値を指定する SELECT クエリを実行すると (WHERE 句など) 、その値が system.query_log に記録される可能性があります。ログを無効にすることを検討してください。
圧縮が必要な場合は、明示的に指定する必要があります。指定しない場合、データには暗号化のみが適用されます。
一時テーブル
一時テーブルはレプリケーションされない点に注意してください。そのため、一時テーブルに挿入されたデータが他のレプリカで利用可能である保証はありません。一時テーブルが主に役立つのは、単一のセッション中に小規模な外部データセットに対してクエリを実行したり、join したりする場合です。
- 一時テーブルは、接続が失われた場合を含め、セッションが終了すると削除されます。
- 一時テーブルでは、エンジンが指定されていない場合は Memory テーブルエンジンが使用され、Replicated および
KeeperMapエンジンを除く任意のテーブルエンジンを使用できます。 - 一時テーブルには DB を指定できません。データベースの外部に作成されます。
- 分散 DDL クエリを使って、クラスター内のすべてのサーバー上に一時テーブルを作成することはできません (
ON CLUSTERを使用) 。このテーブルは現在のセッション内にのみ存在します。 - 一時テーブルが別のテーブルと同じ名前を持ち、クエリで DB を指定せずにそのテーブル名を指定した場合は、一時テーブルが使用されます。
- 分散クエリ処理では、クエリ内で使用される Memory エンジンの一時テーブルはリモートサーバーに渡されます。
(GLOBAL) IN を使用する場合には作成されます。詳細については、該当するセクションを参照してください。
一時テーブルの代わりに、ENGINE = Memory を使用するテーブルを使うこともできます。
REPLACE TABLE
REPLACE ステートメントを使用すると、テーブルをアトミックに更新できます。
このステートメントは、
Atomic および Replicated データベースエンジンでサポートされています。
これらはそれぞれ、ClickHouse と ClickHouse Cloud のデフォルトのデータベースエンジンです。SELECT ステートメントでデータを投入してから、
古いテーブルを削除し、新しいテーブルをリネームします。
この方法は、以下の例で示しています。
REPLACE を使って同じ結果を得ることもできます:
構文
CREATE ステートメントのすべての構文形式は、このステートメントでも利用できます。存在しないテーブルに対して REPLACE を実行すると、エラーが発生します。例:
- ローカル
- Cloud
次のテーブルを考えます:また、
REPLACE ステートメントを使用すると、すべてのデータを消去できます:REPLACE ステートメントを使用してテーブルの構造を変更することもできます:COMMENT 句
COMMENT 句は、PARTITION BY、ORDER BY、ストレージ固有の SETTINGS など、ストレージ固有の句の後に指定する必要があります。COMMENT 句の後に解析されるのは、ストレージ関連の設定ではなく、max_threads などのクエリ固有の SETTINGS のみです。つまり、句の正しい順序は次のとおりです。ENGINE- ストレージ句
COMMENT- クエリ設定 (ある場合)
Query
Response