> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-vortex-format.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Définitions des concepts relatifs aux bases de données et de la terminologie ClickHouse, en mettant l’accent sur les comportements qui diffèrent de ceux des bases de données transactionnelles.

# Glossaire

export const Glossary = ({children, metadata = {}}) => {
  const nodeText = node => {
    if (node === null || node === undefined || typeof node === "boolean") return "";
    if (typeof node === "string" || typeof node === "number") return String(node);
    if (Array.isArray(node)) return node.map(nodeText).join(" ");
    return nodeText(node.props && node.props.children);
  };
  const entries = [];
  const childNodes = Array.isArray(children) ? children : [children];
  let currentEntry;
  childNodes.forEach(node => {
    const id = node && node.props && node.props.id;
    if (id) {
      currentEntry = {
        id,
        term: nodeText(node),
        content: [],
        ...metadata[id] || ({})
      };
      entries.push(currentEntry);
    } else if (currentEntry && node !== null && node !== undefined) {
      currentEntry.content.push(node);
    }
  });
  const [query, setQuery] = useState("");
  const searchForms = value => {
    const text = String(value);
    const lowercase = text.toLowerCase();
    const words = text.replace(/([a-z0-9])([A-Z])/g, "$1 $2").toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
    return [...new Set([lowercase, words])];
  };
  const queryForms = searchForms(query.trim()).filter(Boolean);
  const matches = (value, exact = false) => searchForms(value).some(valueForm => queryForms.some(queryForm => exact ? valueForm === queryForm : valueForm.includes(queryForm)));
  const matchRank = entry => {
    if (matches(entry.term, true)) return 2;
    if ((entry.aliases || []).some(value => matches(value, true))) return 1;
    return 0;
  };
  const visibleEntries = queryForms.length > 0 ? entries.filter(entry => [entry.term, ...entry.aliases || [], nodeText(entry.content)].some(value => matches(value))).sort((a, b) => matchRank(b) - matchRank(a)) : entries;
  return <div className="not-prose glossary-browser">
      <div className="glossary-search-row">
        <label className="sr-only" htmlFor="glossary-search">
          Rechercher des termes et définitions du glossaire
        </label>
        <div className="glossary-search-wrap">
          <svg aria-hidden="true" viewBox="0 0 20 20" className="glossary-search-icon">
            <path d="m17 17-3.7-3.7m1.7-4.8A6.5 6.5 0 1 1 2 8.5a6.5 6.5 0 0 1 13 0Z" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
          </svg>
          <input id="glossary-search" type="search" value={query} onChange={event => setQuery(event.target.value)} placeholder="Rechercher des termes et définitions..." autoComplete="off" />
        </div>
        <span className="glossary-count" aria-live="polite">
          {visibleEntries.length} {visibleEntries.length === 1 ? "terme" : "termes"}
        </span>
      </div>

      {visibleEntries.length > 0 ? <div className="glossary-grid">
          {visibleEntries.map(entry => <article key={entry.id} className="glossary-entry">
              <h2 id={entry.id} className="glossary-entry-title">
                {entry.code ? <code>{entry.term}</code> : entry.term}
              </h2>
              {(entry.legacyIds || []).map(id => <span key={id} id={id} className="glossary-entry-legacy-anchor" aria-hidden="true" />)}
              <div className="glossary-entry-description">{entry.content}</div>
              {entry.learnMore && <a className="glossary-entry-link" href={entry.learnMore}>
                  En savoir plus <span aria-hidden="true">→</span>
                </a>}
            </article>)}
        </div> : <div className="glossary-empty">
          <p>Aucun terme du glossaire ne correspond à « {query} ».</p>
          <button type="button" onClick={() => setQuery("")}>
            Effacer la recherche
          </button>
        </div>}

      <style>{`
        .glossary-browser { margin-top: 1.5rem; }
        .glossary-search-row { display: flex; align-items: center; gap: .75rem; margin-bottom: 1.25rem; }
        .glossary-search-wrap { position: relative; flex: 1; }
        .glossary-search-icon { position: absolute; top: 50%; left: .85rem; width: 1rem; height: 1rem; color: #6b7280; transform: translateY(-50%); pointer-events: none; }
        .glossary-search-wrap input { width: 100%; height: 2.75rem; padding: 0 1rem 0 2.5rem; color: inherit; background: var(--background-light, #fff); border: 1px solid rgb(156 163 175 / .35); border-radius: .5rem; outline: none; }
        .glossary-search-wrap input:focus { border-color: #f1c40f; box-shadow: 0 0 0 3px rgb(253 255 117 / .35); }
        .dark .glossary-search-wrap input { background: var(--background-dark, #151515); border-color: rgb(107 114 128 / .45); }
        .glossary-count { flex: none; min-width: 4.5rem; color: #6b7280; font-size: .8rem; text-align: right; }
        .dark .glossary-count { color: #9ca3af; }
        .glossary-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: .85rem; }
        .glossary-entry { position: relative; padding: 1.15rem 1.25rem; background: var(--background-light, #fff); border: 1px solid rgb(156 163 175 / .3); border-radius: .65rem; }
        .dark .glossary-entry { background: var(--background-dark, #151515); border-color: rgb(107 114 128 / .35); }
        .glossary-entry-title { margin: 0 0 .55rem; scroll-margin-top: 6rem; font-size: 1.05rem; line-height: 1.35; }
        .glossary-entry-legacy-anchor { position: absolute; top: 0; scroll-margin-top: 6rem; }
        .glossary-entry-title code { font-size: .95em; }
        .glossary-entry-description { color: #4b5563; font-size: .9rem; line-height: 1.55; }
        .dark .glossary-entry-description { color: #d1d5db; }
        .glossary-entry-description p { margin: 0; }
        .glossary-entry-link { display: inline-block; margin-top: .75rem; color: inherit; font-size: .85rem; font-weight: 600; text-decoration: none; }
        .glossary-entry-link:hover { text-decoration: underline; }
        .glossary-empty { padding: 2.5rem 1rem; text-align: center; border: 1px dashed rgb(156 163 175 / .45); border-radius: .65rem; }
        .glossary-empty p { margin: 0 0 .75rem; color: #6b7280; }
        .glossary-empty button { padding: .45rem .75rem; color: inherit; background: transparent; border: 1px solid rgb(156 163 175 / .45); border-radius: .4rem; cursor: pointer; }
        @media (min-width: 768px) {
          .glossary-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
        }
        @media (max-width: 520px) {
          .glossary-search-row { align-items: stretch; flex-direction: column; }
          .glossary-count { min-width: 0; text-align: left; }
        }
      `}</style>
    </div>;
};

Un glossaire des concepts et de la terminologie des bases de données dans ClickHouse, notamment les différences d’utilisation des termes courants dans ClickHouse.

export const glossaryMetadata = {
  delete: {
    learnMore: '/deletes/overview'
  },
  deduplication: {
    aliases: ['lignes en double', 'contrainte d’unicité'],
    learnMore: '/guides/developer/deduplication'
  },
  dictionary: {
    learnMore: '/dictionary'
  },
  'distributed-table': {
    learnMore: '/engines/table-engines/special/distributed'
  },
  final: {
    aliases: ['voit encore des doublons', 'fusion lors de l’exécution de la requête'],
    code: true,
    learnMore: '/sql-reference/statements/select/from#final-modifier'
  },
  granule: {
    learnMore: '/guides/clickhouse/data-modelling/sparse-primary-indexes#clickhouse-index-design'
  },
  'incremental-materialized-view': {
    aliases: ['déclencheur d’insertion'],
    learnMore: '/materialized-view/incremental-materialized-view'
  },
  json: {
    code: true,
    learnMore: '/sql-reference/data-types/newjson'
  },
  'materialized-view': {
    aliases: ['MV', 'requête stockée', 'déclencheur d’insertion', 'table dynamique', 'tables dynamiques'],
    learnMore: '/materialized-views'
  },
  merge: {
    learnMore: '/merges'
  },
  mergetree: {
    code: true,
    learnMore: '/engines/table-engines/mergetree-family/mergetree'
  },
  mutation: {
    aliases: ['ALTER UPDATE', 'ALTER DELETE', 'instruction MERGE'],
    learnMore: '/concepts/best-practices/avoid-mutations'
  },
  'nullable-column': {
    aliases: ['NULL', 'NULL ou valeur par défaut'],
    learnMore: '/sql-reference/data-types/nullable'
  },
  parts: {
    learnMore: '/concepts/core-concepts/parts'
  },
  partition: {
    aliases: ['PARTITION BY', 'élimination de partitions'],
    learnMore: '/partitions'
  },
  'partitioning-key': {
    learnMore: '/concepts/core-concepts/partitions'
  },
  'primary-key': {
    aliases: ['ORDER BY', 'clé de tri', 'clé unique', 'contrainte d’unicité'],
    learnMore: '/concepts/core-concepts/primary-indexes'
  },
  projection: {
    aliases: ['projection ou vue matérialisée', 'ordre de tri alternatif'],
    learnMore: '/data-modeling/projections'
  },
  'refreshable-materialized-view': {
    aliases: ['vue matérialisée planifiée', 'actualiser une vue matérialisée', 'requête planifiée', 'requêtes planifiées'],
    learnMore: '/materialized-view/refreshable-materialized-view'
  },
  replacingmergetree: {
    aliases: ['upsert', 'déduplication', 'a encore des doublons', 'instruction MERGE'],
    code: true,
    learnMore: '/guides/replacing-merge-tree'
  },
  'secondary-index': {
    learnMore: '/optimize/skipping-indexes'
  },
  'skipping-index': {
    learnMore: '/optimize/skipping-indexes'
  },
  'sorting-key': {
    aliases: ['ORDER BY', 'clé primaire', 'ordre sur disque', 'clé de clustering', 'colonnes de clustering', 'table clusterisée', 'CLUSTER BY'],
    learnMore: '/concepts/best-practices/choosing-a-primary-key'
  },
  'sparse-index': {
    learnMore: '/guides/clickhouse/data-modelling/sparse-primary-indexes'
  },
  'table-engine': {
    learnMore: '/engines/table-engines'
  },
  transaction: {
    learnMore: '/guides/developer/transactional'
  },
  ttl: {
    aliases: ['expiration', 'rétention', 'rétention des données'],
    code: true,
    learnMore: '/concepts/features/operations/delete/ttl'
  },
  update: {
    aliases: ['mise à jour de ligne', 'mise à jour légère'],
    legacyIds: ['lightweight-update'],
    learnMore: '/updating-data/overview'
  },
  upsert: {
    aliases: ['ON CONFLICT', 'insérer ou mettre à jour', 'instruction MERGE'],
    learnMore: '/guides/replacing-merge-tree'
  },
  warehouse: {
    aliases: ['séparation du calcul et du stockage', 'entrepôt virtuel', 'entrepôts virtuels'],
    learnMore: '/cloud/reference/warehouses'
  }
};

<Glossary metadata={glossaryMetadata}>
  ## Atomicité

  L'atomicité signifie qu'une opération est observée soit intégralement, soit pas du tout. Dans ClickHouse, un insert dans une partition d'une table de la famille `MergeTree` est atomique lorsque ses rows sont écrites en un seul block. Un insert portant sur plusieurs partitions est atomique séparément pour chaque partition, et un insert dans une table distribuée est atomique séparément pour chaque segment. Les transactions multi-statements restent expérimentales et soumises à des restrictions.

  ## Block

  Un block est un batch de rows en colonnes, auto-descriptif, utilisé pour le query processing et le transfert de données. Les blocks sont des unités de runtime et de wire ; les data parts et les granules relèvent, quant à eux, de concepts distincts de stockage et d'indexing. Le traitement des column values au sein des blocks permet une exécution vectorisée.

  ## Cluster

  Un ensemble de nodes (servers) qui fonctionnent de concert pour stocker et traiter les données.

  ## CMEK

  Dans ClickHouse Cloud, les clés de chiffrement gérées par le client (CMEK) permettent à la clé du service de gestion de clés (KMS) du client de protéger la clé de chiffrement des données (DEK) utilisée pour les données au repos.

  ## Suppression

  Pour les tables de la famille `MergeTree`, supprimer des lignes peut consister à les marquer comme supprimées avec `DELETE FROM`, à réécrire les parties de données concernées avec `ALTER TABLE ... DELETE`, ou à supprimer efficacement une partition entière. Les suppressions légères (lightweight deletes) masquent les lignes aux requêtes ultérieures avant que les données ne soient physiquement supprimées lors des fusions en arrière-plan.

  ## Déduplication

  La déduplication peut désigner différents mécanismes dans ClickHouse. Pour la déduplication de versions de lignes, des engines tels que `ReplacingMergeTree` identifient les versions dupliquées via la sorting key et les résolvent lors des background merges au sein d'une partition. Les table engines Replicated peuvent, quant à eux, dédupliquer les blocs d'insertion réémis en s'appuyant sur leurs identifiants de bloc.

  ## Dictionary

  Un dictionary fournit un accès de type key-value à des données de référence provenant d'une source in-memory ou external. Pour les lookups par key compatibles, les fonctions de dictionary ou un `JOIN` direct sur un dictionary évitent de parcourir de manière répétée une table de référence.

  ## Table Distributed

  Une table distribuée dans ClickHouse est un type particulier de table qui ne stocke pas elle-même les données, mais offre une vue unifiée permettant le traitement distribué des requêtes sur plusieurs serveurs d'un cluster.

  ## `FINAL`

  `FINAL` est un modificateur de requête qui applique, à la lecture des données, les transformations qu'un engine effectue lors du merge, sans fusionner physiquement les parts stockées. Il permet d'obtenir des résultats réconciliés depuis des engines tels que `ReplacingMergeTree` avant la fin des background merges, au prix d'un surcroît de compute et de mémoire au moment de la requête.

  ## Granule

  Un granule est le plus petit groupe logique de lignes que ClickHouse lit pour l'élagage de l'index primaire. Il contient par défaut jusqu'à 8 192 lignes, mais la granularité d'index adaptative peut créer des granules plus petits. En règle générale, l'index primaire stocke une entrée par granule.

  ## Vue matérialisée incrémentale

  Une vue matérialisée incrémentale exécute sa requête à mesure que les données sont insérées dans une table source et écrit le résultat dans une table cible. Elle ne traite que les blocks nouvellement insérés, et non l'état actuel complet de la table source ; de plus, les modifications apportées aux tables jointes du côté droit ne la redéclenchent pas.

  ## `JSON`

  Le type `JSON` stocke des documents semi-structurés dont les chemins et les types peuvent varier d'une ligne à l'autre. ClickHouse enregistre les chemins découverts sous forme de sous-colonnes, ce qui permet aux requêtes de lire efficacement chaque champ. Utilisez des colonnes typées ou des types structurels tels que `Tuple` lorsque le schéma est stable.

  ## Fichier de marques

  Un mark file stocke les offsets permettant de localiser les granules au sein des column data compressées. Chaque mark enregistre un offset dans le fichier compressé ainsi qu'un offset à l'intérieur du block décompressé correspondant, ce qui permet à ClickHouse d'effectuer un seek jusqu'à un granule sans avoir à lire la colonne entière.

  ## Vue matérialisée

  ClickHouse propose deux modèles de vue matérialisée. Une vue matérialisée incrémentale se comporte comme un déclencheur à l'insertion qui traite les blocs nouvellement insérés, tandis qu'une vue matérialisée actualisable réexécute périodiquement sa requête sur l'intégralité du jeu de données. Dans d'autres bases de données, des fonctionnalités portant des noms similaires peuvent combiner ces deux comportements : la correspondance n'est donc pas toujours biunivoque.

  ## Merge

  Un merge dans ClickHouse est une opération de stockage en arrière-plan qui regroupe de petits data parts immuables en parts plus volumineux au sein d'une même partition. Selon le table engine, les merges peuvent également agréger, réduire (collapse) ou remplacer des rows ; ils ne sont pas équivalents à un statement SQL `MERGE` transactionnel.

  ## `MergeTree`

  Un `MergeTree` dans ClickHouse est un moteur de table conçu pour des débits d'ingestion élevés et de grands volumes de données. Il constitue le moteur de stockage central de ClickHouse et offre des fonctionnalités telles que le stockage en colonnes, le partitionnement personnalisé, les index primaires clairsemés et la prise en charge des fusions de données en arrière-plan.

  ## Mutation

  Pour les tables de la famille `MergeTree`, une mutation modifie ou supprime des données existantes au moyen de commandes telles que `ALTER TABLE ... UPDATE` ou `ALTER TABLE ... DELETE`. Contrairement à une mise à jour de ligne OLTP, elle réécrit les data parts concernés et s'exécute normalement de manière asynchrone ; les parts sont remplacés au fur et à mesure qu'ils sont prêts, si bien que l'opération ne constitue pas une transaction atomique portant sur l'ensemble de la table.

  ## Colonne Nullable

  Une colonne doit utiliser `Nullable(T)` pour distinguer `NULL` des valeurs ordinaires de type `T`, y compris de valeurs telles que `0` ou une chaîne vide. ClickHouse stocke un masque de nullité distinct, ce qui engendre un surcoût de stockage et de traitement : n'utilisez donc des colonnes nullables que lorsque les valeurs manquantes ont une sémantique significative, et non par défaut.

  ## Mutation on-the-fly

  Lorsque `apply_mutations_on_fly` est activé à la fois pour une mutation et pour les lectures qui suivent, ClickHouse applique les mises à jour ou les suppressions en attente lors des requêtes `SELECT`, si bien que leurs résultats sont visibles avant même que les parts stockées ne soient réécrites. La mutation n'en est pas moins matérialisée de manière asynchrone en arrière-plan.

  ## Parts

  Un data part est un ensemble immuable de fichiers sur le stockage contenant une partie des lignes d'une table. Les parts sont créés par les insertions et combinés par les fusions en arrière-plan au sein d'une partition. Contrairement à une partition, qui constitue un regroupement logique des données, un part est une unité de stockage physique gérée par ClickHouse.

  ## Partition

  Une partition est un regroupement logique de data parts au sein d'une table de la famille `MergeTree`. Le partitionnement sert avant tout aux opérations de gestion des données, comme la suppression, le déplacement et l'application de politiques de rétention à des groupes de données. Le partition pruning peut bénéficier aux requêtes qui ne sélectionnent que quelques partitions, mais les clés de tri et les clés primaires pèsent généralement davantage sur les performances des requêtes.

  ## Clé de partitionnement

  Une clé de partitionnement est l'expression figurant dans la clause `PARTITION BY` d'une table. Les lignes qui produisent le même identifiant de partition appartiennent à la même partition logique, tandis que des insertions distinctes peuvent créer des data parts distincts au sein de cette partition. Ce regroupement rend possibles des opérations telles que la suppression, le déplacement ou l'archivage d'une partition entière.

  ## Clé primaire

  Contrairement à la primary key de nombreuses bases de données transactionnelles, une primary key ClickHouse n'est pas une contrainte d'unicité au niveau des lignes. Elle définit les colonnes du sparse primary index qui permet à ClickHouse d'ignorer des granules lors de la lecture. Par défaut, elle correspond à la sorting key définie par `ORDER BY` ; si elle est définie séparément, elle doit constituer un préfixe de la sorting key.

  ## Projection

  Une projection est une représentation, maintenue automatiquement, des données d'une table selon un ordre différent, avec un sous-ensemble de colonnes ou une agrégation précalculée. ClickHouse peut la sélectionner automatiquement lors de l'interrogation de la table d'origine. Les projections peuvent dupliquer les données stockées et alourdir les écritures, même si les projections `_part_offset` permettent de réduire le stockage au prix de lectures supplémentaires dans la table de base.

  ## Vue matérialisée actualisable

  Une vue matérialisée actualisable réexécute périodiquement sa requête sur l'intégralité du jeu de données et remplace ou complète le résultat stocké selon une planification définie. Contrairement à une vue matérialisée incrémentale, elle n'est pas déclenchée par chaque bloc inséré et peut recourir à des requêtes complexes. Elle peut se substituer à une requête planifiée qui matérialise un résultat `SELECT`, mais elle ne constitue pas un ordonnanceur généraliste pour des instructions DDL ou DML quelconques.

  ## `ReplacingMergeTree`

  `ReplacingMergeTree` modélise les updates et les upserts en acceptant plusieurs versions de rows partageant la même sorting key et en n'en conservant qu'une seule lors des background merges. La deduplication est différée et ne constitue pas une garantie d'unicité à l'insert-time : les queries peuvent donc voir plusieurs versions tant qu'elles n'utilisent pas `FINAL` ou une logique de query équivalente, ou tant que les parts concernées n'ont pas fusionné.

  ## Replica

  Une réplique est un serveur ou une instance de compute qui conserve les mêmes données logiques de table que les autres répliques, ou y accède, afin d'assurer la disponibilité et la capacité de requêtage. Avec `ReplicatedMergeTree`, chaque réplique conserve sa propre copie indépendante des données ; à l'inverse, les répliques ClickHouse Cloud utilisant `SharedMergeTree` partagent un stockage objet.

  ## Index secondaire

  Dans ClickHouse, l'équivalent le plus proche d'un index secondaire classique est généralement un data skipping index. Au lieu de localiser des rows individuelles au moyen d'un arbre B, il stocke des metadata pour des groupes de granules, ce qui permet à ClickHouse d'éviter de lire les blocks qui ne peuvent pas contenir de valeurs correspondantes.

  ## Segment

  Un segment est un sous-ensemble logique des données d'une table affecté à un serveur ou à un groupe de répliques dans un déploiement distribué. Le partitionnement en segments répartit les données et la charge des requêtes entre les serveurs ; les répliques assurent quant à elles un accès redondant ou parallèle aux données de chaque segment.

  ## Index de saut de données

  Un data skipping index stocke des metadata compactes pour un ou plusieurs granules consécutifs, ce qui permet à ClickHouse d'éviter de lire les blocks qui ne peuvent pas correspondre à une query. Il est d'autant plus efficace que les values indexées sont corrélées à l'ordre de tri de la table, et n'apporte que peu de gain lorsque les values recherchées sont présentes dans la plupart des blocks indexés.

  ## Clé de tri

  Pour une table de la famille `MergeTree`, la clause `ORDER BY` définit la clé de tri : l'ordre physique des lignes au sein de chaque data part. Elle joue un rôle comparable à celui des colonnes ou des clés de clustering dans d'autres bases de données analytiques, mais ClickHouse l'utilise pour maintenir un ordre lexicographique défini des lignes. Si aucune clé primaire distincte n'est spécifiée, la clé de tri devient également la clé primaire ; les deux clés sont liées, mais elles n'ont pas besoin d'être identiques.

  ## Index sparse

  Un index primaire sparse stocke les valeurs de clé de chaque granule plutôt qu'une entrée par row. ClickHouse s'appuie sur ces entrées pour identifier les granules candidats, puis en lit les rows. Sa taille évoluant avec le nombre de granules et non avec celui des rows, l'index reste généralement assez petit pour être conservé en mémoire.

  ## Moteur de table

  Les table engines de ClickHouse déterminent la manière dont les données sont écrites, stockées et consultées. `MergeTree` est le table engine le plus courant : il permet l'insertion rapide de grands volumes de données, qui sont ensuite traitées en arrière-plan.

  ## Transaction

  Dans ClickHouse, la portée des garanties transactionnelles diffère de celle d'une base de données OLTP classique. Les inserts éligibles sont atomiques au niveau du block ou de la partition, tandis que les transactions multi-statements classiques avec `COMMIT` et `ROLLBACK` restent expérimentales et sont soumises à d'importantes restrictions.

  ## `TTL`

  Les règles `TTL` déplacent, suppriment ou agrègent les données dès qu'une expression devient éligible. L'expiration n'est pas immédiate : ClickHouse applique généralement les actions sur les données expirées lors des background merges ; les expired rows peuvent donc subsister sur le disk et être renvoyées par les queries tant qu'un merge n'a pas traité les parts concernées.

  ## Mise à jour

  ClickHouse est optimisé pour des données immuables, majoritairement ajoutées en fin de table (append), plutôt que pour des mises à jour fréquentes de lignes en place. Les mises à jour sont généralement modélisées par l'insertion de nouvelles versions à l'aide de moteurs de table spécialisés, ou réalisées sous forme de mutations qui réécrivent les data parts concernées.

  ## Upsert

  Les tables de la famille `MergeTree` n'effectuent pas d'upsert transactionnel `INSERT ... ON CONFLICT`. Les upserts sont généralement modélisés en insérant une version plus récente de la row dans un engine tel que `ReplacingMergeTree`. Les versions antérieures sont résolues lors des background merges : les queries peuvent donc nécessiter `FINAL` ou une logique équivalente tant que le merging n'a pas eu lieu.

  ## Warehouse

  Dans ClickHouse Cloud, un warehouse est un ensemble de services qui partagent les mêmes données tout en disposant de ressources de compute et d'endpoints indépendants. Dans les systèmes où un warehouse correspond à un seul cluster de compute, l'équivalent le plus proche est un service ClickHouse individuel ; un warehouse ClickHouse, lui, regroupe plusieurs services.
</Glossary>
