メインコンテンツへスキップ
ClickHouseはJSONデータの構造を自動的に推定できます。これにより、たとえばディスク上やS3バケット内のJSONデータをclickhouse-localで直接クエリしたり、ClickHouseにデータをロードする前にスキーマを自動的に作成したりできます。

型推論を使用する場合

  • 構造が一定している - 型を推論しようとしているデータに、必要なすべてのキーが含まれている場合です。型推論は、データを最大行数または最大バイト数までサンプリングして行われます。サンプル範囲より後のデータに追加のカラムがあっても、それらは無視されるためクエリできません。
  • 型が一定している - 特定のキーのデータ型には互換性が必要です。つまり、ある型から別の型へ自動的に型変換できる必要があります。
より動的な JSON で、新しいキーが追加され、同じパスに対して複数の型を取りうる場合は、「半構造化データと動的データの操作」を参照してください。

型の検出

以下では、JSON の構造が一貫しており、各パスに対応する型が 1 つだけであることを前提とします。 これまでの例では、NDJSON フォーマットの Python PyPI dataset の簡易版を使用してきました。この節では、より複雑な入れ子構造を持つデータセット、つまり 250 万件の学術論文を含む arXiv dataset を見ていきます。NDJSON として配布されるこのデータセットでは、各行が公開済みの学術論文 1 件を表します。行の例を以下に示します。
このデータには、前の例よりもはるかに複雑なスキーマが必要です。以下では、このスキーマを定義するプロセスの概要を示し、TupleArray などの複雑な型を導入します。 このデータセットは、s3://datasets-documentation/arxiv/arxiv.json.gz にある公開 S3 バケットに保存されています。 上記のデータセットには、ネストされた JSON オブジェクトが含まれていることがわかります。スキーマは作成してバージョン管理すべきですが、スキーマ推論を使うと、データから型を推論できます。これにより、スキーマ DDL を自動生成できるため、手動で作成する必要がなくなり、開発プロセスを高速化できます。
フォーマットの自動検出スキーマの検出に加えて、JSON スキーマ推論では、ファイル拡張子と内容からデータのフォーマットも自動的に推論します。その結果、上記のファイルは自動的に NDJSON として検出されます。
s3 関数DESCRIBE コマンドとともに使用すると、推論される型を確認できます。
NULL を避ける多くのカラムが Nullable として検出されていることがわかります。Nullable 型は、どうしても必要な場合を除いて使用しないことを推奨します。Nullable を適用するタイミングの挙動は、schema_inference_make_columns_nullable で制御できます。
ほとんどのカラムは自動的に String として検出され、update_date カラムは正しく Date として検出されています。versions カラムはオブジェクトのリストを格納するために Array(Tuple(created String, version String)) として作成され、authors_parsed はネストされた配列を表す Array(Array(String)) として定義されています。
型推論の制御日付および日時の自動検出は、それぞれ設定 input_format_try_infer_datesinput_format_try_infer_datetimes で制御できます (いずれもデフォルトで有効です) 。オブジェクトをタプルとして推論するかどうかは、設定 input_format_json_try_infer_named_tuples_from_objects で制御されます。数値の自動検出など、JSON のスキーマ推論を制御するその他の設定については、こちら を参照してください。

JSON のクエリ

以下では、JSON が一貫した構造を持ち、各 パス ごとに型が 1 つだけであることを前提としています。 スキーマ推論を利用すれば、JSON データをそのままクエリできます。以下では、日付と配列が自動的に検出されることを利用して、年ごとの上位の著者を求めます。
スキーマ推論により、スキーマを指定しなくてもJSONファイルをクエリでき、アドホックなデータ分析を迅速化できます。

テーブルの作成

スキーマ推論を利用して、テーブルのスキーマを作成できます。次の CREATE AS EMPTY コマンドを実行すると、テーブルの DDL が推論され、テーブルが作成されます。この操作ではデータは読み込まれません。
テーブルのスキーマを確認するには、SHOW CREATE TABLE コマンドを使用します。
上記がこのデータの正しいスキーマです。スキーマ推論は、データをサンプリングしながら1行ずつ読み取って行われます。カラムの値はフォーマットに従って抽出され、各値の型を判定するために再帰的なパーサーとヒューリスティクスが使用されます。スキーマ推論でデータから読み取る行数とバイト数の上限は、設定 input_format_max_rows_to_read_for_schema_inference (デフォルトは25000) と input_format_max_bytes_to_read_for_schema_inference (デフォルトは32MB) で制御されます。検出結果が正しくない場合は、こちら に記載されているようにヒントを指定できます。

スニペットからテーブルを作成する

上の例では、S3 上のファイルを使ってテーブルのスキーマを作成しています。1 行だけのスニペットからスキーマを作成したい場合もあるでしょう。その場合は、以下のように format 関数を使用します。

JSON データの取り込み

以下では、JSON が一貫した構造を持ち、各パスに対して型が 1 つだけであることを前提としています。 前のコマンドで、データを取り込めるテーブルを作成しました。これで、次の INSERT INTO SELECT を使ってデータをテーブルに挿入できます。
ファイルなどのほかのソースからデータを読み込む例については、こちらを参照してください。 読み込み後はデータをクエリできます。必要に応じてフォーマット PrettyJSONEachRow を使用すると、行を元の構造のまま表示できます。

エラーへの対処

不正なデータが含まれることがあります。たとえば、型が合っていない特定のカラムや、フォーマットが不正な JSON オブジェクト などです。このような場合、データによって insert エラーが発生しても一定数の行を無視できるように、設定 input_format_allow_errors_numinput_format_allow_errors_ratio を使用できます。さらに、推論を補助するために hints を指定することもできます。

半構造化データと動的データの操作

前の例では JSON を使用しましたが、そこではキー名と型があらかじめ決まっている静的なものでした。しかし、実際にはそうでないことがよくあります。キーが追加されたり、キーの型が変わったりすることがあります。これはオブザーバビリティデータのようなユースケースでは一般的です。 ClickHouse では、専用の JSON 型によってこれに対応しています。 JSON が非常に動的で、一意なキーが多く、同じキーに複数の型が現れることが分かっている場合は、JSONEachRow でスキーマ推論を使い、各キーに対応するカラムを推論しようとすることは推奨しません。データが改行区切りの JSON フォーマットであっても同様です。 次の例では、上記の Python PyPI dataset を拡張したデータセットを使用します。ここでは、ランダムなキーと値のペアを持つ任意の tags カラムを追加しています。
このデータのサンプルは、改行区切りの JSON フォーマットで一般公開されています。このファイルに対してスキーマ推論を試みると、応答が極めて冗長になるため、パフォーマンスがあまり良くないことがわかります。
ここでの主な問題は、推論に JSONEachRow フォーマットが使われていることです。これは JSON の各キーごとにカラム型を 1 つ推論 しようとするもので、つまり JSON 型を使わずに、データに静的なスキーマを適用しようとしていることになります。 一意なカラムが数千もある場合、この推論方法では時間がかかります。代わりに、JSONAsObject フォーマットを使用できます。 JSONAsObject は入力全体を 1 つの JSON オブジェクトとして扱い、JSON 型の単一カラムに格納するため、動的に変化しやすい JSON ペイロードやネストされた JSON ペイロードにより適しています。
このフォーマットは、カラムに相互に整合しない複数の型がある場合にも不可欠です。たとえば、以下のような改行区切りのJSONを含む sample.json ファイルを考えてみましょう。
この場合、ClickHouse は型の競合を吸収し、カラム aNullable(String) として扱えます。
型変換この型変換は、いくつかの設定で制御できます。上記の例は、設定 input_format_json_read_numbers_as_strings に依存しています。
ただし、一部の型同士には互換性がありません。次の例を見てみましょう。
この場合、ここで型変換を行うことはできません。そのため、DESCRIBE コマンドは失敗します。
この場合、JSONAsObject は各行を単一の JSON 型 (同じカラムに複数の型を持たせることをサポート) として扱います。これは不可欠です。

関連情報

データ型推論の詳細については、こちらのドキュメントを参照してください。
最終更新日 2026年6月12日