Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

Moteur de table ReplacingMergeTree

Ce moteur diffère de MergeTree par le fait qu’il supprime les entrées en double ayant la même valeur de clé de tri (section ORDER BY de la table, et non PRIMARY KEY).

La déduplication des données ne se produit que lors d’une fusion. Les fusions s’effectuent en arrière-plan à un moment indéterminé, vous ne pouvez donc pas vous appuyer dessus dans votre planification. Une partie des données peut rester non traitée. Bien que vous puissiez lancer une fusion non planifiée à l’aide de la requête OPTIMIZE, ne comptez pas dessus, car la requête OPTIMIZE lira et écrira une grande quantité de données.

Ainsi, ReplacingMergeTree convient pour supprimer les données en double en arrière-plan afin d’économiser de l’espace, mais il ne garantit pas l’absence de doublons.

Créer une table

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

Pour une description des paramètres de la requête, consultez la description de l’instruction.

Paramètres de ReplacingMergeTree

ver

ver — colonne contenant le numéro de version. Type UInt*, Date, DateTime ou DateTime64. Paramètre facultatif.

Lors de la fusion, ReplacingMergeTree ne conserve qu’une seule ligne parmi toutes celles ayant la même clé de tri :

  • La dernière de la sélection, si ver n’est pas défini. Une sélection est un ensemble de lignes dans un ensemble de parts participant à la fusion. La part créée le plus récemment (la dernière insertion) sera la dernière de la sélection. Ainsi, après déduplication, c’est la toute dernière ligne de l’insertion la plus récente qui sera conservée pour chaque clé de tri unique.
  • Celle ayant la version maximale, si ver est spécifié. Si ver est identique pour plusieurs lignes, la règle "si ver n’est pas spécifié" s’applique alors, c’est-à-dire que la ligne insérée le plus récemment sera conservée.

Exemple :

-- without ver - the last inserted 'wins'
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 — Nom d’une colonne utilisée lors d’une fusion pour déterminer si les données de cette ligne représentent un état ou doivent être supprimées ; 1 correspond à une ligne "supprimée", 0 à une ligne "d’état".

Type de données de la colonne — UInt8.

Exemple :

-- with ver and 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.

-- delete rows with is_deleted
OPTIMIZE TABLE myThirdReplacingMT FINAL CLEANUP;

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

select * from myThirdReplacingMT final;

Clauses de requête

Lors de la création d'une table ReplacingMergeTree, les mêmes clauses sont requises que pour la création d'une table MergeTree.

Méthode obsolète de création d'une table
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])

Tous les paramètres, à l'exception de ver, ont la même signification que dans MergeTree.

  • ver - colonne contenant la version. Paramètre facultatif. Pour une description, voir le texte ci-dessus.

Déduplication à l’exécution de la requête & FINAL

Lors des fusions, ReplacingMergeTree identifie les lignes dupliquées en utilisant les valeurs des colonnes ORDER BY (utilisées pour créer la table) comme identifiant unique, et ne conserve que la version la plus élevée. Cela ne garantit toutefois la correction qu’à terme : rien n’assure que les lignes seront dédupliquées, et vous ne devez pas vous y fier. Les requêtes peuvent donc produire des résultats incorrects, car des lignes mises à jour ou supprimées peuvent encore être prises en compte.

Pour obtenir des résultats corrects, les utilisateurs doivent donc compléter les fusions en arrière-plan par une déduplication à l’exécution de la requête et la suppression des lignes marquées comme supprimées. Pour cela, on peut utiliser l’opérateur FINAL. Par exemple, prenons l’exemple suivant :

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

Exécuter une requête sans FINAL produit un décompte incorrect (le résultat exact variera selon les opérations de fusion) :

SELECT count()
FROM rmt_example

L’ajout de FINAL donne un résultat correct :

SELECT count()
FROM rmt_example
FINAL

Pour en savoir plus sur FINAL, notamment sur la façon d’optimiser ses performances, nous vous recommandons de consulter notre guide détaillé sur ReplacingMergeTree.

Navigation