メインコンテンツまでスキップ
メインコンテンツまでスキップ

JSON データ型

ガイドをお探しですか?

JSON型を使用する際の例、進んだ機能、考慮事項については、私たちのJSONベストプラクティスガイドをご覧ください。

詳しく読む


JSON型は、JavaScript Object Notation (JSON) ドキュメントを単一のカラムに格納します。

JSON型を使用する場合、及びこのページの例については、次のコマンドを使用してください:

しかし、ClickHouse Cloudを使用している場合、JSON型の使用を有効にするために最初にサポートに連絡する必要があります

注記

ClickHouse Open-Sourceでは、JSONデータ型はバージョン25.3でプロダクション準備完了とマークされています。以前のバージョンでは、この型を本番環境で使用することは推奨されません。

JSON型のカラムを宣言するには、次の構文を使用できます:

ここで、上記の構文のパラメータは次のように定義されています:

パラメータ説明デフォルト値
max_dynamic_paths1つのデータブロックで個別に保存できるパスの数を示すオプショナルパラメータ。これは、(例えば、MergeTreeテーブルの単一データパートで)個別に保存されます。

この制限を超えると、他のすべてのパスは1つの構造体にまとめて保存されます。
1024
max_dynamic_types1から255の間のオプショナルパラメータで、単一パスのカラムにDynamic型として保持されることのできる異なるデータ型の数を示します。

この制限を超えると、すべての新しい型はString型に変換されます。
32
some.path TypeNameJSON内の特定のパスのためのオプショナル型ヒント。これらのパスは常に指定された型でサブカラムとして保存されます。
SKIP path.to.skipJSONパース中にスキップすべき特定のパスに対するオプショナルヒント。こうしたパスはJSONカラムに保存されません。指定されたパスがネストされたJSONオブジェクトである場合、ネストされたオブジェクト全体がスキップされます。
SKIP REGEXP 'path_regexp'JSONパース中にパスをスキップするために使用される正規表現を持つオプショナルヒント。この正規表現に一致するすべてのパスはJSONカラムに保存されません。

JSONの作成

このセクションでは、JSONを作成するためのさまざまな方法を見ていきます。

テーブルカラム定義におけるJSONの使用

::JSONを使用したCAST

特別な構文::JSONを使用してさまざまな型をキャストすることが可能です。

StringからJSONへのCAST

TupleからJSONへのCAST

MapからJSONへのCAST

非推奨のObject('json')からJSONへのCAST

注記

JSONのパスは平坦化されて保存されます。これは、a.b.cのようなパスからJSONオブジェクトがフォーマットされる場合、そのオブジェクトが{ "a.b.c" : ... }として構築されるべきか、{ "a" : {"b" : {"c" : ... }}}として構築されるべきかを知ることが不可能であることを意味します。私たちの実装は常に後者を想定します。

例えば:

は次のように返します:

そして決して:

JSONパスをサブカラムとして読む

JSON型は、すべてのパスを別々のサブカラムとして読むことをサポートしています。 要求されたパスの型がJSON型宣言で指定されていない場合、パスのサブカラムは常に型Dynamicを持ちます。

例えば:

要求されたパスがデータ内に見つからなかった場合、それはNULL値で埋め込まれます:

返されたサブカラムのデータ型を確認しましょう:

ご覧のように、a.bについては、私たちがJSON型宣言で指定した通りにUInt32型です。 他のすべてのサブカラムの型はDynamicです。

特別な構文json.some.path.:TypeNameを使用して、Dynamic型のサブカラムを読むことも可能です:

Dynamicサブカラムは任意のデータ型にキャストできます。この場合、Dynamic内の内部型が要求された型にキャストできない場合は例外がスローされます:

JSONサブオブジェクトをサブカラムとして読む

JSON型は、特別な構文json.^some.pathを使用して、型JSONとしてネストされたオブジェクトをサブカラムとして読むことをサポートしています:

注記

サブオブジェクトをサブカラムとして読むことは、効率が悪い可能性があります。これは、JSONデータ全体をほぼフルスキャンする必要があるからです。

パスの型推論

JSONの解析中、ClickHouseは各JSONパスに最も適切なデータ型を検出しようとします。 これは、入力データからの自動スキーマ推論と似たように機能し、次の設定で制御されます:

いくつかの例を見てみましょう:

JSONオブジェクトの配列を処理する

オブジェクトの配列を含むJSONパスは、型Array(JSON)として解析され、パスのDynamicカラムに挿入されます。 オブジェクトの配列を読むには、それをDynamicカラムからサブカラムとして抽出できます:

ご覧のとおり、ネストされたJSON型のmax_dynamic_types/max_dynamic_pathsパラメータは、デフォルト値と比較して減少しています。 これは、ネストされたJSONオブジェクトの配列で異なるサブカラムの数が無限に増えるのを避けるために必要です。

ネストされたJSONカラムからサブカラムを読み取ってみましょう:

Array(JSON)のサブカラム名を記述する際、特別な構文を使用して[]の記述を省略できます:

[]の数は、配列のレベルを示します。例えば、json.path[][]json.path.:Array(Array(JSON))に変換されます。

Array(JSON)内のパスと型を確認しましょう:

Array(JSON)カラムからサブカラムを読み取ってみましょう:

ネストされたJSONカラムからサブオブジェクトのサブカラムも読み取ることができます:

データからのJSON型の読み取り

すべてのテキスト形式 (JSONEachRowTSVCSVCustomSeparatedValues、など)は、JSON型の読み取りをサポートしています。

例:

テキスト形式でのJSONは、JSONオブジェクトを含む文字列から解析されます:

JSON内の動的パスの限界に達する

JSONデータ型は、内部で別々のサブカラムとして保存できるパスの数に限りがあります。 デフォルトでこの上限は1024ですが、型宣言内でパラメータmax_dynamic_pathsを使用して変更できます。

制限に達すると、JSONカラムに挿入されるすべての新しいパスは、単一の共有データ構造に保存されます。 こうしたパスはサブカラムとして読み取ることができますが、値を抽出するために共有データ構造全体を読み取る必要があります。 この制限は、テーブルを使用不能にすることがある大量の異なるサブカラムが発生するのを避けるために必要です。

制限に達した場合に何が起こるかを、いくつかの異なるシナリオで見てみましょう。

データ解析中に制限に達する

データからJSONオブジェクトを解析する際、現在のデータブロックの制限に達すると、すべての新しいパスは共有データ構造に保存されます。 次の2つのイントロスペクション関数JSONDynamicPathsJSONSharedDataPathsを使用できます:

ご覧のとおり、ef.gというパスが挿入された後、制限に達し、共有データ構造に挿入されました。

MergeTreeテーブルエンジンにおけるデータパーツのマージ中

MergeTree テーブルで複数のデータパーツをマージする際、結果のデータパーツにおける JSON カラムは動的パスの制限に達し、ソースパーツからのすべてのパスをサブカラムとして保存できなくなります。この場合、ClickHouseはマージ後にどのパスがサブカラムとして残り、どのパスが共有データ構造に保存されるかを選択します。ほとんどの場合、ClickHouseは非NULL値の数が最も多いパスを保持し、最も希少なパスを共有データ構造に移動させます。ただし、これは実装に依存します。

このようなマージの例を見てみましょう。まず、JSON カラムを持つテーブルを作成し、動的パスの制限を 3 に設定し、次に 5 つの異なるパスを持つ値を挿入します:

各挿入は、JSON カラムに単一のパスを含む別々のデータパーツを作成します:

さて、すべてのパーツを1つにマージし、何が起こるかを見てみましょう:

ご覧のように、ClickHouseは最も頻繁に出現するパスである abc を保持し、de のパスを共有データ構造に移動しました。

内部調査関数

JSON カラムの内容を検査するのに役立つ関数がいくつかあります:

2020-01-01 の日付に対する GH Archive データセットの内容を調査しましょう:

ALTER MODIFY COLUMNを使用してJSON型に変更

既存のテーブルを変更し、カラムの型を新しい JSON 型に変更することができます。現在、String 型からの ALTER のみがサポートされています。

JSON型の値の比較

JSONオブジェクトは、マップと同様に比較されます。

例えば:

注意: 2つのパスが異なるデータ型の値を含む場合、それらは Variant データ型の比較規則に従って比較されます。

JSON型のより良い使用のためのヒント

JSON カラムを作成し、データをロードする前に、以下のヒントを考慮してください:

  • データを調査し、できるだけ多くのパスヒントとタイプを指定してください。これにより、ストレージと読み取りがはるかに効率的になります。
  • 必要なパスと決して必要ないパスについて考えます。必要ないパスは、SKIP セクション、SKIP REGEXP セクションに指定してください。これにより、ストレージが改善されます。
  • max_dynamic_paths パラメータを非常に高い値に設定しないでください。これは、ストレージと読み取りの効率を低下させる可能性があります。 システムパラメータ(メモリ、CPUなど)に依存するため、一般的な目安として max_dynamic_paths > 10 000 に設定しないことをお勧めします。

さらなる情報