ORDER BY 테이블 절, PRIMARY KEY 아님)을 가진 중복 레코드를 제거한다는 점에서 MergeTree와 다릅니다.
데이터 중복 제거는 머지 중에만 발생합니다. 머지는 시점을 알 수 없는 상태로 백그라운드에서 수행되므로 이를 계획할 수 없습니다. 일부 데이터는 처리되지 않은 채 남아 있을 수 있습니다. OPTIMIZE 쿼리를 사용해 예정되지 않은 머지를 실행할 수는 있지만, OPTIMIZE 쿼리는 대량의 데이터를 읽고 쓰므로 이에 의존해서는 안 됩니다.
따라서 ReplacingMergeTree는 공간 절약을 위해 백그라운드에서 중복 데이터를 정리하는 데는 적합하지만, 중복이 전혀 없다고 보장하지는 않습니다.
모범 사례와 성능 최적화 방법을 포함한 ReplacingMergeTree의 자세한 가이드는 여기에서 확인할 수 있습니다.
테이블 생성
행의 고유성은
PRIMARY KEY가 아니라 테이블의 ORDER BY 테이블 절에 따라 결정됩니다.ReplacingMergeTree 매개변수
ver
ver — 버전 번호를 담는 컬럼입니다. 유형은 UInt*, Date, DateTime 또는 DateTime64입니다. 선택적 매개변수입니다.
머지 시 ReplacingMergeTree는 동일한 정렬 키를 가진 모든 행 중 하나만 남깁니다.
ver가 설정되지 않은 경우 선택(selection)에서 마지막 행을 남깁니다. selection은 머지에 참여하는 파트 집합 내 행들의 집합입니다. 가장 최근에 생성된 파트(마지막 삽입)가 selection에서 마지막이 됩니다. 따라서 중복 제거 후에는 각 고유한 정렬 키별로 가장 최근 삽입에서 들어온 마지막 행이 남습니다.ver가 지정된 경우 최댓값 버전을 가진 행을 남깁니다. 여러 행의ver가 같으면 해당 행들에는 “ver가 지정되지 않은 경우” 규칙이 적용됩니다. 즉, 가장 최근에 삽입된 행이 남습니다.
is_deleted
is_deleted — 머지 중 이 행의 데이터가 현재 state를 나타내는지, 또는 삭제 대상인지를 판단하는 데 사용하는 컬럼 이름입니다. 1은 “deleted” 행이고, 0은 “state” 행입니다.
컬럼의 데이터 타입 — UInt8.
is_deleted는 ver를 사용할 때만 활성화할 수 있습니다.데이터에 어떤 작업을 수행하더라도 버전은 증가해야 합니다. 삽입된 두 행의 버전 번호가 같으면, 나중에 삽입된 행이 유지됩니다.기본적으로 ClickHouse는 해당 행이 삭제 행이더라도 키별로 마지막 행을 유지합니다. 이렇게 하면 이후에 더 낮은 버전의 행이 들어와도
안전하게 삽입할 수 있으며, 삭제 행도 계속 적용됩니다.이러한 삭제 행을 영구적으로 삭제하려면 테이블 설정 allow_experimental_replacing_merge_with_cleanup를 활성화한 다음, 다음 중 하나를 수행하십시오.-
테이블 설정
enable_replacing_merge_with_cleanup_for_min_age_to_force_merge,min_age_to_force_merge_on_partition_only,min_age_to_force_merge_seconds를 설정합니다. 파티션의 모든 파트가min_age_to_force_merge_seconds보다 오래된 경우, ClickHouse는 이를 모두 하나의 파트로 머지하고 모든 삭제 행을 제거합니다. -
OPTIMIZE TABLE table [PARTITION partition | PARTITION ID 'partition_id'] FINAL CLEANUP를 수동으로 실행합니다.
쿼리 절
ReplacingMergeTree 테이블을 생성할 때는 MergeTree 테이블을 생성할 때와 동일한 절이 필요합니다.
쿼리 시점 중복 제거 & FINAL
ORDER BY 컬럼 값(테이블 생성 시 사용됨)을 고유 식별자로 사용해 중복 행을 식별하고, 가장 높은 버전만 유지합니다. 그러나 이 방식은 결국 정확한 상태에 수렴할 뿐, 행이 중복 제거된다고 보장하지 않으므로 이에 의존해서는 안 됩니다. 따라서 쿼리에서는 업데이트 행과 삭제 행도 함께 고려될 수 있어, 올바르지 않은 결과가 반환될 수 있습니다.
올바른 결과를 얻으려면 백그라운드 머지에 더해 쿼리 시점의 중복 제거와 삭제 행 제거를 함께 적용해야 합니다. 이는 FINAL 연산자를 사용해 수행할 수 있습니다. 예를 들어, 다음 예시를 살펴보겠습니다:
FINAL 없이 쿼리하면 정확하지 않은 개수가 반환됩니다(정확한 결과는 머지 진행 상태에 따라 달라집니다):
FINAL 성능 최적화 방법을 포함한 FINAL의 자세한 내용은 ReplacingMergeTree 자세히 알아보기를 참조하십시오.