이 엔진은 동일한 정렬 키 값(ORDER BY 테이블 절, PRIMARY KEY 아님)을 가진 중복 레코드를 제거한다는 점에서 MergeTree와 다릅니다.
데이터 중복 제거는 머지 중에만 발생합니다. 머지는 시점을 알 수 없는 상태로 백그라운드에서 수행되므로 이를 계획할 수 없습니다. 일부 데이터는 처리되지 않은 채 남아 있을 수 있습니다. OPTIMIZE 쿼리를 사용해 예정되지 않은 머지를 실행할 수는 있지만, OPTIMIZE 쿼리는 대량의 데이터를 읽고 쓰므로 이에 의존해서는 안 됩니다.
따라서 ReplacingMergeTree는 공간 절약을 위해 백그라운드에서 중복 데이터를 정리하는 데는 적합하지만, 중복이 전혀 없다고 보장하지는 않습니다.
테이블 생성
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE = ReplacingMergeTree([ver [, is_deleted]])
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]요청 매개변수에 대한 설명은 SQL 문 설명을 참조하십시오.
ReplacingMergeTree 매개변수
ver
ver — 버전 번호를 담는 컬럼입니다. 유형은 UInt*, Date, DateTime 또는 DateTime64입니다. 선택적 매개변수입니다.
머지 시 ReplacingMergeTree는 동일한 정렬 키를 가진 모든 행 중 하나만 남깁니다.
ver가 설정되지 않은 경우 선택(selection)에서 마지막 행을 남깁니다. selection은 머지에 참여하는 파트 집합 내 행들의 집합입니다. 가장 최근에 생성된 파트(마지막 삽입)가 selection에서 마지막이 됩니다. 따라서 중복 제거 후에는 각 고유한 정렬 키별로 가장 최근 삽입에서 들어온 마지막 행이 남습니다.ver가 지정된 경우 최댓값 버전을 가진 행을 남깁니다. 여러 행의ver가 같으면 해당 행들에는 "ver가 지정되지 않은 경우" 규칙이 적용됩니다. 즉, 가장 최근에 삽입된 행이 남습니다.
예시:
-- ver 없음 - 마지막으로 삽입된 행이 '우선'
CREATE TABLE myFirstReplacingMT
(
`key` Int64,
`someCol` String,
`eventTime` DateTime
)
ENGINE = ReplacingMergeTree
ORDER BY key;
INSERT INTO myFirstReplacingMT Values (1, 'first', '2020-01-01 01:01:01');
INSERT INTO myFirstReplacingMT Values (1, 'second', '2020-01-01 00:00:00');
SELECT * FROM myFirstReplacingMT FINAL;
┌is_deleted
is_deleted — 머지 중 이 행의 데이터가 현재 state를 나타내는지, 또는 삭제 대상인지를 판단하는 데 사용하는 컬럼 이름입니다. 1은 "deleted" 행이고, 0은 "state" 행입니다.
컬럼의 데이터 타입 — UInt8.
예시:
-- ver 및 is_deleted 사용
CREATE OR REPLACE TABLE myThirdReplacingMT
(
`key` Int64,
`someCol` String,
`eventTime` DateTime,
`is_deleted` UInt8
)
ENGINE = ReplacingMergeTree(eventTime, is_deleted)
ORDER BY key
SETTINGS allow_experimental_replacing_merge_with_cleanup = 1;
INSERT INTO myThirdReplacingMT Values (1, 'first', '2020-01-01 01:01:01', 0);
INSERT INTO myThirdReplacingMT Values (1, 'first', '2020-01-01 01:01:01', 1);
select * from myThirdReplacingMT final;
0 rows in set. Elapsed: 0.003 sec.
-- is_deleted로 행 삭제
OPTIMIZE TABLE myThirdReplacingMT FINAL CLEANUP;
INSERT INTO myThirdReplacingMT Values (1, 'first', '2020-01-01 00:00:00', 0);
select * from myThirdReplacingMT final;
┌쿼리 절
ReplacingMergeTree 테이블을 생성할 때는 MergeTree 테이블을 생성할 때와 동일한 절이 필요합니다.
Deprecated 테이블 생성 방법
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
) ENGINE [=] ReplacingMergeTree(date-column [, sampling_expression], (primary, key), index_granularity, [ver])ver를 제외한 모든 매개변수의 의미는 MergeTree와 동일합니다.
ver- 버전 정보를 담는 컬럼입니다. 선택적 매개변수입니다. 자세한 설명은 위 내용을 참조하십시오.
쿼리 시점 중복 제거 & FINAL
머지 시점에 ReplacingMergeTree는 ORDER BY 컬럼 값(테이블 생성 시 사용됨)을 고유 식별자로 사용해 중복 행을 식별하고, 가장 높은 버전만 유지합니다. 그러나 이 방식은 결국 정확한 상태에 수렴할 뿐, 행이 중복 제거된다고 보장하지 않으므로 이에 의존해서는 안 됩니다. 따라서 쿼리에서는 업데이트 행과 삭제 행도 함께 고려될 수 있어, 올바르지 않은 결과가 반환될 수 있습니다.
올바른 결과를 얻으려면 백그라운드 머지에 더해 쿼리 시점의 중복 제거와 삭제 행 제거를 함께 적용해야 합니다. 이는 FINAL 연산자를 사용해 수행할 수 있습니다. 예를 들어, 다음 예시를 살펴보겠습니다:
CREATE TABLE rmt_example
(
`number` UInt16
)
ENGINE = ReplacingMergeTree
ORDER BY number
INSERT INTO rmt_example SELECT floor(randUniform(0, 100)) AS number
FROM numbers(1000000000)
0 rows in set. Elapsed: 19.958 sec. Processed 1.00 billion rows, 8.00 GB (50.11 million rows/s., 400.84 MB/s.)FINAL 없이 쿼리하면 정확하지 않은 개수가 반환됩니다(정확한 결과는 머지 진행 상태에 따라 달라집니다):
SELECT count()
FROM rmt_example
┌FINAL을 추가하면 올바른 결과가 반환됩니다:
SELECT count()
FROM rmt_example
FINAL
┌FINAL 성능 최적화 방법을 포함한 FINAL의 자세한 내용은 ReplacingMergeTree 자세히 알아보기를 참조하십시오.