메인 콘텐츠로 건너뛰기
이 가이드는 ClickPipes를 통해 MongoDB에서 ClickHouse로 복제된 JSON 데이터를 다루는 일반적인 패턴을 설명합니다. 예를 들어, 고객 주문을 추적하기 위해 MongoDB에 t1 컬렉션을 만들었다고 가정하겠습니다:
MongoDB CDC Connector는 네이티브 JSON 데이터 타입을 사용해 MongoDB 문서를 ClickHouse로 복제합니다. ClickHouse의 복제된 테이블 t1에는 다음 행이 들어 있습니다:

테이블 스키마

복제된 테이블은 다음과 같은 표준 스키마를 사용합니다:
  • _id: MongoDB의 기본 키
  • doc: JSON 데이터 타입으로 복제된 MongoDB 문서
  • _peerdb_synced_at: 행이 마지막으로 동기화된 시점을 기록합니다
  • _peerdb_version: 행의 버전을 추적하며, 행이 업데이트되거나 삭제되면 값이 증가합니다
  • _peerdb_is_deleted: 행이 삭제되었는지 여부를 나타냅니다

ReplacingMergeTree 테이블 엔진

ClickPipes는 ReplacingMergeTree 테이블 엔진 계열을 사용해 MongoDB 컬렉션을 ClickHouse에 매핑합니다. 이 엔진에서는 특정 기본 키(primary key)(_id)에 대해 더 최신 버전(_peerdb_version)의 문서를 삽입하는 방식으로 업데이트를 표현하므로, 업데이트, 교체, 삭제를 버전이 부여된 삽입으로 효율적으로 처리할 수 있습니다. ReplacingMergeTree는 백그라운드에서 중복을 비동기적으로 제거합니다. 동일한 행에 중복이 없음을 확실히 보장하려면 FINAL 수정자를 사용하십시오. 예시:

삭제 처리

MongoDB에서 삭제된 데이터는 _peerdb_is_deleted 컬럼에 삭제 표시가 된 새 행으로 전파됩니다. 일반적으로 쿨리에서는 이러한 행이 제외되도록 필터링하는 것이 좋습니다:
각 쿼리에서 필터를 지정하는 대신, 삭제된 행이 자동으로 제외되도록 행 수준 정책을 만들 수도 있습니다:

JSON 데이터 쿼리

점 표기법으로 JSON 필드를 직접 쿼리할 수 있습니다:
Query
Result
점 표기법을 사용해 중첩된 객체 필드를 쿼리할 때는 ^ 연산자를 추가해야 합니다:
Query
Result

Dynamic type

ClickHouse에서는 JSON의 각 field가 Dynamic type입니다. Dynamic type을 사용하면 ClickHouse는 사전에 type을 몰라도 어떤 type의 값이든 저장할 수 있습니다. 이는 toTypeName 함수를 사용해 확인할 수 있습니다:
Query
Result
필드의 실제 데이터 타입을 확인하려면 dynamicType 함수를 사용하면 됩니다. 같은 필드 이름이라도 행마다 데이터 타입이 서로 다를 수 있다는 점에 유의하십시오:
Query
Result
일반 함수는 일반 컬럼과 마찬가지로 Dynamic 타입에서도 작동합니다: 예시 1: 날짜 파싱
Query
Result
예시 2: 조건부 로직
Query
Result
예시 3: 배열 연산
Query
Result

필드 형 변환

ClickHouse의 집계 함수는 Dynamic 데이터 타입에 직접 사용할 수 없습니다. 예를 들어 Dynamic 데이터 타입에 sum 함수를 직접 사용하면 다음과 같은 오류가 발생합니다:
집계 함수를 사용하려면 CAST 함수 또는 :: 구문으로 필드를 적절한 데이터 타입으로 변환하십시오:
Query
Result
Dynamic 타입에서 기본 데이터 타입(dynamicType으로 결정됨)으로 캐스팅하는 작업은 성능이 매우 뛰어납니다. ClickHouse가 이미 값을 내부적으로 해당 기본 타입으로 저장하기 때문입니다.

JSON 평탄화

일반 뷰

JSON 테이블을 기반으로 일반 뷰를 생성하면 평탄화, 형 변환, 변환 로직을 캡슐화하여 관계형 테이블처럼 데이터를 쿼리할 수 있습니다. 일반 뷰는 기반 데이터는 저장하지 않고 쿼리 자체만 저장하므로 가볍습니다. 예시는 다음과 같습니다:
이 뷰의 스키마는 다음과 같습니다:
이제 평탄화된 테이블을 쿼리하듯이 뷰도 쿼리할 수 있습니다:

갱신 가능 구체화 뷰

갱신 가능 구체화 뷰를 생성할 수 있습니다. 이를 사용하면 행 중복 제거를 위한 쿼리 실행을 예약하고, 그 결과를 평탄화된 대상 테이블에 저장할 수 있습니다. 예약된 갱신이 실행될 때마다 대상 테이블은 최신 쿼리 결과로 대체됩니다. 이 방식의 가장 큰 장점은 FINAL 키워드를 사용하는 쿼리가 갱신 시 한 번만 실행된다는 점입니다. 따라서 이후 대상 테이블을 조회하는 쿼리에서는 FINAL을 사용할 필요가 없습니다. 단점은 대상 테이블의 데이터가 가장 최근 갱신 시점을 기준으로만 최신 상태를 유지한다는 점입니다. 많은 사용 사례에서는 몇 분에서 몇 시간까지의 갱신 주기가 데이터 최신성과 쿼리 성능 사이에서 좋은 균형을 제공합니다.
이제 flattened_t1 테이블(table)을 FINAL 수정자 없이 직접 쿼리할 수 있습니다:

증분형 materialized view

실시간으로 평탄화된 컬럼에 액세스하려면 증분형 materialized view를 생성할 수 있습니다. 테이블에 업데이트가 자주 발생한다면, 업데이트가 일어날 때마다 머지가 트리거되므로 materialized view에서 FINAL 수정자를 사용하는 것은 권장되지 않습니다. 대신 materialized view 위에 일반 뷰를 만들어 쿼리 시점에 데이터를 중복 제거할 수 있습니다.
이제 다음과 같이 뷰 flattened_t1_final을 쿼리할 수 있습니다:
마지막 수정일 2026년 7월 1일