Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Motor de tabela ReplacingMergeTree

O motor difere de MergeTree por remover entradas duplicadas com o mesmo valor da chave de ordenação (cláusula ORDER BY da tabela, não PRIMARY KEY).

A desduplicação de dados ocorre apenas durante uma mesclagem. As mesclagens ocorrem em segundo plano, em um momento desconhecido, portanto não é possível planejá-las. Parte dos dados pode permanecer sem processamento. Embora seja possível executar uma mesclagem não programada usando a consulta OPTIMIZE, não dependa disso, porque a consulta OPTIMIZE lerá e gravará uma grande quantidade de dados.

Assim, ReplacingMergeTree é adequado para remover dados duplicados em segundo plano a fim de economizar espaço, mas não garante a ausência de duplicatas.

Criar uma tabela

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, ...]

Para ver uma descrição dos parâmetros da solicitação, consulte a descrição da instrução.

Parâmetros do ReplacingMergeTree

ver

ver — coluna com o número da versão. Tipo UInt*, Date, DateTime ou DateTime64. Parâmetro opcional.

Durante a mesclagem, o ReplacingMergeTree mantém apenas uma entre todas as linhas com a mesma chave de ordenação:

  • A última na seleção, se ver não estiver definido. Uma seleção é um conjunto de linhas em um conjunto de partes que participam da mesclagem. A parte criada mais recentemente (o último insert) será a última na seleção. Assim, após a desduplicação, a última linha do insert mais recente permanecerá para cada chave de ordenação exclusiva.
  • A de versão máxima, se ver for especificado. Se ver for o mesmo para várias linhas, será usada para elas a regra "se ver não for especificado", isto é, a linha inserida mais recentemente permanecerá.

Exemplo:

-- sem ver - o último inserido 'vence'
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 — Nome de uma coluna usada durante uma mesclagem para determinar se os dados nesta linha representam o estado ou devem ser excluídos; 1 é uma linha "excluída", 0 é uma linha de "estado".

Tipo de dados da coluna — UInt8.

Exemplo:

-- com ver e 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.

-- excluir linhas com is_deleted
OPTIMIZE TABLE myThirdReplacingMT FINAL CLEANUP;

INSERT INTO myThirdReplacingMT Values (1, 'first', '2020-01-01 00:00:00', 0);

select * from myThirdReplacingMT final;

Cláusulas da consulta

Ao criar uma tabela ReplacingMergeTree, são necessárias as mesmas cláusulas exigidas na criação de uma tabela MergeTree.

Método obsoleto para criar uma tabela
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])

Todos os parâmetros, exceto ver, têm o mesmo significado que em MergeTree.

  • ver - coluna com a versão. Parâmetro opcional. Para mais detalhes, consulte o texto acima.

Desduplicação em tempo de consulta & FINAL

Durante a mesclagem, o ReplacingMergeTree identifica linhas duplicadas usando os valores das colunas de ORDER BY (usadas para criar a tabela) como identificador único e mantém apenas a versão mais alta. No entanto, isso oferece apenas correção eventual — não garante que as linhas serão desduplicadas, e você não deve depender disso. Portanto, as consultas podem produzir respostas incorretas porque linhas de atualização e exclusão são consideradas nas consultas.

Para obter respostas corretas, os usuários precisarão complementar as mesclagens em segundo plano com desduplicação em tempo de consulta e remoção de linhas excluídas. Isso pode ser feito usando o operador FINAL. Por exemplo, considere o exemplo a seguir:

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.)

Consultar sem FINAL gera uma contagem incorreta (o resultado exato varia conforme as mesclagens):

SELECT count()
FROM rmt_example

Adicionar FINAL gera o resultado correto:

SELECT count()
FROM rmt_example
FINAL

Para mais detalhes sobre FINAL, inclusive sobre como otimizar seu desempenho, recomendamos a leitura do nosso guia detalhado sobre ReplacingMergeTree.

Navigation