매핑 타입
Elasticsearch와 ClickHouse는 매우 다양한 데이터 타입을 지원하지만, 저장 방식과 쿼리 모델은 근본적으로 다릅니다. 이 섹션에서는 일반적으로 사용되는 Elasticsearch 필드 타입을 가능한 경우 해당하는 ClickHouse 타입에 매핑하고, 마이그레이션을 안내하는 데 도움이 되는 설명을 제공합니다. 직접 대응되는 타입이 존재하지 않는 경우에는 주석에 대안 또는 참고 사항을 제공합니다.
| Elasticsearch 유형 | ClickHouse 상응 항목 | 설명 |
|---|---|---|
boolean | UInt8 또는 Bool | ClickHouse의 최신 버전에서는 Boolean을 UInt8의 별칭으로 지원합니다. |
keyword | String | 정확히 일치하는 값을 기준으로 필터링, 그룹화, 정렬하는 데 사용합니다. |
text | String | ClickHouse의 전체 텍스트 검색 기능은 제한적이며, 토큰화를 위해서는 tokens와 배열 함수를 조합한 사용자 정의 로직이 필요합니다. |
long | Int64 | 64비트 부호 있는 정수입니다. |
integer | Int32 | 32비트 부호 있는 정수입니다. |
short | Int16 | 16비트 부호 있는 정수입니다. |
byte | Int8 | 8비트 부호 있는 정수입니다. |
unsigned_long | UInt64 | 부호 없는 64비트 정수입니다. |
double | Float64 | 64비트 부동 소수점 수입니다. |
float | Float32 | 32비트 부동 소수점 수입니다. |
half_float | Float32 또는 BFloat16 | 가장 가까운 대응 타입입니다. ClickHouse는 16비트 부동 소수점 타입을 지원하지 않습니다. ClickHouse에는 BFloat16이 있으며, 이는 Half-float IEEE-754와는 다른 타입입니다. half-float는 표현 범위는 더 좁지만 정밀도가 더 높고, bfloat16은 더 넓은 범위를 위해 정밀도를 일부 희생하므로 머신 러닝 워크로드에 더 적합합니다. |
scaled_float | Decimal(x, y) | 고정 소수점 숫자 값을 저장합니다. |
date | DateTime | 초 단위 정밀도를 갖는 날짜/시간 타입입니다. |
date_nanos | DateTime64 | ClickHouse는 DateTime64(9)를 사용하여 나노초 단위의 정밀도를 지원합니다. |
binary | String, FixedString(N) | 이진 필드는 base64 디코딩이 필요합니다. |
ip | IPv4, IPv6 | 네이티브 IPv4 및 IPv6 타입이 제공됩니다. |
object | Nested, Map, Tuple, JSON | ClickHouse는 Nested 또는 JSON을 사용하여 JSON 유사 객체를 모델링할 수 있습니다. |
flattened | String | Elasticsearch의 flattened 타입은 전체 JSON 객체를 단일 필드로 저장하여, 전체 매핑 없이도 중첩 키에 유연하고 스키마 없이 접근할 수 있도록 합니다. ClickHouse에서는 String 타입을 사용해 유사한 기능을 구현할 수 있지만, 해당 처리 작업은 materialized view에서 수행해야 합니다. |
nested | Nested | ClickHouse Nested 컬럼은 flatten_nested=0을 사용하는 경우, 그룹화된 하위 필드에 대해 유사한 의미를 갖도록 동작합니다. |
join | 해당 없음 | 부모-자식 관계에 대한 직접적인 개념이 없습니다. ClickHouse에서는 테이블 간 조인을 지원하므로 별도로 필요하지 않습니다. |
alias | Alias 컬럼 수정자 | 별칭(alias)은 필드 수정자를 통해 지원됩니다. 이러한 별칭에는 함수도 적용할 수 있습니다. 예를 들어 size String ALIAS formatReadableSize(size_bytes)와 같이 사용할 수 있습니다. |
range types (*_range) | Tuple(start, end) 또는 Array(T) | ClickHouse에는 네이티브 범위(range) 타입이 없지만, 숫자 및 날짜 범위는 Tuple(start, end) 또는 Array 구조를 사용해 표현할 수 있습니다. IP 범위(ip_range)의 경우 CIDR 값을 String으로 저장하고 isIPAddressInRange()와 같은 함수로 판별하십시오. 또는 효율적인 필터링을 위해 ip_trie 기반 조회용 dictionary를 사용하는 방법을 고려하십시오. |
aggregate_metric_double | AggregateFunction(...) 및 SimpleAggregateFunction(...) | 사전 집계된 메트릭을 모델링하기 위해 집계 함수 상태와 materialized view를 사용합니다. 모든 집계 함수는 집계 상태를 지원합니다. |
histogram | Tuple(Array(Float64), Array(UInt64)) | 배열 또는 사용자 정의 스키마를 사용해 버킷과 개수를 수동으로 표현합니다. |
annotated-text | String | 엔터티 인지 검색이나 주석에 대한 기본 제공 지원이 없습니다. |
completion, search_as_you_type | 해당 없음 | 기본 제공되는 자동완성 또는 추천(suggester) 엔진이 없습니다. 유사한 기능은 String과 search functions를 사용하여 구현할 수 있습니다. |
semantic_text | 해당 없음 | 네이티브 의미론적 검색 기능은 없으며, 임베딩을 생성한 후 벡터 검색을 사용해야 합니다. |
token_count | Int32 | 수집 시 토큰 개수를 수동으로 계산하는 데 사용합니다. 예: length(tokens()) 함수, 구체화된 컬럼(Materialized column)에 사용 |
dense_vector | Array(Float32) | 임베딩 저장을 위해 배열을 사용합니다. |
sparse_vector | Map(UInt32, Float32) | 맵을 사용하여 희소 벡터를 모사합니다. 네이티브 희소 벡터 지원은 없습니다. |
rank_feature / rank_features | Float32, Array(Float32) | 쿼리 시점 부스팅에 대한 네이티브 지원은 없지만, 점수 계산 로직에서 수동으로 모델링할 수 있습니다. |
geo_point | Tuple(Float64, Float64) 또는 Point | 위도와 경도로 구성된 튜플을 사용합니다. Point는 ClickHouse 데이터 타입으로 제공됩니다. |
geo_shape, shape | Ring, LineString, MultiLineString, Polygon, MultiPolygon | 지리 공간 도형과 공간 인덱싱에 대한 네이티브 지원을 제공합니다. |
percolator | 해당 없음 | 쿼리를 인덱싱하는 개념이 없습니다. 대신 표준 SQL과 증분형 materialized view를 사용하십시오. |
version | String | ClickHouse에는 네이티브 버전 타입이 없습니다. 버전은 문자열로 저장하고, 필요하다면 의미론적 비교를 수행하기 위해 사용자 정의 함수(UDF)를 사용하십시오. 범위 쿼리가 필요한 경우 숫자 형식으로 정규화하는 것을 고려하십시오. |
참고
-
배열(Arrays): Elasticsearch에서는 모든 필드가 기본적으로 배열을 지원합니다. ClickHouse에서는 배열을 명시적으로 정의해야 합니다(예:
Array(String)), 대신 특정 위치에 직접 접근하거나 쿼리할 수 있다는 장점이 있습니다(예:an_array[1]). -
멀티 필드(Multi-fields): Elasticsearch는 동일한 필드를 여러 방식으로 인덱싱할 수 있습니다(예:
text와keyword둘 다). ClickHouse에서는 이 패턴을 별도의 컬럼이나 뷰로 모델링해야 합니다. -
Map 및 JSON 타입 - ClickHouse에서는
Map타입을resourceAttributes및logAttributes와 같은 동적 키-값 구조를 모델링하는 데 흔히 사용합니다. 이 타입은 런타임에 임의의 키를 추가할 수 있으므로, Elasticsearch의 JSON 객체와 유사한 방식으로 유연한 스키마리스 수집을 가능하게 합니다. 그러나 고려해야 할 중요한 제한 사항이 있습니다:- 값 타입의 균일성: ClickHouse
Map컬럼은 일관된 값 타입을 가져야 합니다(예:Map(String, String)). 변환(coercion) 없이 혼합 타입 값은 지원되지 않습니다. - 성능 비용:
Map내의 어떤 키에 접근하더라도 전체 맵을 메모리로 로드해야 하므로, 성능 측면에서 비효율적일 수 있습니다. - 서브컬럼 없음: JSON 타입과 달리,
Map의 키는 실제 서브컬럼으로 표현되지 않으며, 이로 인해 ClickHouse가 인덱싱, 압축, 쿼리를 효율적으로 수행하는 능력이 제한됩니다.
이러한 제한으로 인해 ClickStack은
Map대신 ClickHouse의 향상된JSON타입으로 마이그레이션하고 있습니다.JSON타입은Map의 많은 단점을 보완합니다:-
진정한 열 지향 저장: 각 JSON 경로가 서브컬럼으로 저장되며, 이를 통해 효율적인 압축, 필터링, 벡터화된 쿼리 실행이 가능합니다.
-
혼합 타입 지원: 정수, 문자열, 배열 등 서로 다른 데이터 타입이 동일한 경로 아래에서 변환이나 타입 통일 없이 공존할 수 있습니다.
-
파일 시스템 확장성: 동적 키(
max_dynamic_paths)와 타입(max_dynamic_types)에 대한 내부 제한을 통해, 키 집합의 카디널리티가 매우 높더라도 디스크 상의 컬럼 파일 폭발을 방지합니다. -
조밀한 저장: null 및 누락된 값은 희소하게 저장되어 불필요한 오버헤드를 방지합니다.
JSON타입은 특히 관측성 워크로드에 매우 적합하며, 스키마리스 수집의 유연성과 ClickHouse 네이티브 타입의 성능 및 확장성을 함께 제공하므로, 동적 속성 필드에서Map을 대체하기에 이상적인 선택입니다.JSON 타입에 대한 자세한 내용은 JSON 가이드와 "How we built a new powerful JSON data type for ClickHouse"를 참고할 것을 권장합니다.
- 값 타입의 균일성: ClickHouse