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

> Определения понятий баз данных и терминов ClickHouse с акцентом на отличия в поведении от транзакционных баз данных.

# Глоссарий

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">
          Поиск по терминам и определениям глоссария
        </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="Поиск по терминам и определениям..." autoComplete="off" />
        </div>
        <span className="glossary-count" aria-live="polite">
          {visibleEntries.length} {visibleEntries.length === 1 ? "термин" : "терминов"}
        </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}>
                  Подробнее <span aria-hidden="true">→</span>
                </a>}
            </article>)}
        </div> : <div className="glossary-empty">
          <p>По запросу «{query}» терминов не найдено.</p>
          <button type="button" onClick={() => setQuery("")}>
            Очистить поиск
          </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>;
};

Глоссарий понятий баз данных и терминологии ClickHouse, включая различия в значении привычных терминов баз данных в ClickHouse.

export const glossaryMetadata = {
  delete: {
    learnMore: '/deletes/overview'
  },
  deduplication: {
    aliases: ['дублирующиеся строки', 'уникальное ограничение'],
    learnMore: '/guides/developer/deduplication'
  },
  dictionary: {
    learnMore: '/dictionary'
  },
  'distributed-table': {
    learnMore: '/engines/table-engines/special/distributed'
  },
  final: {
    aliases: ['дубликаты всё ещё отображаются', 'слияние во время выполнения запроса'],
    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: ['триггер вставки'],
    learnMore: '/materialized-view/incremental-materialized-view'
  },
  json: {
    code: true,
    learnMore: '/sql-reference/data-types/newjson'
  },
  'materialized-view': {
    aliases: ['MV', 'сохранённый запрос', 'триггер вставки', 'динамическая таблица', 'динамические таблицы'],
    learnMore: '/materialized-views'
  },
  merge: {
    learnMore: '/merges'
  },
  mergetree: {
    code: true,
    learnMore: '/engines/table-engines/mergetree-family/mergetree'
  },
  mutation: {
    aliases: ['ALTER UPDATE', 'ALTER DELETE', 'оператор MERGE'],
    learnMore: '/concepts/best-practices/avoid-mutations'
  },
  'nullable-column': {
    aliases: ['NULL', 'NULL и значение по умолчанию'],
    learnMore: '/sql-reference/data-types/nullable'
  },
  parts: {
    learnMore: '/concepts/core-concepts/parts'
  },
  partition: {
    aliases: ['PARTITION BY', 'отсечение партиций'],
    learnMore: '/partitions'
  },
  'partitioning-key': {
    learnMore: '/concepts/core-concepts/partitions'
  },
  'primary-key': {
    aliases: ['ORDER BY', 'ключ сортировки', 'уникальный ключ', 'уникальное ограничение'],
    learnMore: '/concepts/core-concepts/primary-indexes'
  },
  projection: {
    aliases: ['проекция и materialized view', 'альтернативный порядок сортировки'],
    learnMore: '/data-modeling/projections'
  },
  'refreshable-materialized-view': {
    aliases: ['materialized view по расписанию', 'обновление materialized view', 'запрос по расписанию', 'запросы по расписанию'],
    learnMore: '/materialized-view/refreshable-materialized-view'
  },
  replacingmergetree: {
    aliases: ['upsert', 'дедупликация', 'дубликаты всё ещё есть', 'оператор 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', 'первичный ключ', 'порядок данных на диске', 'ключ кластеризации', 'столбцы кластеризации', 'кластеризованная таблица', '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: ['истечение срока хранения', 'срок хранения', 'хранение данных'],
    code: true,
    learnMore: '/concepts/features/operations/delete/ttl'
  },
  update: {
    aliases: ['обновление строки', 'легковесное обновление'],
    legacyIds: ['lightweight-update'],
    learnMore: '/updating-data/overview'
  },
  upsert: {
    aliases: ['ON CONFLICT', 'вставка или обновление', 'оператор MERGE'],
    learnMore: '/guides/replacing-merge-tree'
  },
  warehouse: {
    aliases: ['разделение вычислительных ресурсов', 'виртуальное хранилище', 'виртуальные хранилища'],
    learnMore: '/cloud/reference/warehouses'
  }
};

<Glossary metadata={glossaryMetadata}>
  ## Атомарность

  Атомарность означает, что операция видна либо целиком, либо не видна вовсе. В ClickHouse вставка в одну партицию одной таблицы семейства `MergeTree` атомарна, если её строки записываются единым блоком. Вставка, затрагивающая несколько партиций, атомарна по отдельности для каждой партиции, а вставка в distributed таблицу — по отдельности для каждого сегмента. Транзакции из нескольких операторов остаются экспериментальными и ограниченными в применении.

  ## Block

  Блок — это самоописывающийся столбцовый батч строк, используемый для обработки запросов и передачи данных. Блоки — это единицы времени выполнения и передачи по сети, тогда как части данных и гранулы относятся к хранению и индексированию. Обработка значений столбцов блоками позволяет использовать векторизованное выполнение.

  ## Кластер

  Набор узлов (серверов), которые совместно хранят и обрабатывают данные.

  ## CMEK

  В ClickHouse Cloud управляемые клиентом ключи шифрования (CMEK) позволяют защитить ключ шифрования данных (DEK), используемый для данных при хранении, с помощью ключа из сервиса управления ключами (KMS) клиента.

  ## Удаление

  Для таблиц семейства `MergeTree` удаление строк может означать пометку строк как удалённых с помощью `DELETE FROM`, перезапись затронутых частей данных командой `ALTER TABLE ... DELETE` либо эффективное удаление партиции целиком. Легковесные удаления скрывают строки от последующих запросов ещё до того, как данные будут физически удалены в ходе фоновых слияний.

  ## Дедупликация

  В ClickHouse под дедупликацией могут пониматься разные механизмы. При дедупликации версий строк такие движки, как `ReplacingMergeTree`, определяют дублирующиеся версии по ключу сортировки и устраняют их в ходе фоновых слияний в пределах партиции. Реплицируемые движки таблиц, в свою очередь, могут выполнять дедупликацию повторно отправленных блоков вставки по идентификаторам этих блоков.

  ## Словарь

  Словарь обеспечивает доступ по модели ключ-значение к справочным данным из источника в оперативной памяти или из внешнего источника. Если поиск выполняется по ключу, функции работы со словарями или прямой `JOIN` со словарём позволяют избежать многократного сканирования справочной таблицы.

  ## Distributed таблица

  Distributed таблица в ClickHouse — это особый тип таблицы, которая сама не хранит данные, а предоставляет единое представление для распределённой обработки запросов на нескольких серверах кластера.

  ## `FINAL`

  `FINAL` — это модификатор запроса, который применяет преобразования движка, выполняемые при слиянии, прямо во время чтения данных, без физического слияния хранимых частей. Он позволяет получить согласованные результаты от таких движков, как `ReplacingMergeTree`, ещё до завершения фоновых слияний — ценой дополнительных вычислительных ресурсов и памяти при выполнении запроса.

  ## Гранула

  Гранула — это наименьшая логическая группа строк, которую ClickHouse считывает при отсечении данных по основному индексу. По умолчанию она содержит до 8192 строк, однако при адаптивной гранулярности индекса могут создаваться гранулы меньшего размера. Основной индекс, как правило, хранит по одной записи на гранулу.

  ## Incremental materialized view

  Инкрементное материализованное представление выполняет свой запрос по мере вставки данных в исходную таблицу и записывает результат в целевую таблицу. Оно обрабатывает только вновь вставленные блоки, а не всё текущее содержимое исходной таблицы; изменения в присоединяемых правых таблицах не приводят к его повторному запуску.

  ## `JSON`

  Тип `JSON` хранит полуструктурированные документы, пути и типы которых могут различаться от строки к строке. ClickHouse сохраняет обнаруженные пути как подстолбцы, благодаря чему запросы могут эффективно читать отдельные поля. Если схема стабильна, используйте типизированные столбцы или структурные типы, например `Tuple`.

  ## Файл засечек

  Файл засечек (mark file) хранит смещения, определяющие расположение гранул в сжатых данных столбца. Каждая засечка содержит смещение в сжатом файле и смещение внутри соответствующего распакованного блока, что позволяет ClickHouse перейти сразу к нужной грануле, не считывая весь столбец целиком.

  ## Materialized view

  В ClickHouse есть две модели материализованных представлений. Инкрементальное материализованное представление работает как триггер на вставку и обрабатывает только что вставленные блоки, тогда как обновляемое материализованное представление периодически повторно выполняет свой запрос по всему набору данных. Возможности с похожими названиями в других базах данных могут сочетать оба этих поведения, поэтому однозначное соответствие есть не всегда.

  ## Слияние

  Слияние в ClickHouse — это фоновая операция хранения, объединяющая мелкие неизменяемые части данных в более крупные в пределах одной партиции. В зависимости от движка таблицы слияния могут также агрегировать, схлопывать или заменять строки; они не эквивалентны транзакционному SQL-оператору `MERGE`.

  ## `MergeTree`

  `MergeTree` в ClickHouse — это движок таблицы, рассчитанный на высокую скорость приёма данных и большие объёмы данных. Это основной движок хранения в ClickHouse, который предоставляет такие возможности, как столбцовое хранение, пользовательское партиционирование, разреженные первичные индексы и поддержка фоновых слияний данных.

  ## Мутация

  Для таблиц семейства `MergeTree` мутация изменяет или удаляет существующие данные с помощью команд вида `ALTER TABLE ... UPDATE` или `ALTER TABLE ... DELETE`. В отличие от построчного обновления в OLTP-системах, мутация перезаписывает затронутые части данных и, как правило, выполняется асинхронно: части заменяются по мере готовности, поэтому операция не является атомарной транзакцией на уровне всей таблицы.

  ## Nullable-столбец

  Чтобы отличать `NULL` от обычных значений типа `T`, включая такие значения, как `0` или пустая строка, столбец должен иметь тип `Nullable(T)`. ClickHouse хранит отдельную маску null, что увеличивает объём хранилища и накладные расходы на обработку, поэтому используйте столбцы с типом Nullable только там, где отсутствующие значения несут осмысленную семантику, а не по умолчанию.

  ## Мутация «на лету»

  Если параметр `apply_mutations_on_fly` включен как для мутации, так и для последующих чтений, ClickHouse применяет ожидающие обновления и удаления при выполнении запросов `SELECT`, поэтому их результаты видны еще до перезаписи хранимых частей. Сама мутация при этом материализуется асинхронно в фоновом режиме.

  ## Части

  Часть данных (data part) — это неизменяемый набор файлов в хранилище, содержащий часть строк таблицы. Части создаются при вставках и объединяются фоновыми слияниями в пределах партиции. В отличие от партиции, которая является логической группировкой данных, часть — это физическая единица хранения, управляемая ClickHouse.

  ## Партиция

  Партиция — это логическая группировка частей данных в таблице семейства `MergeTree`. Партиционирование предназначено прежде всего для операций управления данными: удаления, перемещения и применения политик хранения к группам данных. Отсечение партиций может ускорить запросы, которые обращаются лишь к нескольким партициям, однако для производительности запросов обычно важнее ключ сортировки и основной ключ.

  ## Ключ партиционирования

  Ключ партиционирования — это выражение в конструкции `PARTITION BY` таблицы. Строки, для которых получается одинаковый partition ID, относятся к одной логической партиции, при этом отдельные вставки могут создавать внутри неё отдельные data parts. Такая группировка позволяет выполнять операции над партицией целиком: удалять, перемещать или архивировать её.

  ## Первичный ключ

  В отличие от первичного ключа во многих транзакционных базах данных, первичный ключ в ClickHouse не является ограничением уникальности на уровне строки. Он определяет столбцы разреженного первичного индекса, который позволяет ClickHouse пропускать гранулы при чтении. По умолчанию он совпадает с ключом сортировки, заданным в `ORDER BY`; если же он задаётся отдельно, он должен быть префиксом ключа сортировки.

  ## Проекция

  Проекция — это автоматически поддерживаемое представление данных таблицы с другим порядком сортировки, подмножеством столбцов или предварительно вычисленной агрегацией. ClickHouse может выбрать её автоматически при выполнении запроса к исходной таблице. Проекции могут дублировать хранимые данные и увеличивать издержки на запись, однако проекции с `_part_offset` позволяют сэкономить место в хранилище ценой дополнительных чтений из базовой таблицы.

  ## Refreshable materialized view

  Refreshable materialized view периодически заново выполняет свой запрос по всему набору данных и по расписанию заменяет или дополняет сохранённый результат. В отличие от incremental materialized view, он не срабатывает на каждом вставляемом блоке и может использовать сложные запросы. Им можно заменить выполняемый по расписанию запрос, который материализует результат `SELECT`, однако универсальным планировщиком для произвольных команд DDL или DML он не является.

  ## `ReplacingMergeTree`

  `ReplacingMergeTree` реализует обновления и upsert-операции, принимая несколько версий строк с одинаковым ключом сортировки и оставляя лишь одну версию при фоновых слияниях. Дедупликация происходит отложенно и не гарантирует уникальность в момент вставки, поэтому запросы могут видеть несколько версий до тех пор, пока не будет применён модификатор `FINAL` или эквивалентная логика запроса либо пока не будут слиты соответствующие части.

  ## Реплика

  Реплика — это сервер или вычислительный инстанс, который хранит те же логические данные таблицы, что и другие реплики, или обращается к ним, обеспечивая доступность и пропускную способность обработки запросов. При использовании `ReplicatedMergeTree` реплики хранят независимые копии данных, тогда как реплики в ClickHouse Cloud с `SharedMergeTree` совместно используют объектное хранилище.

  ## Вторичный индекс

  В ClickHouse ближайшим аналогом привычного вторичного индекса обычно выступает индекс пропуска данных (data skipping index). Вместо поиска отдельных строк по B-дереву он хранит метаданные о группах гранул, благодаря чему ClickHouse может не читать блоки, которые заведомо не содержат подходящих значений.

  ## Сегмент

  Сегмент — это логическое подмножество данных таблицы, закреплённое за одним сервером или группой реплик в распределённом развёртывании. Сегментирование распределяет данные и нагрузку по обработке запросов между серверами, а реплики обеспечивают резервный или параллельный доступ к данным внутри каждого сегмента.

  ## Индекс пропуска данных

  Индекс пропуска данных (data skipping index) хранит компактные метаданные для одной или нескольких последовательных гранул, благодаря чему ClickHouse может не читать блоки, которые заведомо не соответствуют запросу. Наибольшую эффективность он даёт, когда индексируемые значения коррелируют с порядком сортировки таблицы, и приносит мало пользы, если подходящие значения встречаются в большинстве индексируемых блоков.

  ## Ключ сортировки

  Для таблицы семейства `MergeTree` выражение `ORDER BY` задаёт ключ сортировки — физический порядок строк внутри каждого data part. Оно играет ту же роль, что кластеризующие столбцы или кластеризующие ключи в других аналитических базах данных, но ClickHouse использует его для поддержания заданного лексикографического порядка строк. Если отдельный первичный ключ не указан, ключ сортировки одновременно становится и первичным ключом; эти два ключа связаны между собой, но совпадать не обязаны.

  ## Разреженный индекс

  Разреженный первичный индекс хранит значения ключа для каждой гранулы, а не по одной записи на строку. ClickHouse использует эти записи, чтобы определить гранулы-кандидаты, а затем читает их строки. Поскольку размер индекса растёт пропорционально числу гранул, а не строк, он обычно достаточно мал, чтобы целиком помещаться в памяти.

  ## Движок таблицы

  Движки таблиц в ClickHouse определяют, как данные записываются, хранятся и как к ним предоставляется доступ. `MergeTree` — наиболее распространённый движок таблиц: он позволяет быстро вставлять большие объёмы данных, которые затем обрабатываются в фоновом режиме.

  ## Транзакция

  В ClickHouse транзакционные гарантии распространяются иначе, чем в типичной OLTP-базе данных. Отвечающие определённым условиям вставки атомарны на уровне блока или партиции, тогда как классические транзакции из нескольких операторов с `COMMIT` и `ROLLBACK` остаются экспериментальными и имеют существенные ограничения.

  ## `TTL`

  Правила `TTL` перемещают, удаляют или агрегируют данные, когда выполняется заданное выражение. Истечение срока происходит не мгновенно: как правило, ClickHouse применяет действия над устаревшими данными в ходе фоновых слияний, поэтому устаревшие строки могут оставаться на диске и попадать в результаты запросов до тех пор, пока слияние не обработает соответствующие части.

  ## Обновление

  ClickHouse оптимизирован для неизменяемых данных с преобладанием операций добавления, а не для частого обновления строк «на месте». Обновления обычно моделируются вставкой новых версий строк с использованием специализированных движков таблиц либо выполняются как мутации, перезаписывающие затронутые части данных.

  ## Upsert

  Таблицы семейства `MergeTree` не выполняют транзакционный upsert вида `INSERT ... ON CONFLICT`. Обычно upsert реализуется вставкой более новой версии строки в таблицу с движком типа `ReplacingMergeTree`. Устаревшие версии отсеиваются в ходе фоновых слияний, поэтому до выполнения слияния запросам может потребоваться `FINAL` или эквивалентная логика.

  ## Хранилище

  В ClickHouse Cloud хранилище — это набор сервисов, которые работают с одними и теми же данными, но имеют независимые вычислительные ресурсы и конечные точки. В системах, где хранилище соответствует одному вычислительному кластеру, более близким аналогом будет отдельный сервис ClickHouse, тогда как хранилище ClickHouse объединяет несколько сервисов.
</Glossary>
