Elasticsearch와 ClickHouse는 매우 다양한 데이터 타입을 지원하지만, 기본 저장 방식과 쿼리 모델은 근본적으로 다릅니다. 이 섹션에서는 일반적으로 사용되는 Elasticsearch 필드 타입을 가능한 경우 ClickHouse의 대응 타입에 매핑하고, 마이그레이션에 도움이 되는 맥락을 제공합니다. 대응되는 타입이 없는 경우에는 비고에 대안이나 참고 사항을 제공합니다.
| Elasticsearch 유형 | ClickHouse 대응 개념 | 비고 |
|---|---|---|
boolean |
UInt8 or Bool |
최신 버전의 ClickHouse에서는 Boolean을 UInt8의 alias로 지원합니다. |
keyword |
String |
정확히 일치하는 값의 필터링, 그룹화, 정렬에 사용됩니다. |
text |
String |
ClickHouse의 전문 검색은 제한적이며, tokenization에는 tokens와 array functions 등의 함수를 조합한 사용자 정의 로직이 필요합니다. |
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 or BFloat16 |
가장 가까운 대응 타입입니다. ClickHouse에는 16비트 float 타입이 없습니다. ClickHouse의 BFloat16은 Half-float IEEE-754와는 다릅니다. half-float는 더 좁은 범위 대신 더 높은 정밀도를 제공하고, bfloat16은 더 넓은 범위를 위해 정밀도를 희생하므로 머신 러닝 workload에 더 적합합니다. |
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 views에서 수행해야 합니다. |
nested |
Nested |
ClickHouse의 Nested 컬럼은 사용자가 flatten_nested=0을 사용하는 경우 그룹화된 하위 필드에 대해 유사한 의미를 제공합니다. |
join |
NA | 부모-자식 관계에 직접 대응하는 개념은 없습니다. ClickHouse는 테이블 간 조인을 지원하므로 필요하지 않습니다. |
alias |
Alias column modifier |
필드 modifier를 통해 alias를 지원합니다. 예를 들어 size String ALIAS formatReadableSize(size_bytes)와 같이 이러한 alias에 함수를 적용할 수 있습니다. |
range types (*_range) |
Tuple(start, end) or Array(T) |
ClickHouse에는 네이티브 range 타입이 없지만, 숫자 및 날짜 범위는 Tuple(start, end) 또는 Array 구조로 표현할 수 있습니다. IP 범위(ip_range)의 경우 CIDR 값을 String으로 저장하고 isIPAddressInRange() 같은 함수로 평가하십시오. 또는 효율적인 필터링을 위해 ip_trie 기반 lookup Dictionaries를 고려할 수 있습니다. |
aggregate_metric_double |
AggregateFunction(...) and SimpleAggregateFunction(...) |
사전 집계된 메트릭을 모델링하려면 집계 함수 상태와 materialized views를 사용하십시오. 모든 집계 함수는 aggregate states를 지원합니다. |
histogram |
Tuple(Array(Float64), Array(UInt64)) |
배열 또는 사용자 정의 schemas를 사용해 버킷과 개수를 수동으로 표현하십시오. |
annotated-text |
String |
엔터티 인식 검색이나 어노테이션에 대한 내장 지원은 없습니다. |
completion, search_as_you_type |
NA | 네이티브 자동완성 또는 suggester engine은 없습니다. String과 search functions으로 구현할 수 있습니다. |
semantic_text |
NA | 네이티브 semantic search는 지원하지 않으므로 embeddings를 생성하고 벡터 검색을 사용하십시오. |
token_count |
Int32 |
수집 중 토큰 수를 수동으로 계산하는 데 사용하십시오. 예: Materialized column과 함께 length(tokens()) 함수 사용 |
dense_vector |
Array(Float32) |
embeddings 저장에는 배열을 사용하십시오. |
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 |
Geo shape와 공간 인덱싱을 네이티브로 지원합니다. |
percolator |
NA | 쿼리를 인덱싱하는 개념은 없습니다. 대신 표준 SQL + 증분형 materialized view를 사용하십시오. |
version |
String |
ClickHouse에는 네이티브 버전 타입이 없습니다. 버전은 문자열로 저장하고, 필요하면 사용자 정의 UDF를 사용해 시맨틱 비교를 수행하십시오. 범위 쿼리가 필요하다면 숫자 포맷으로 정규화하는 방안을 고려하십시오. |
참고 사항
-
배열: Elasticsearch에서는 모든 필드가 배열을 네이티브하게 지원합니다. ClickHouse에서는 배열을 명시적으로 정의해야 하며(예:
Array(String)), 그 대신an_array[1]처럼 특정 위치의 값을 직접 참조하고 쿼리할 수 있습니다. -
다중 필드: Elasticsearch에서는 동일한 필드를 여러 방식으로 인덱싱할 수 있습니다(예:
text와keyword를 모두 사용). ClickHouse에서는 이 패턴을 별도의 컬럼이나 뷰로 모델링해야 합니다. -
맵 및 JSON 타입 - ClickHouse에서는
Map타입을resourceAttributes및logAttributes와 같은 동적 키-값 구조를 모델링하는 데 일반적으로 사용합니다. 이 타입은 런타임에 임의의 키를 추가할 수 있으므로 유연한 스키마 없는 수집이 가능하며, 개념적으로는 Elasticsearch의 JSON 객체와 유사합니다. 다만, 고려해야 할 중요한 제약이 있습니다.- 균일한 값 타입: ClickHouse
Map컬럼은 일관된 값 타입을 가져야 합니다(예:Map(String, String)). 타입이 섞인 값은 강제 변환 없이는 지원되지 않습니다. - 성능 비용:
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