> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

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

# Motor de tabela ReplacingMergeTree

O motor difere de [MergeTree](/docs/pt-BR/reference/engines/table-engines/mergetree-family/mergetree) por remover entradas duplicadas com o mesmo valor da [chave de ordenação](/docs/pt-BR/reference/engines/table-engines/mergetree-family/mergetree) (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.

<Note>
  Um guia detalhado sobre ReplacingMergeTree, incluindo melhores práticas e como otimizar o desempenho, está disponível [aqui](/docs/pt-BR/concepts/features/operations/update/replacing-merge-tree).
</Note>

<div id="creating-a-table">
  ## Criar uma tabela
</div>

```sql theme={null}
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](/docs/pt-BR/reference/statements/create/table).

<Note>
  A unicidade das linhas é determinada pela cláusula `ORDER BY` da tabela, não pela `PRIMARY KEY`.
</Note>

<div id="replacingmergetree-parameters">
  ## Parâmetros do ReplacingMergeTree
</div>

<div id="ver">
  ### `ver`
</div>

`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:

```sql theme={null}
-- 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;

┌─key─┬─someCol─┬───────────eventTime─┐
│   1 │ second  │ 2020-01-01 00:00:00 │
└─────┴─────────┴─────────────────────┘

-- com ver - a linha com o maior ver 'vence'
CREATE TABLE mySecondReplacingMT
(
    `key` Int64,
    `someCol` String,
    `eventTime` DateTime
)
ENGINE = ReplacingMergeTree(eventTime)
ORDER BY key;

INSERT INTO mySecondReplacingMT Values (1, 'first', '2020-01-01 01:01:01');
INSERT INTO mySecondReplacingMT Values (1, 'second', '2020-01-01 00:00:00');

SELECT * FROM mySecondReplacingMT FINAL;

┌─key─┬─someCol─┬───────────eventTime─┐
│   1 │ first   │ 2020-01-01 01:01:01 │
└─────┴─────────┴─────────────────────┘
```

<div id="is_deleted">
  ### `is_deleted`
</div>

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

<Note>
  `is_deleted` só pode ser habilitado quando `ver` é usado.

  Independentemente da operação realizada nos dados, a versão deve ser incrementada. Se duas linhas inseridas tiverem o mesmo número de versão, a última linha inserida será mantida.

  Por padrão, o ClickHouse manterá a última linha de uma chave, mesmo que ela seja uma linha de exclusão. Isso garante que quaisquer linhas futuras com versões menores possam
  ser inseridas com segurança, e a linha de exclusão ainda será aplicada.

  Para remover permanentemente essas linhas de exclusão, habilite a configuração da tabela `allow_experimental_replacing_merge_with_cleanup` e então:

  1. Defina as configurações da tabela `enable_replacing_merge_with_cleanup_for_min_age_to_force_merge`, `min_age_to_force_merge_on_partition_only` e `min_age_to_force_merge_seconds`. Se todas as partes em uma partição forem mais antigas que `min_age_to_force_merge_seconds`, o ClickHouse fará a mesclagem de
     todas elas em uma única parte e removerá quaisquer linhas de exclusão.

  2. Execute manualmente `OPTIMIZE TABLE table [PARTITION partition | PARTITION ID 'partition_id'] FINAL CLEANUP`.
</Note>

Exemplo:

```sql theme={null}
-- 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;

┌─key─┬─someCol─┬───────────eventTime─┬─is_deleted─┐
│   1 │ first   │ 2020-01-01 00:00:00 │          0 │
└─────┴─────────┴─────────────────────┴────────────┘
```

<div id="query-clauses">
  ## Cláusulas da consulta
</div>

Ao criar uma tabela `ReplacingMergeTree`, são necessárias as mesmas [cláusulas](/docs/pt-BR/reference/engines/table-engines/mergetree-family/mergetree) exigidas na criação de uma tabela `MergeTree`.

<details markdown="1">
  <summary>Método obsoleto para criar uma tabela</summary>

  <Note>
    Não use este método em novos projetos e, se possível, migre os projetos antigos para o método descrito acima.
  </Note>

  ```sql theme={null}
  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.
</details>

<div id="query-time-de-duplication--final">
  ## Desduplicação em tempo de consulta & FINAL
</div>

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:

```sql theme={null}
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):

```sql theme={null}
SELECT count()
FROM rmt_example

┌─count()─┐
│     200 │
└─────────┘

1 row in set. Elapsed: 0.002 sec.
```

Adicionar FINAL gera o resultado correto:

```sql theme={null}
SELECT count()
FROM rmt_example
FINAL

┌─count()─┐
│     100 │
└─────────┘

1 row in set. Elapsed: 0.002 sec.
```

Para mais detalhes sobre `FINAL`, inclusive sobre como otimizar seu desempenho, recomendamos a leitura do nosso [guia detalhado sobre ReplacingMergeTree](/docs/pt-BR/concepts/features/operations/update/replacing-merge-tree).
