- Permet d’écrire rapidement des états d’objets qui changent en permanence.
- Supprime les anciens états d’objet en arrière-plan. Cela réduit considérablement le volume de stockage.
VersionedCollapsingMergeTree remplit le même rôle que CollapsingMergeTree, mais utilise un algorithme de collapsing différent qui permet d’insérer les données dans n’importe quel ordre avec plusieurs threads. En particulier, la colonne Version aide à effectuer correctement le collapsing des lignes, même si elles sont insérées dans le mauvais ordre. À l’inverse, CollapsingMergeTree n’autorise qu’une insertion strictement consécutive.
Création d’une table
Paramètres du moteur
Clauses de requête
VersionedCollapsingMergeTree, les mêmes clauses sont requises que pour la création d’une table MergeTree.
Collapsing
Données
Sign lors de l’écriture de la ligne. Si Sign = 1, cela signifie que la ligne représente l’état d’un objet (appelons-la la ligne d’« état »). Si Sign = -1, cela indique l’annulation de l’état d’un objet ayant les mêmes attributs (appelons-la la ligne d’« annulation »). Utilisez également la colonne Version, qui doit identifier chaque état d’un objet par un numéro distinct.
Par exemple, nous voulons calculer combien de pages les utilisateurs ont consultées sur un site donné et combien de temps ils y sont restés. À un moment donné, nous écrivons la ligne suivante avec l’état de l’activité de l’utilisateur :
Sign.
La deuxième ligne contient l’état actuel.
Comme nous n’avons besoin que du dernier état de l’activité de l’utilisateur, les lignes
VersionedCollapsingMergeTree le fait lors de la fusion des parties de données.
Pour comprendre pourquoi nous avons besoin de deux lignes pour chaque modification, consultez Algorithm.
Remarques sur l’utilisation
- Le programme qui écrit les données doit mémoriser l’état d’un objet pour pouvoir l’annuler. La chaîne “Annulation” doit contenir des copies des champs de la clé primaire, de la version de la chaîne “état” et du
Signopposé. Cela augmente la taille initiale du stockage, mais permet d’écrire les données rapidement. - Les tableaux qui s’allongent dans les colonnes réduisent l’efficacité du moteur en raison de la charge d’écriture. Plus les données sont simples, meilleure est l’efficacité.
- Les résultats de
SELECTdépendent fortement de la cohérence de l’historique des modifications de l’objet. Soyez précis lors de la préparation des données à insérer. Des données incohérentes peuvent produire des résultats imprévisibles, comme des valeurs négatives pour des métriques non négatives telles que la profondeur de session.
Algorithme
Sign différent. L’ordre des lignes n’a pas d’importance.
Lorsque ClickHouse insère des données, il trie les lignes selon la clé primaire. Si la colonne Version ne fait pas partie de la clé primaire, ClickHouse l’y ajoute implicitement comme dernier champ et l’utilise pour le tri.
Sélection des données
SELECT avec plusieurs threads et ne peut pas prédire l’ordre des lignes dans le résultat. Cela signifie qu’une agrégation est nécessaire si vous devez obtenir des données entièrement « collapsées » à partir d’une table VersionedCollapsingMergeTree.
Pour finaliser le collapsing, écrivez une requête avec une clause GROUP BY et des fonctions d’agrégation qui tiennent compte du signe. Par exemple, pour calculer une quantité, utilisez sum(Sign) au lieu de count(). Pour calculer une somme, utilisez sum(Sign * x) au lieu de sum(x), et ajoutez HAVING sum(Sign) > 0.
Les agrégats count, sum et avg peuvent être calculés de cette manière. L’agrégat uniq peut être calculé si un objet possède au moins un état non collapsé. Les agrégats min et max ne peuvent pas être calculés, car VersionedCollapsingMergeTree n’enregistre pas l’historique des valeurs des états collapsés.
Si vous devez extraire les données avec « collapsing », mais sans agrégation (par exemple, pour vérifier si des lignes sont présentes dont les valeurs les plus récentes correspondent à certaines conditions), vous pouvez utiliser le modificateur FINAL dans la clause FROM. Cette approche est inefficace et ne doit pas être utilisée avec de grandes tables.
Exemple d’utilisation
INSERT pour créer deux parties de données différentes. Si nous insérons les données avec une seule requête, ClickHouse crée une seule partie de données et n’effectuera jamais de merge.
Récupération des données :
INSERT. La requête SELECT a été exécutée dans deux threads, et le résultat est un ordre aléatoire des lignes.
Le collapsing ne s’est pas produit, car les parties de données n’ont pas encore été fusionnées. ClickHouse fusionne les parties de données à un moment que nous ne pouvons pas prévoir.
C’est pourquoi nous avons besoin d’une agrégation :
FINAL dans la clause FROM.