반정형 데이터 타입

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

  • VARIANT(기타 모든 데이터 타입의 값이 포함될 수 있음).

  • OBJECT(VARIANT 값을 직접 포함할 수 있으므로 그 자신을 포함한 다른 모든 데이터 타입의 값을 간접적으로 포함할 수 있음).

  • ARRAY(VARIANT 값을 직접 포함할 수 있으므로 그 자신을 포함한 다른 모든 데이터 타입의 값을 간접적으로 포함할 수 있음).

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

참고

정형 데이터 타입 (예: ARRAY(INTEGER), OBJECT(도시 VARCHAR) 또는 MAP(VARCHAR, VARCHAR)에 대한 자세한 내용은 정형 데이터 타입 섹션을 참조하십시오.

이 항목에서 이러한 각 데이터 타입에 대해 설명합니다.

VARIANT

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

VARIANT 값의 특성

VARIANT 값의 최대 크기는 압축되지 않은 데이터로 16MB일 수 있습니다. 하지만 실제로는 내부 오버헤드로 인해 최대 크기가 보통 더 작습니다. 최대 크기는 저장되는 오브젝트에 따라서도 달라집니다.

VARIANT 데이터 삽입하기

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

CREATE OR REPLACE TABLE variant_insert (v VARIANT);
INSERT INTO variant_insert (v)
  SELECT PARSE_JSON('{"key3": "value3", "key4": "value4"}');
SELECT * FROM variant_insert;
Copy
+---------------------+
| V                   |
|---------------------|
| {                   |
|   "key3": "value3", |
|   "key4": "value4"  |
| }                   |
+---------------------+

VARIANT 값 사용하기

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

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

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

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

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

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

UPDATE varia SET v = TO_VARIANT(float1);  -- converts from a FLOAT value to a VARIANT value.
UPDATE varia SET float2 = v::FLOAT;       -- converts from a VARIANT value to a FLOAT value.
Copy

모든 값을 SELECT합니다.

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

이전 예에서 보여준 것처럼, VARIANT 데이터 타입의 값을 변환하려면 VARIANT 값을 대상 데이터 타입으로 캐스팅합니다. 예를 들어, 다음 문에서는 :: 연산자를 사용하여 VARIANT를 FLOAT로 변환합니다.

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

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

SELECT my_variant_column * 3.14 FROM ...;
Copy

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

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

SELECT 'Sample', 'Sample'::VARIANT, 'Sample'::VARIANT::VARCHAR;
Copy
+----------+-------------------+----------------------------+
| '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 데이터는 일반적으로 다음의 경우에 사용됩니다.

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

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

OBJECT 데이터에는 다음 고려 사항이 적용됩니다.

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

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

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

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

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

참고

Snowflake는 VARIANT 값 이외의 값을 허용하는 정형 OBJECT 데이터 타입도 지원합니다. 정형 OBJECT 유형은 해당 유형의 OBJECT 값에 있어야 하는 키도 정의합니다. 자세한 내용은 정형 데이터 타입 섹션을 참조하십시오.

OBJECT 데이터 삽입하기

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

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

CREATE OR REPLACE TABLE object_example (object_column OBJECT);
INSERT INTO object_example (object_column)
  SELECT OBJECT_CONSTRUCT('thirteen', 13::VARIANT, 'zero', 0::VARIANT);
SELECT * FROM object_example;
Copy
+-------------------+
| OBJECT_COLUMN     |
|-------------------|
| {                 |
|   "thirteen": 13, |
|   "zero": 0       |
| }                 |
+-------------------+

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

OBJECT 상수를 사용하여 삽입할 OBJECT 값을 지정할 수도 있습니다. 자세한 내용은 OBJECT 상수 섹션을 참조하십시오.

OBJECT 상수

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

OBJECT 상수의 구문은 다음과 같습니다.

{ [<key>: <value> [, <key>: <value> , ...]] }
Copy

여기서

key

키-값 페어의 키. key 는 문자열 리터럴이어야 합니다.

value

키와 연결된 값입니다. value 는 리터럴 또는 식일 수 있습니다. value 는 어떤 데이터 타입이든 될 수 있습니다.

다음은 OBJECT 상수를 지정하는 예입니다.

  • {} 는 빈 OBJECT 값입니다.

  • { 'key1': 'value1' , 'key2': 'value2' } 에는 값에 대한 리터럴을 사용하여 OBJECT 값에 대해 지정된 키-값 페어가 포함됩니다.

  • { 'key1': c1+1 , 'key2': c1+2 } 에는 값에 대한 식을 사용하여 OBJECT 값에 대해 지정된 키-값 페어가 포함됩니다.

  • {*} 는 특성 이름을 키로, 그에 연결된 값을 값으로 사용하여 지정된 데이터에서 OBJECT 값을 생성하는 와일드카드입니다.

    이 와일드카드가 오브젝트 상수에 지정된 경우에는 정규화되지 않거나 테이블 이름이나 별칭으로 정규화될 수 있습니다. 예를 들어, 다음 와일드카드 지정은 모두 유효합니다.

    SELECT {*} FROM my_table;
    
    SELECT {my_table1.*}
      FROM my_table1 INNER JOIN my_table2
          ON my_table2.col1 = my_table1.col1;
    
    Copy

    오브젝트 상수에서 ILIKE 및 EXCLUDE 키워드를 사용할 수 있습니다. 특정 열을 선택하려면 ILIKE 키워드를 사용합니다. 예를 들어, 다음 쿼리는 테이블 my_table 의 패턴 col1% 와 일치하는 열을 선택합니다.

    SELECT {* ILIKE 'col1%'} FROM my_table;
    
    Copy

    특정 열을 제외하려면 EXCLUDE 키워드를 사용합니다. 예를 들어, 다음 쿼리는 my_table 테이블에서 col1 을 제외합니다.

    SELECT {* EXCLUDE col1} FROM my_table;
    
    Copy

    다음 쿼리는 테이블 my_table 에서 col1col2 를 제외합니다.

    SELECT {* EXCLUDE (col1, col2)} FROM my_table;
    
    Copy

    와일드카드는 키-값 페어와 혼합할 수 없습니다. 예를 들어, 다음 와일드카드 지정은 허용되지 않습니다.

    SELECT {*, 'k': 'v'} FROM my_table;
    
    Copy

    한 오브젝트 상수에 두 개 이상의 와일드카드를 사용할 수 없습니다. 예를 들어, 다음 와일드카드 지정은 허용되지 않습니다.

    SELECT {t1.*, t2.*} FROM t1, t2;
    
    Copy

다음 문은 OBJECT 상수와 OBJECT_CONSTRUCT 함수를 사용하여 OBJECT 데이터를 테이블에 삽입하는 작업을 수행합니다. OBJECT 값에는 캐나다의 2개 주의 이름과 주도가 포함되어 있습니다.

CREATE OR REPLACE TABLE my_object_table (my_object OBJECT);

INSERT INTO my_object_table (my_object)
  SELECT { 'PROVINCE': 'Alberta'::VARIANT , 'CAPITAL': 'Edmonton'::VARIANT };

INSERT INTO my_object_table (my_object)
  SELECT OBJECT_CONSTRUCT('PROVINCE', 'Manitoba'::VARIANT , 'CAPITAL', 'Winnipeg'::VARIANT );

SELECT * FROM my_object_table;
Copy
+--------------------------+
| MY_OBJECT                |
|--------------------------|
| {                        |
|   "CAPITAL": "Edmonton", |
|   "PROVINCE": "Alberta"  |
| }                        |
| {                        |
|   "CAPITAL": "Winnipeg", |
|   "PROVINCE": "Manitoba" |
| }                        |
+--------------------------+

다음 예에서는 와일드카드({*})를 사용하여 FROM 절에서 특성 이름과 값을 가져와 OBJECT 데이터를 삽입합니다. 먼저, 주와 주도 이름이 포함된 VARCHAR 값을 갖는 demo_ca_provinces 라는 테이블을 만듭니다.

CREATE OR REPLACE TABLE demo_ca_provinces (province VARCHAR, capital VARCHAR);
INSERT INTO demo_ca_provinces (province, capital) VALUES
  ('Ontario', 'Toronto'),
  ('British Columbia', 'Victoria');

SELECT province, capital
  FROM demo_ca_provinces
  ORDER BY province;
Copy
+------------------+----------+
| PROVINCE         | CAPITAL  |
|------------------+----------|
| British Columbia | Victoria |
| Ontario          | Toronto  |
+------------------+----------+

demo_ca_provinces 테이블의 데이터를 사용하여 my_object_table 에 오브젝트 데이터를 삽입합니다.

INSERT INTO my_object_table (my_object)
  SELECT {*} FROM demo_ca_provinces;

SELECT * FROM my_object_table;
Copy
+----------------------------------+
| MY_OBJECT                        |
|----------------------------------|
| {                                |
|   "CAPITAL": "Edmonton",         |
|   "PROVINCE": "Alberta"          |
| }                                |
| {                                |
|   "CAPITAL": "Winnipeg",         |
|   "PROVINCE": "Manitoba"         |
| }                                |
| {                                |
|   "CAPITAL": "Toronto",          |
|   "PROVINCE": "Ontario"          |
| }                                |
| {                                |
|   "CAPITAL": "Victoria",         |
|   "PROVINCE": "British Columbia" |
| }                                |
+----------------------------------+

다음 예에서는 OBJECT 상수의 값에 대한 식을 사용합니다.

SET my_variable = 10;
SELECT {'key1': $my_variable+1, 'key2': $my_variable+2};
Copy
+--------------------------------------------------+
| {'KEY1': $MY_VARIABLE+1, 'KEY2': $MY_VARIABLE+2} |
|--------------------------------------------------|
| {                                                |
|   "key1": 11,                                    |
|   "key2": 12                                     |
| }                                                |
+--------------------------------------------------+

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

SELECT { 'Manitoba': 'Winnipeg' } AS province_capital;
Copy
+--------------------------+
| PROVINCE_CAPITAL         |
|--------------------------|
| {                        |
|   "Manitoba": "Winnipeg" |
| }                        |
+--------------------------+

키로 OBJECT 값의 요소에 액세스하기

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

SELECT my_variant_column['key1'] FROM my_table;
Copy

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

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

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

OBJECT 데이터의 일반적인 용도

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

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

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

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

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

ARRAY

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

배열의 특성

반정형 배열의 각 값은 VARIANT 타입입니다. VARIANT 값은 기타 모든 데이터 타입의 값을 포함할 수 있습니다.

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

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

배열에는 다음 고려 사항이 적용됩니다.

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

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

  • 배열에는 NULL 값이 포함될 수 있습니다.

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

참고

Snowflake는 VARIANT 이외 유형의 요소를 허용하는 정형 배열도 지원합니다. 자세한 내용은 정형 데이터 타입 섹션을 참조하십시오.

ARRAY 데이터 삽입하기

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

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

CREATE OR REPLACE TABLE array_example (array_column ARRAY);
INSERT INTO array_example (array_column)
  SELECT ARRAY_CONSTRUCT(12, 'twelve', NULL);
Copy

ARRAY 상수를 사용하여 삽입할 배열을 지정할 수도 있습니다. 자세한 내용은 ARRAY 상수 섹션을 참조하십시오.

ARRAY 상수

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

ARRAY 상수의 구문은 다음과 같습니다.

[<value> [, <value> , ...]]
Copy

여기서

value

배열 요소와 연결된 값입니다. value 는 리터럴 또는 식일 수 있습니다. value 는 어떤 데이터 타입이든 될 수 있습니다.

다음은 ARRAY 상수를 지정하는 예입니다.

  • [] 는 빈 ARRAY 값입니다.

  • { 'value1' , 'value2' } 는 값에 대한 리터럴을 사용하여 ARRAY 상수에 대해 지정된 값을 포함합니다.

  • { c1+1 , c1+2 } 는 값에 대한 식을 사용하여 ARRAY 상수에 대해 지정된 값을 포함합니다.

다음 예에서는 ARRAY 상수를 사용하여 삽입할 배열을 지정합니다.

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

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

UPDATE my_table SET my_array = [ 1, 2 ];

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

다음 예에서는 ARRAY 상수의 값에 대한 식을 사용합니다.

SET my_variable = 10;
SELECT [$my_variable+1, $my_variable+2];
Copy
+----------------------------------+
| [$MY_VARIABLE+1, $MY_VARIABLE+2] |
|----------------------------------|
| [                                |
|   11,                            |
|   12                             |
| ]                                |
+----------------------------------+

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

SELECT [ 'Alberta', 'Manitoba' ] AS province;
Copy
+--------------+
| PROVINCE     |
|--------------|
| [            |
|   "Alberta", |
|   "Manitoba" |
| ]            |
+--------------+

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

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

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

SELECT my_array_column[2] FROM my_table;
Copy

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

SELECT my_array_column[0][0] FROM my_table;
Copy

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

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

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

SELECT ARRAY_SLICE(my_array_column, 5, 10) FROM my_table;
Copy

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

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

밀집 배열과 희소 배열

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

밀집 배열에서 요소의 인덱스 값은 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 ]
Copy

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

SELECT ARRAY_SLICE(array_column, 6, 8) FROM table_1;
Copy

출력은 빈 배열입니다.

+---------------------------------+
| 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 데이터는 일반적으로 다음 중 1개 이상이 해당될 때 사용됩니다.

  • 데이터 컬렉션이 있으며, 컬렉션의 각 부분은 동일하거나 유사한 구조로 되어 있습니다.

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

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

다음 예에서는 VARIANT, ARRAY, OBJECT 데이터가 있는 테이블에 대한 DESC TABLE 명령의 출력을 보여줍니다.

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

DESC TABLE test_semi_structured;
Copy
+------+---------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
| name | type    | kind   | null? | default | primary key | unique key | check | expression | comment | policy name | privacy domain |
|------+---------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------|
| VAR  | VARIANT | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| ARR  | ARRAY   | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| OBJ  | OBJECT  | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | 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 } '
              ||
               ' } ');
Copy

이제 테이블에 데이터를 표시합니다.

SELECT * 
  FROM demonstration1
  ORDER BY id;
Copy
+----+-------------+---------------------+--------------------------+
| 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      |
|    |             |                     |   }                      |
|    |             |                     | }                        |
+----+-------------+---------------------+--------------------------+

추가적인 예를 보려면 반정형 데이터 쿼리하기 섹션을 참조하십시오.