반정형 데이터 타입

다른 데이터 타입이 포함될 수 있는 Snowflake 데이터 타입은 다음과 같습니다.

  • VARIANT(기타 데이터 타입만 포함 가능).

  • ARRAY(VARIANT를 직접 포함할 수 있으므로, 자체를 포함하여 다른 모든 데이터 타입을 간접적으로 포함 가능).

  • OBJECT(VARIANT를 직접 포함할 수 있으므로, 자체를 포함하여 다른 모든 데이터 타입을 간접적으로 포함 가능).

이러한 데이터 타입을 반정형 데이터 타입이라고 합니다. 엄밀히 말하면, OBJECT는 진정한 반정형 데이터 타입 의 모든 특성을 자체적으로 갖는 이러한 데이터 타입 중 유일한 타입입니다. 그러나 이러한 데이터 타입을 결합하면 임의의 계층적 데이터 구조 를 명시적으로 나타내어, 반정형 형식의 데이터(예: JSON, Avro, ORC, Parquet 또는 XML)를 로딩하고 작동하기 위해 사용할 수 있습니다.

이러한 각 데이터 타입에 대한 설명은 아래에서 제공됩니다.

이 항목의 내용:

VARIANT

VARIANT의 특성

VARIANT는 OBJECT 및 ARRAY 등 기타 타입의 값을 저장할 수 있습니다.

VARIANT의 최대 길이는 16MB입니다.

VARIANT에서 변수 사용하기

값을 VARIANT 데이터 타입에서/으로 변환하려면 CAST 함수, TO_VARIANT 함수 또는 :: 연산자(예: expression::variant)를 사용하여 명시적으로 캐스팅할 수 있습니다.

어떤 상황에서는 값을 VARIANT로 암시적으로 캐스팅할 수 있습니다. 자세한 내용은 데이터 타입 변환 섹션을 참조하십시오.

아래 샘플 코드는 VARIANT에서 변환하는 방법과 VARIANT로 변환하는 방법을 비롯해, VARIANT를 사용하는 방법을 보여줍니다.

테이블을 만들고 값을 삽입합니다.

CREATE TABLE varia (float1 FLOAT, v VARIANT, float2 FLOAT);
INSERT INTO varia (float1, v, float2) VALUES (1.23, NULL, NULL);

첫 번째 UPDATE에서는 값을 FLOAT에서 VARIANT로 변환합니다. 두 번째 UPDATE에서는 값을 VARIANT에서 FLOAT로 변환합니다.

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합니다.

SELECT * FROM varia;
+--------+-----------------------+--------+
| FLOAT1 | V                     | FLOAT2 |
|--------+-----------------------+--------|
|   1.23 | 1.230000000000000e+00 |   1.23 |
+--------+-----------------------+--------+

VARIANT 데이터 타입에서 값을 변환하려면 변환할 데이터 타입을 지정합니다. 예를 들어, 다음 문에서는 :: 연산자를 사용하여 VARIANT를 FLOAT로 변환해야 하는 것으로 지정합니다.

SELECT my_variant_column::FLOAT * 3.14 FROM ...;

VARIANT는 값 및 값의 데이터 타입을 모두 저장합니다. 이렇게 하면 VARIANT를 먼저 캐스팅하지 않고도 값의 데이터 타입이 유효한 식에서 VARIANT 값을 사용할 수도 있습니다. 예를 들어, VARIANT 열 my_variant_column 에 숫자 값이 포함된 경우 my_variant_column 에 다른 숫자 값을 직접 곱할 수 있습니다.

SELECT my_variant_column * 3.14 FROM ...;

값의 네이티브 데이터 타입은 TYPEOF 함수를 사용하여 검색할 수 있습니다.

기본적으로 VARCHAR, DATE, TIME, TIMESTAMP가 VARIANT 열에서 검색될 때 값은 큰따옴표로 묶입니다. 값을 기본 데이터 타입으로 명시적으로 캐스팅하여(예: VARIANT에서 VARCHAR로) 큰따옴표를 제거할 수 있습니다. 예:

SELECT 'Sample', 'Sample'::VARIANT, 'Sample'::VARIANT::VARCHAR;
+----------+-------------------+----------------------------+
| 'SAMPLE' | 'SAMPLE'::VARIANT | 'SAMPLE'::VARIANT::VARCHAR |
|----------+-------------------+----------------------------|
| Sample   | "Sample"          | Sample                     |
+----------+-------------------+----------------------------+

VARIANT 값이 누락될 수 있습니다(SQL NULL 포함). 이는 반정형 데이터에서 null 값을 나타내는 데 사용되는 실수 값인 VARIANT null 값과는 다릅니다. VARIANT null 은 비교 결과 자신과 똑같은 true 값입니다. 자세한 내용은 VARIANT null 을 참조하십시오.

데이터가 JSON 형식에서 로딩되고 VARIANT에 저장되는 경우에 적용되는 지침은 다음과 같습니다.

  • 주로 일반 데이터로서 기본 JSON 형식(타임스탬프가 아닌 문자열과 숫자)만 사용하는 데이터의 경우, 관계형 데이터와 VARIANT 열의 데이터에 대한 작업을 위한 저장소와 쿼리 성능이 모두 매우 유사합니다. 그러나 날짜 및 타임스탬프와 같이 기본이 아닌 값은 VARIANT 열에 로딩될 때 문자열로 저장되므로, 이러한 값에 대한 작업은 해당 데이터 타입으로 관계형 열에 저장할 때보다 속도가 느려지고 공간도 더 많이 사용될 수 있습니다.

VARIANT 사용에 대한 자세한 내용은 VARIANT로 저장된 반정형 데이터에 대한 고려 사항 섹션을 참조하십시오.

VARIANT에 저장된 반정형 데이터 쿼리에 대한 자세한 내용은 반정형 데이터 쿼리하기 섹션을 참조하십시오.

VARIANT 삽입의 예

VARIANT 데이터를 직접 삽입하려면 IIS(INSERT INTO ... SELECT)를 사용하십시오. 아래 예제에서는 JSON 형식의 데이터를 VARIANT에 삽입하는 방법을 보여줍니다.

INSERT INTO varia (v) 
    SELECT TO_VARIANT(PARSE_JSON('{"key3": "value3", "key4": "value4"}'));

VARIANT의 일반적인 용도

VARIANT는 일반적으로 다음의 경우에 사용됩니다.

  • 둘 이상의 ARRAY 또는 OBJECT를 포함하는 계층을 명시적으로 정의하여 계층 구조 데이터 를 생성하려고 합니다.

  • 데이터의 계층 구조를 명시적으로 설명하지 않고 JSON, Avro, ORC 또는 Parquet 데이터를 직접 로딩하려고 합니다.

    Snowflake는 JSON, Avro, ORC 또는 Parquet 형식의 데이터를 ARRAY, OBJECT 및 VARIANT 데이터의 내부 계층 구조로 자동 변환하고 해당 계층 구조 데이터를 VARIANT에 직접 저장할 수 있습니다. 데이터 계층 구조를 스스로 수동으로 구성할 수도 있지만, 일반적으로 Snowflake가 자동으로 이 작업을 수행하도록 하는 것이 더 쉽습니다.

    반정형 데이터의 로딩과 변환에 대한 자세한 내용은 반정형 데이터 로드하기 섹션을 참조하십시오.

OBJECT

Snowflake OBJECT는 JSON 《오브젝트》 와 유사합니다. 다른 프로그래밍 언어에서는 그러한 데이터 타입을 《딕셔너리》, 《해시》 또는 《맵》이라고 합니다.

OBJECT에는 키-값 페어가 포함됩니다.

OBJECT의 특성

Snowflake OBJECT에서 각 키는 VARCHAR이고 각 값은 VARIANT 입니다.

VARIANT는 다른 모든 데이터 타입을 저장할 수 있으므로, (다른 키-값 페어의) 다른 값은 기본 데이터 타입이 다를 수 있습니다. 예를 들어, OBJECT에는 VARCHAR 타입의 사람 이름과 INTEGER 타입의 연령이 있을 수 있습니다. 아래 예제에서는 이름과 나이가 모두 VARIANT로 캐스팅됩니다.

SELECT OBJECT_CONSTRUCT(
    'name', 'Jones'::VARIANT,
    'age',  42::VARIANT
    );

Snowflake는 현재 명시적으로 형식이 지정된 오브젝트를 지원하지 않습니다.

키-값 페어에서는 키는 빈 문자열이 아니어야 하며 키 또는 값 모두 NULL이 아니어야 합니다.

OBJECT의 최대 길이는 16MB입니다.

OBJECT에는 반정형 데이터 가 포함될 수 있습니다.

OBJECT를 사용하여 계층형 데이터 구조 를 생성할 수 있습니다.

OBJECT 상수

상수 (리터럴 이라고도 함)는 고정된 데이터 값을 나타냅니다. Snowflake는 상수를 사용하여 OBJECT 값을 지정하는 기능을 지원합니다. OBJECT 상수는 중괄호({})로 구분됩니다.

예를 들어 다음 코드 블록에는 두 OBJECT 상수가 표시되는데, 첫 번째는 빈 OBJECT이고 두 번째는 두 캐나다 주의 이름과 주도를 포함합니다.

{}

{ 'Alberta': 'Edmonton' , 'Manitoba': 'Winnipeg' }

다음 문에서는 OBJECT 상수와 OBJECT_CONSTRUCT 함수를 사용하여 동일한 작업을 수행합니다.

UPDATE my_table SET my_object = { 'Alberta': 'Edmonton' , 'Manitoba': 'Winnipeg' };

UPDATE my_table SET my_object = OBJECT_CONSTRUCT('Alberta', 'Edmonton', 'Manitoba', 'Winnipeg');

SQL 문에서는 (Snowflake SQL의 다른 곳에서처럼) 작은따옴표로 OBJECT 내부의 문자열 리터럴을 지정하지만, OBJECT 내부의 문자열 리터럴은 큰따옴표로 표시됩니다.

SELECT { 'Manitoba': 'Winnipeg' } AS province_capital;

+--------------------------+
| PROVINCE_CAPITAL         |
|--------------------------|
| {                        |
|   "Manitoba": "Winnipeg" |
| }                        |
+--------------------------+

키를 기준으로 OBJECT의 요소에 액세스하기

오브젝트에서 값을 검색하려면 아래와 같이 키를 대괄호 로 묶습니다.

select my_variant_column['key1'] from my_table;

콜론 연산자를 사용할 수도 있습니다. 다음 명령은 콜론을 사용하든 대괄호를 사용하든 결과가 동일함을 보여줍니다.

SELECT object_column['thirteen'],
       object_column:thirteen
    FROM object_example;
+---------------------------+------------------------+
| OBJECT_COLUMN['THIRTEEN'] | OBJECT_COLUMN:THIRTEEN |
|---------------------------+------------------------|
| 13                        | 13                     |
+---------------------------+------------------------+

콜론 연산자에 대한 자세한 내용은 :. 연산자를 사용하여 중첩 데이터에 액세스하는 방법을 설명하는 점 표기법 섹션을 참조하십시오.

OBJECT 삽입의 예

OBJECT 데이터를 직접 삽입하려면 IIS(INSERT INTO ... SELECT)를 사용하십시오.

다음 코드에서는 OBJECT_CONSTRUCT 함수를 사용하여 함수가 삽입하는 OBJECT를 생성합니다.

INSERT INTO object_example (object_column)
    SELECT OBJECT_CONSTRUCT('thirteen', 13::VARIANT, 'zero', 0::VARIANT);

다음 코드에서는 OBJECT 상수 를 사용하여 삽입할 OBJECT를 지정합니다.

INSERT INTO object_example (object_column)
    SELECT { 'thirteen': 13::VARIANT, 'zero': 0::VARIANT };

각각의 키-값 페어에서, 값은 명시적으로 VARIANT로 캐스팅되었습니다. 이러한 경우 명시적 캐스팅이 필요하지 않았습니다. Snowflake는 암시적으로 VARIANT로 캐스팅할 수 있습니다. (암시적 캐스팅에 대한 자세한 내용은 데이터 타입 변환 섹션을 참조하십시오.)

OBJECT의 일반적인 용도

OBJECT는 일반적으로 다음 중 1개 이상이 해당될 때 사용됩니다.

  • 문자열로 식별되는 여러 데이터 조각이 있는 경우. 예를 들어, 지역 이름으로 정보를 조회하려면 OBJECT를 사용할 수 있습니다.

  • 데이터에 대한 정보를 데이터와 함께 저장하고, 이름(키)은 단순히 구별되는 식별자가 아니라 의미가 있습니다.

  • 정보에는 자연스러운 순서가 없거나 키에서만 순서를 유추할 수 있습니다.

  • 데이터의 구조가 다양하거나 데이터가 불완전할 수 있습니다. 예를 들어, 일반적으로 제목, 저자 이름 및 출판일이 포함된 책의 카탈로그를 제작하려고 하지만 출판일을 모르는 경우에 OBJECT를 사용할 수 있습니다.

ARRAY

Snowflake ARRAY는 다른 많은 프로그래밍 언어에서의 배열과 유사합니다. ARRAY에는 0개 이상의 데이터 조각이 포함됩니다. 각 요소는 배열 내 위치를 지정하여 액세스합니다.

ARRAY의 특성

ARRAY의 각 값은 VARIANT 타입입니다. (VARIANT에는 기타 모든 데이터 타입의 값이 포함될 수 있습니다.)

다른 데이터 타입의 값은 VARIANT로 캐스팅한 후 배열에 저장할 수 있습니다. ARRAY_CONSTRUCT 등 ARRAY용 일부 함수는 사용자를 위해 값을 VARIANT로 암시적으로 캐스팅 할 수 있습니다.

ARRAYs는 VARIANT 값을 저장하고 VARIANT 값은 자체 내에 다른 데이터 타입을 저장할 수 있으므로 ARRAY에 포함된 값의 기본 데이터 타입은 같지 않아도 됩니다. 그러나 대부분의 경우 데이터 요소는 모두 동일한 방식으로 처리가 가능하도록 타입이 같거나 호환이 가능합니다.

Snowflake는 특정 VARIANT 외 타입의 요소 배열을 지원하지 않습니다.

Snowflake ARRAY는 요소의 개수를 지정하지 않고 선언됩니다. ARRAY는 ARRAY_APPEND 등의 연산을 통해 동적으로 증가할 수 있습니다. Snowflake는 현재 고정 크기 배열을 지원하지 않습니다.

ARRAY에는 NULL 값이 포함될 수 있습니다.

ARRAY에서 이론적으로 가능한 모든 값의 최대 결합 크기는 16 MB입니다. 그러나 ARRAYs에는 내부 오버헤드가 있습니다. 실제 최대 데이터 크기는 일반적으로 요소의 개수와 값에 따라 더 작습니다.

ARRAY 상수

상수 (리터럴 이라고도 함)는 고정된 데이터 값을 나타냅니다. Snowflake는 상수를 사용하여 ARRAY 값을 지정하는 기능을 지원합니다. ARRAY 상수는 대괄호([])로 구분됩니다.

예를 들어 다음 코드 블록에는 두 ARRAY 상수가 표시되는데, 첫 번째는 빈 ARRAY이고 두 번째는 두 캐나다 주의 이름을 포함합니다.

[]

[ 'Alberta', 'Manitoba' ]

다음 문에서는 ARRAY 상수와 ARRAY_CONSTRUCT 함수를 사용하여 동일한 작업을 수행합니다.

UPDATE my_table SET my_array = [ 1, 2 ];

UPDATE my_table SET my_array = ARRAY_CONSTRUCT(1, 2);

SQL 문에서는 (Snowflake SQL의 다른 곳에서처럼) 작은따옴표로 ARRAY 내부의 문자열 리터럴을 지정하지만, ARRAY 내부의 문자열 리터럴은 큰따옴표로 표시됩니다.

SELECT [ 'Alberta', 'Manitoba ] AS province;

+--------------+
| PROVINCE     |
|--------------|
| [            |
|   "Alberta", |
|   "Manitoba" |
| ]            |
+--------------+

인덱스 또는 슬라이스를 기준으로 ARRAY 요소에 액세스하기

배열 인덱스는 0에서 시작하며 배열의 첫 번째 요소는 요소 0입니다.

배열의 값은 대괄호 안에 배열 요소의 인덱스 번호를 지정하여 액세스할 수 있습니다. 예를 들어, 다음 쿼리에서는 my_array_column 에 저장된 배열의 인덱스 위치 2에 있는 값을 읽습니다.

select my_array_column[2] from my_table;

배열은 중첩될 수 있습니다. 다음 쿼리에서는 중첩 배열의 0번째 요소 중 0번째 요소를 읽습니다.

select my_array_column[0][0] from my_table;

배열의 끝을 초과하는 요소에 액세스를 시도하면 NULL이 반환됩니다.

배열의 슬라이스 는 인접 요소의 시퀀스, 즉 배열의 인접한 하위 세트입니다.

배열의 슬라이드에는 ARRAY_SLICE 함수를 호출하여 액세스할 수 있습니다. 예:

select array_slice(my_array_column, 5, 10) from my_table;

ARRAY_SLICE() 함수는 지정된 시작 요소(위의 예에서 5)부터 지정된 끝 요소(위의 예에서 10)가 포함되지 않은 요소까지의 요소를 반환합니다.

빈 배열이나 빈 슬라이스는 사이에 아무 것도 없는 한 쌍의 대괄호([])로 표시됩니다.

스파스 vs 밀집 ARRAY

배열은 밀집 또는 스파스 일 수 있습니다.

밀집 배열에서 요소의 인덱스 값은 0에서 시작하며 순차적입니다(0, 1, 2 등). 그러나 스파스 배열에서 인덱스 값은 비순차적일 수 있습니다(예: 0, 2, 5). 값은 0에서 시작하지 않아도 됩니다.

인덱스에 해당 요소가 없으면 해당 인덱스에 해당하는 값을 undefined 라고 합니다. 예를 들어, 스파스 배열에 3개의 요소가 있고 해당 요소가 인덱스 0, 2, 5에 있는 경우 인덱스 1, 3, 4에 있는 요소는 undefined 입니다.

   0            2                  5
+-----+.....+-------+.....+.....+------+
| Ann |     | Carol |     |     | Fred |
+-----+.....+-------+.....+.....+------+

         ^             ^     ^
         |             |     |
        undefined--------------

정의되지 않은 요소는 요소로 취급됩니다. 예를 들어, 인덱스 0, 2, 5에 요소가 있고 (인덱스 5 이후에는 요소가 없는) 스파스 배열의 이전 예를 생각해 보겠습니다. 인덱스 3 및 4의 요소가 포함된 슬라이스를 읽으면 다음과 유사한 출력이 제공됩니다.

[ undefined, undefined ]

배열 끝을 초과하는 슬라이스에 액세스를 시도하면 결과는 undefined 값의 배열이 아닌 빈 배열이 됩니다. 다음 SELECT 문에서는 샘플 스파스 배열의 마지막 요소를 초과하는 읽기를 시도합니다.

select array_slice(array_column, 6, 8) from table_1;

출력은 빈 배열입니다.

+---------------------------------+
| array_slice(array_column, 6, 8) |
+---------------------------------+
| [ ]                             |
+---------------------------------+

참고로 undefined 는 NULL과 다릅니다. 배열의 NULL 값은 정의된 요소입니다.

밀집 배열에서 각 요소는 요소의 값이 NULL인 경우에도 저장 공간을 사용합니다.

스파스 배열에서 undefined 요소는 저장 공간을 직접 사용하지 않습니다.

밀집 배열에서 인덱스 값의 이론적 범위는 0 ~ 16777215입니다. (크기의 상한은 16 MB(16777216 바이트)이고 가능한 최소값은 1 바이트이므로 이론상 최대 요소 개수는 16777216개입니다.)

스파스 배열에서 인덱스 값의 이론적 범위는 0 ~ 231 - 1입니다. 그러나 16 MB 제한으로 인해 스파스 배열에는 231 값을 저장할 수 없습니다. 이론적인 값의 최대 개수는 여전히 16777216개로 제한됩니다.

(내부 오버헤드로 인해 밀집 배열 및 스파스 배열 모두에서 실제 크기 제한은 이론상 최대값인 16 MB보다 약간 작습니다.)

사용자는 ARRAY_INSERT 함수를 사용하여 배열의 특정 인덱스 포인트에 값을 삽입하여 스파스 배열을 생성할 수 있습니다(다른 배열 요소는 undefined 로 유지). 참고로 ARRAY_INSERT() 는 요소를 오른쪽으로 밀어 요소에 액세스하기 위해 필요한 인덱스 값을 변경하므로 거의 항상 스파스 배열은 왼쪽에서 오른쪽으로 채우는 것이 좋습니다(즉, 0에서 증가, 삽입된 각 새 값에 대해 인덱스 값 증가).

ARRAY 삽입의 예

ARRAY 데이터를 직접 삽입하려면 IIS(INSERT INTO ... SELECT)를 사용하십시오.

다음 코드에서는 ARRAY_CONSTRUCT 함수를 사용하여 함수가 삽입하는 ARRAY를 생성합니다.

INSERT INTO array_example (array_column)
    SELECT ARRAY_CONSTRUCT(12, 'twelve', NULL);

다음 코드에서는 ARRAY 상수 를 사용하여 삽입할 ARRAY를 지정합니다.

INSERT INTO array_example (array_column)
    SELECT [ 12, 'twelve', NULL ];

ARRAY의 일반적인 용도

ARRAY는 일반적으로 다음 중 1개 이상이 해당될 때 사용됩니다.

  • 각각의 구조가 동일하거나 유사한 데이터 조각이 여러 개 있는 경우.

  • 각 데이터 조각을 유사하게 처리해야 하는 경우. 예를 들어, 데이터를 반복하여 각 조각을 같은 방식으로 처리할 수 있습니다.

  • 데이터는 자연스러운 순서(예: 시간순)를 갖습니다.

이 첫 번째 예에서는 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 
    2,
    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
    ORDER BY id;
+----+-------------+---------------------+--------------------------+
| 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      |
|    |             |                     |   }                      |
|    |             |                     | }                        |
|  2 | [           | {                   | {                        |
|    |   1,        |   "key1": "value1", |   "outer_key1": {        |
|    |   2,        |   "key2": null      |     "inner_key1A": "1a", |
|    |   3,        | }                   |     "inner_key1B": null  |
|    |   undefined |                     |   },                     |
|    | ]           |                     |   "outer_key2": {        |
|    |             |                     |     "inner_key2": 2      |
|    |             |                     |   }                      |
|    |             |                     | }                        |
+----+-------------+---------------------+--------------------------+

추가적인 반정형 데이터 사용 예는 반정형 데이터 쿼리하기 를 참조하십시오.

맨 위로 이동