Why do I still see two rows for one key?
Merges are asynchronous. Query with FINAL, or GROUP BY key and take argMax(column, updated_at), until the background merge collapses them.
Gerador de upsert
Nomeie tabela, chave e colunas e receba a instrução que o ClickHouse realmente aceita, com uma guarda para que uma linha antiga nunca sobrescreva uma nova. Abaixo: como a mecânica funciona, o que quebra e como a Datrise carrega o ClickHouse de forma incremental.
As notas técnicas desta página estão em inglês.
Instrução · INSERT into ReplacingMergeTree + FINAL
-- Declare the target once; the ORDER BY key is the dedupe key and
-- the version column decides which duplicate survives a merge:
-- ENGINE = ReplacingMergeTree(updated_at) ORDER BY (id)
INSERT INTO deals (id, name, stage, amount, owner_id, updated_at)
SELECT id, name, stage, amount, owner_id, updated_at
FROM deals_staging;
-- Reads must ask for the collapsed view; merges are asynchronous.
SELECT id, name, stage, amount, owner_id, updated_at
FROM deals FINAL;ClickHouse does not upsert on write. The idiom is a ReplacingMergeTree table: you INSERT every version of a row, and background merges later collapse duplicates that share the ORDER BY key, keeping the one with the highest version column (updated_at in the generated statement). Until a merge runs, both versions exist, so reads use FINAL or argMax to see the current one.
That trade is what makes ClickHouse fast at ingest: inserts are append-only and cheap, and deduplication is deferred. Insert in large batches, thousands of rows at a time or with async_insert enabled, because each INSERT creates a data part and a table with too many parts throttles writes. Partition by month and order by (key, updated_at) so range scans and merges stay local.
Merges are asynchronous. Query with FINAL, or GROUP BY key and take argMax(column, updated_at), until the background merge collapses them.
No. It forces a full merge of every part and is expensive on large tables. Let merges run in the background and read with FINAL.
ReplacingMergeTree accepts an is_deleted column (ClickHouse 23.2+): insert the row with is_deleted = 1 and a newer version, and merges drop it. Lightweight DELETE also works but marks rows rather than removing them immediately.
A Datrise entrega entidades de CRM e SaaS no ClickHouse com exatamente esta mecânica, uma marca d'água sobre updated-at e colunas tipadas, então a instrução acima é a que roda por você. Entre na lista de espera para acesso antecipado.
Explorar o catálogo de integrações