SQL 데이터 타입

SQL 데이터 타입 (SQL data types)

Druid SQL 에서 지원하는 데이터 타입에 대해 설명하는 문서예요. Druid는 각 컬럼을 특정 데이터 타입과 연결해요. 표준 타입과 배열, 멀티-밸류 문자열, NULL 처리, 중첩 컬럼까지 차근차근 살펴볼게요.

출처: 문서

본문

Apache Druid는 두 가지 쿼리 언어를 지원해요: Druid SQL 과 native 쿼리. 이 문서는 SQL 언어를 설명해요.

Druid는 각 컬럼을 특정 데이터 타입과 연결해요. 이 문서는 Druid SQL 에서 지원되는 데이터 타입을 설명해요.

표준 타입 (Standard types)

Druid는 기본적으로 다음 기본 컬럼 타입을 지원해요:

  • LONG: 64비트 부호 있는 정수
  • FLOAT: 32비트 부동소수점
  • DOUBLE: 64비트 부동소수점
  • STRING: UTF-8 인코딩 문자열과 문자열 배열
  • COMPLEX: 비표준 데이터 타입. 예: 중첩 JSON, hyperUnique, approxHistogram, DataSketches
  • ARRAY: 이 타입들로 구성된 배열

Druid는 타임스탬프(__time 컬럼 포함)를 LONG으로 취급하며, 그 값은 1970-01-01 00:00:00 UTC 이후의 밀리초 수(윤초 제외)예요. 따라서 Druid의 타임스탬프는 어떤 시간대(timezone) 정보도 담고 있지 않아요. 타임스탬프가 나타내는 정확한 시점(moment)에 대한 정보만 담고 있어요. 타임스탬프 처리에 대한 자세한 내용은 Time functions 를 참고하세요.

다음 표는 쿼리를 실행할 때 Druid가 SQL 타입을 native 타입으로 어떻게 매핑하는지 설명해요:

| SQL 타입 | Druid 런타임 타입 | 기본값 * | 참고 | | CHAR | STRING | '' | | | VARCHAR | STRING | '' | Druid STRING 컬럼은 VARCHAR로 보고돼요. 멀티-밸류 문자열도 포함할 수 있어요. | | DECIMAL | DOUBLE | 0.0 | DECIMAL은 고정소수점이 아니라 부동소수점 연산을 사용해요 | | FLOAT | FLOAT | 0.0 | Druid FLOAT 컬럼은 FLOAT로 보고돼요 | | REAL | DOUBLE | 0.0 | | | DOUBLE | DOUBLE | 0.0 | Druid DOUBLE 컬럼은 DOUBLE로 보고돼요 | | BOOLEAN | LONG | false | | | TINYINT | LONG | 0 | | | SMALLINT | LONG | 0 | | | INTEGER | LONG | 0 | | | BIGINT | LONG | 0 | Druid LONG 컬럼(__time 제외)은 BIGINT로 보고돼요 | | TIMESTAMP | LONG | 0 , 즉 1970-01-01 00:00:00 UTC | Druid의 __time 컬럼은 TIMESTAMP로 보고돼요. 문자열과 timestamp 타입 간 캐스트는 2000-01-02 03:04:05 같은 표준 SQL 형식을 가정해요 (ISO 8601 형식이 아님). 다른 형식은 time functions 중 하나를 사용하세요. | | DATE | LONG | 0 , 즉 1970-01-01 | TIMESTAMP를 DATE로 캐스팅하면 가장 가까운 날로 내림해요. 문자열과 date 타입 간 캐스트는 2000-01-02 같은 표준 SQL 형식을 가정해요. 다른 형식은 time functions 중 하나를 사용하세요. | | ARRAY | ARRAY | NULL | Druid native 배열 타입은 SQL 배열처럼 동작하고, 멀티-밸류 문자열은 배열로 변환할 수 있어요. 자세한 내용은 Arrays 를 참고하세요. | | OTHER | COMPLEX | 없음 | hyperUnique, approxHistogram 등 다양한 Druid 컬럼 타입을 나타낼 수 있어요. |

  • 모든 타입의 기본값은 NULL이에요.

두 SQL 타입 간 캐스트의 동작은 런타임 타입에 따라 달라져요:

  • Druid 런타임 타입이 같은 두 SQL 타입 간 캐스트는 표에 적힌 예외를 제외하고는 아무 효과가 없어요.
  • Druid 런타임 타입이 다른 두 SQL 타입 간 캐스트는 Druid에서 런타임 캐스트를 생성해요.

CAST('foo' AS BIGINT) 처럼 값을 대상 타입으로 캐스트할 수 없으면 Druid는 NULL을 대체해요.

배열 (Arrays)

Druid는 ARRAY 타입 을 지원해요. 표준 SQL 배열처럼 동작하며, 결과는 전체 배열이 일치하는 것으로 그룹화돼요. UNNEST 연산자는 개별 배열 요소에 연산을 수행하는 데 사용할 수 있고, 각 요소를 별도의 행으로 변환해요.

ARRAY 타입 컬럼은 JSON 기반 인제스트에서 스키마 자동 탐지와 공유되는 auto 타입 차원 스키마를 사용해 세그먼트에 저장할 수 있고, ARRAY 타입 컬럼으로 감지·인제스트돼요. SQL 기반 인제스트 의 경우 ARRAY 타입을 인제스트하려면 쿼리 context 파라미터 arrayIngestMode를 "array"로 지정해야 해요. Druid 28 에서 이 파라미터의 기본 모드는 하위 호환성을 위해 "mvd"인데, 이는 ARRAY<STRING>만 처리할 수 있고 그것을 멀티-밸류 문자열 컬럼 에 저장해요.

멀티-밸류 차원을 MV_TO_ARRAY 로 명시적으로, 또는 array functions 로 암시적으로 표준 SQL 배열로 변환할 수 있어요. 또한 array functions로 여러 컬럼에서 배열을 구성할 수도 있어요.

Druid는 기본적으로 ARRAY 결과를 배열의 JSON 문자열로 직렬화해요. 이는 context 파라미터 sqlStringifyArrays 로 제어할 수 있어요. false로 설정하고 JSON result formats 를 사용하면, 배열이 문자열 형태 대신 일반 JSON 배열로 반환돼요.

멀티-밸류 문자열 (Multi-value strings)

Druid의 native 타입 시스템은 문자열이 여러 값을 가질 수 있게 해요. 이러한 멀티-밸류 문자열 차원은 SQL에서 타입 VARCHAR로 보고되고, 다른 VARCHAR처럼 문법적으로 사용될 수 있어요. 멀티-밸류 문자열 차원을 참조하는 일반 문자열 함수는 각 행의 모든 값에 개별적으로 적용돼요.

특수한 multi-value string functions 을 사용하면 멀티-밸류 문자열 차원을 배열처럼 취급할 수 있고, 강력한 배열 인식 연산을 수행하면서도 VARCHAR 타입과 동작을 유지해요.

멀티-밸류 차원으로 그룹화하면 native Druid 멀티-밸류 집계 동작을 따르는데, 이는 암시적 SQL UNNEST와 유사해요. 자세한 내용은 Grouping 을 참고하세요.

:::admonish 참고

SQL 플래너가 멀티-밸류 차원을 VARCHAR로 취급하기 때문에, Druid SQL과 native 쿼리에서 처리 방식에 일부 불일치가 있어요. 예를 들어 멀티-밸류 차원을 포함하는 표현식이 Druid SQL 플래너에 의해 잘못 최적화될 수 있어요. 예를 들어 multi_val_dim = 'a' AND multi_val_dim = 'b'는 false로 최적화되는데, 실제로는 단일 행이 multi_val_dim 값으로 'a'와 'b'를 모두 가질 수 있어요.

멀티-밸류 차원의 SQL 동작은 향후 릴리스에서 native 쿼리에서의 동작과 더 밀접하게 정렬되도록 바뀔 수 있지만, 멀티-밸류 문자열 함수가 native 기능의 거의 모두를 제공할 수 있어야 해요.


멀티-밸류 문자열 동작 (Multi-value strings behavior)

Druid 멀티-밸류 문자열 차원의 동작은 사용되는 상황(context)에 따라 달라져요.

CONCAT처럼 행당 단일 입력 값을 기대하는 표준 VARCHAR 함수와 함께 사용하면, Druid는 함수를 행의 모든 값에 매핑해요. 행이 null이거나 비어 있으면 함수는 NULL을 입력으로 받아요.

명시적 multi-value string functions 와 함께 사용하면, Druid는 행 값을 ARRAY 타입인 것처럼 처리해요. null과 빈 행을 생성하는 연산은 (암시적 매핑 동작과 달리) 별개의 값으로 구분돼요. 보통 MV_ 접두사로 표시되는 이러한 멀티-밸류 문자열 함수는 계산이 완료된 후에도 VARCHAR 타입을 유지해요. Druid 멀티-밸류 컬럼은 빈 행과 null 행을 구분하지 않는다는 점에 유의하세요. 빈 행은 native에서 멀티-밸류 함수의 입력으로 절대 나타나지 않지만, 값의 배열 형태를 조작하는 멀티-밸류 함수는 빈 배열을 생성할 수 있고, 이것은 처리 중 별도로 다뤄져요.

:::admonish 참고

멀티-밸류 함수와 일반 스칼라 함수를 같은 표현식 안에서 섞어 쓰지 마세요. 사용이 모호해서 플래너가 값을 제대로 처리하는 방법을 결정할 수 없게 돼요. 멀티-밸류 문자열은 표현식 안에서 일관되게 처리되어야 해요.


ARRAY로 변환되거나 array functions 와 함께 사용되면 멀티-밸류 문자열은 표준 SQL 배열처럼 동작하고, 더 이상 비-배열 함수로 조작할 수 없어요.

기본적으로 Druid는 값에 그룹화가 적용되지 않았다면 멀티-밸류 VARCHAR 결과를 배열의 JSON 문자열로 직렬화해요. 값에 그룹화가 적용되었다면, 암시적 UNNEST 동작 때문에 모든 결과는 항상 표준 단일 값 VARCHAR가 돼요. ARRAY 타입 결과의 직렬화는 context 파라미터 sqlStringifyArrays 로 제어돼요. false로 설정하고 JSON result formats 를 사용하면, 배열이 문자열 형태 대신 일반 JSON 배열로 반환돼요.

NULL 값 (NULL values)

기본적으로 Druid는 NULL 값을 ANSI SQL 표준과 유사하게 취급해요.

null 처리의 예시는 null handling tutorial 을 참고하세요.

부울 논리 (Boolean logic)

Druid는 필터 처리와 부울 표현식 평가를 위해 SQL 3값 논리(three-valued logic)를 사용해요.

중첩 컬럼 (Nested columns)

Druid는 native COMPLEX<json> 타입을 사용해 세그먼트에 중첩 데이터 구조를 저장하는 것을 지원해요. 자세한 내용은 Nested columns 를 참고하세요.

중첩 값을 추출하고, 문자열에서 파싱하고, 문자열로 직렬화하고, 새 COMPLEX<json> 구조를 생성할 수 있는 JSON functions 를 사용해 중첩 데이터와 상호작용할 수 있어요.

COMPLEX 타입은 그 타입을 사용하는 특수 함수 밖에서는 기능이 제한적이므로, 다음 경우에는 동작이 정의되지 않아요:

  • 복합(complex) 값에 그룹화.
  • 복합 값에 직접 필터링.
  • 특정 복합 타입에 대한 특수 처리가 없는 집계자의 입력으로 사용.

많은 경우 COMPLEX 값 타입을 STRING으로 변환하는 함수가 제공되는데, 이는 COMPLEX 타입 기능이 개선될 때까지의 임시 해결책(workaround) 역할을 해요.

더 알아보기 (Learn more)