半構造化データ型

このトピックでは、Snowflakeでサポートされている半構造化データ型について説明します。

このトピックの内容:

データ型

次のデータ型は、半構造化データ(JSON、Avro、 ORC、Parquet、または XML)のインポートと操作に使用できる任意のデータ構造を表すために使用されます。Snowflakeは、パフォーマンスと効率を向上させるために、これらの型をドキュメントの効率的な圧縮された円柱バイナリ表現に内部的に保存します。これらのデータ型のストレージに対するSnowflakeの最適化は完全に透過的であり、セマンティクスにユーザーが目に見える変化は生じません。

VARIANT

タグ付きユニバーサル型の OBJECT や ARRAYなどは、他の型の値を最大サイズ16 MB で圧縮して保存できます。

任意のデータ型の値は、サイズ制限に従って、暗黙的に VARIANT 値にキャストできます。VARIANT 値(明示的なキャストなし)と NUMERIC 値が同じ型に強制されると、 NUMERIC 値は VARIANTにキャストされます。例:

var:json_path >= 56var:json_path >= 56::VARIANT にキャストされます

明示的なキャストを使用して、値を VARIANT データ型との間で変換できます。たとえば、値を VARIANT データ型に変換するには、 TO_VARIANT または expr::variant を使用します。バリアント型から値を変換するには、 expr::<data_type> を使用します。 <data_type> は、変換先のデータ型です(例: variant_col1::FLOAT)。以下のサンプルコードは、バリアントからバリアントへの変換を示しています。

CREATE TABLE varia (float1 FLOAT, v VARIANT, float2 FLOAT);
INSERT INTO varia (float1, v, float2) VALUES (1.23, NULL, NULL);
SELECT * FROM varia;
UPDATE varia SET v = TO_VARIANT(float1);  -- converts FROM a float TO a variant.
UPDATE varia SET float2 = v::FLOAT;       -- converts FROM a variant TO a float.
SELECT * FROM varia;

VARIANT null 値とは異なる VARIANT 値が欠落している( SQL NULL を含む)可能性があります。これは、半構造化データでnull値を表すために使用される実際の値です。VARIANT null は、それ自体と等しいと比較される真の値です。

VARIANT リレーショナルテーブルの列は、個別の物理列として保存されます。繰り返しキーとパスは、通常の SQL 属性と同様に、個別の物理列としてさらに保存されます。現在、これは配列に保存されているデータには当てはまりません。

ほとんどが規則的で、ネイティブ JSON 型(タイムスタンプではなく文字列と数字)のみを使用するデータの場合、リレーショナルデータと VARIANT 列のデータ操作のストレージとクエリのパフォーマンスは非常に似ています。日付やタイムスタンプなどの非ネイティブ値は、 VARIANT 列にロードされると文字列として格納されるため、これらの値に対する操作は、対応するデータ型のリレーショナル列に格納される場合よりも遅くなり、より多くのスペースを消費します。

OBJECT

キーと値のペアのコレクションを表すために使用されます。キーは空ではない文字列で、値は VARIANT 型の値です。Snowflakeは現在、明示的に入力されたオブジェクトをサポートしていません。

ARRAY

任意のサイズの密配列または疎配列を表すために使用されます。インデックスは負でない整数(最大2^31-1)で、値は VARIANT 型です。Snowflakeは現在、固定サイズの配列または特定の非 VARIANT 型の要素の配列をサポートしていません。

この最初の例は、 VARIANT、 ARRAY、および OBJECT データを含むテーブルでの DESC TABLE コマンドの出力を示しています。

CREATE OR REPLACE TABLE test_semi_structured(var VARIANT,
                                    arr ARRAY,
                                    obj OBJECT
                                    );

DESC TABLE test_semi_structured;

+------+---------+--------+-------+---------+-------------+------------+-------+------------+---------+
| name | type    | kind   | null? | default | primary key | unique key | check | expression | comment |
|------+---------+--------+-------+---------+-------------+------------+-------+------------+---------|
| VAR  | VARIANT | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    |
| ARR  | ARRAY   | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    |
| OBJ  | OBJECT  | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    |
+------+---------+--------+-------+---------+-------------+------------+-------+------------+---------+

この例は、テーブルに単純な値をロードする方法と、テーブルをクエリしたときにそれらの値がどのように見えるかを示しています。

テーブルを作成し、データをロードします。

CREATE TABLE demonstration1 (
    ID INTEGER,
    array1 ARRAY,
    variant1 VARIANT,
    object1 OBJECT
    );

INSERT INTO demonstration1 (id, array1, variant1, object1) 
  SELECT 
    1, 
    ARRAY_CONSTRUCT(1, 2, 3), 
    PARSE_JSON(' { "key1": "value1", "key2": "value2" } '),
    PARSE_JSON(' { "outer_key1": { "inner_key1A": "1a", "inner_key1B": "1b" }, '
              ||
               '   "outer_key2": { "inner_key2": 2 } } ')
    ;

INSERT INTO demonstration1 (id, array1, variant1, object1) 
  SELECT 
    1, 
    ARRAY_CONSTRUCT(1, 2, 3, NULL), 
    PARSE_JSON(' { "key1": "value1", "key2": NULL } '),
    PARSE_JSON(' { "outer_key1": { "inner_key1A": "1a", "inner_key1B": NULL }, '
              ||
               '   "outer_key2": { "inner_key2": 2 } '
              ||
               ' } ')
  ;

テーブルのデータを表示します。

SELECT * 
    FROM demonstration1;
+----+-------------+---------------------+--------------------------+
| ID | ARRAY1      | VARIANT1            | OBJECT1                  |
|----+-------------+---------------------+--------------------------|
|  1 | [           | {                   | {                        |
|    |   1,        |   "key1": "value1", |   "outer_key1": {        |
|    |   2,        |   "key2": "value2"  |     "inner_key1A": "1a", |
|    |   3         | }                   |     "inner_key1B": "1b"  |
|    | ]           |                     |   },                     |
|    |             |                     |   "outer_key2": {        |
|    |             |                     |     "inner_key2": 2      |
|    |             |                     |   }                      |
|    |             |                     | }                        |
|  1 | [           | {                   | {                        |
|    |   1,        |   "key1": "value1", |   "outer_key1": {        |
|    |   2,        |   "key2": null      |     "inner_key1A": "1a", |
|    |   3,        | }                   |     "inner_key1B": null  |
|    |   undefined |                     |   },                     |
|    | ]           |                     |   "outer_key2": {        |
|    |             |                     |     "inner_key2": 2      |
|    |             |                     |   }                      |
|    |             |                     | }                        |
+----+-------------+---------------------+--------------------------+

追加の半構造化データの使用例については、 半構造化データのクエリ をご参照ください。