VARIANT 타입
VARIANT 타입 (Variant Type)
VARIANT 타입은 각 행이 자기만의 타입 정보를 담고 있는, 타입이 지정된(typed) 바이너리 데이터를 저장해요. 이는 물리적으로 텍스트로 저장되는 JSON 타입과 달라요. 값마다 타입 메타데이터가 내장되어 있기 때문에, VARIANT는 반정형 데이터에 대해 JSON보다 더 나은 압축률과 쿼리 성능을 제공해요.
VARIANT 타입은 Snowflake의 반정형 VARIANT 데이터 타입에서 영감을 받았어요. 2025년부터 Parquet에서 사용 가능하며, DuckDB의 Parquet 리더에서도 지원돼요.
출처: 문서
본문
예시 (Examples)
같은 열에 다른 타입 저장하기 (Storing Different Types in the Same Column)
VARIANT 열은 행마다 다른 타입의 값을 담을 수 있어요:
CREATE TABLE events (id INTEGER, data VARIANT);
INSERT INTO events VALUES
(1, 42::VARIANT),
(2, 'hello world'::VARIANT),
(3, [1, 2, 3]::VARIANT),
(4, {'name': 'Alice', 'age': 30}::VARIANT);
SELECT * FROM events;
┌───────┬────────────────────────────┐
│ id │ data │
│ int32 │ variant │
├───────┼────────────────────────────┤
│ 1 │ 42 │
│ 2 │ hello world │
│ 3 │ [1, 2, 3] │
│ 4 │ {'name': Alice, 'age': 30} │
└───────┴────────────────────────────┘
값의 타입 확인하기 (Checking the Type of a Value)
variant_typeof로 각 행의 기저 타입을 살펴볼 수 있어요:
SELECT id, data, variant_typeof(data) AS vtype
FROM events;
┌───────┬────────────────────────────┬───────────────────┐
│ id │ data │ vtype │
│ int32 │ variant │ varchar │
├───────┼────────────────────────────┼───────────────────┤
│ 1 │ 42 │ INT32 │
│ 2 │ hello world │ VARCHAR │
│ 3 │ [1, 2, 3] │ ARRAY(3) │
│ 4 │ {'name': Alice, 'age': 30} │ OBJECT(name, age) │
└───────┴────────────────────────────┴───────────────────┘
중첩 Variant에서 필드 추출하기 (Extracting Fields from Nested Variants)
중첩된 VARIANT 값에서 점 표기법이나 variant_extract 함수로 필드를 추출할 수 있어요:
SELECT data.name FROM events WHERE id = 4;
SELECT variant_extract(data, 'name') AS name FROM events WHERE id = 4;
┌─────────┐
│ name │
│ variant │
├─────────┤
│ Alice │
└─────────┘
Parquet 지원 (Parquet Support)
DuckDB는 Parquet 파일에서 VARIANT 타입을 읽고 쓸 수 있어요. 여기에는 중첩 데이터를 더 효율적으로 접근하기 위해 평평한 값으로 저장하는 쉐딩(shredding) 기법도 포함돼요.
VARIANT를 Parquet에 쓰기 (Writing VARIANT to Parquet)
VARIANT 열을 Parquet에 쓸 때 DuckDB는 첫 번째 row group의 구조를 바탕으로 variant 데이터를 타입된 열로 자동으로 쉐딩(분해)할 수 있어요. 이 자동 쉐딩은 predicate pushdown과 효율적인 열 접근을 가능하게 해 읽기 성능을 높여요.
쉐딩용 스키마를 명시적으로 제공하려면 SHREDDING copy 옵션을 사용해요:
COPY events TO 'events.parquet' (
FORMAT parquet,
SHREDDING {'data': 'STRUCT(name VARCHAR, age INTEGER)'}
);
Parquet에서 Snowflake VARIANT 읽기 (Reading Snowflake VARIANT from Parquet)
DuckDB는 Snowflake가 만든 쉐딩된 VARIANT Parquet 파일을 읽을 수 있어요. 쉐딩된 열에서 variant 값을 자동으로 재구성해요.