ClickHouseJuniorTechnical

Что такое ClickHouse и к какому типу СУБД он относится?

ClickHouse — колоночная аналитическая СУБД (OLAP) с открытым исходным кодом от Яндекса. Обрабатывает миллиарды строк в секунду благодаря векторизованному движку, компрессии колонок и специализированным движкам хранения семейства MergeTree.

Что такое ClickHouse

ClickHouse — система управления базами данных класса OLAP (Online Analytical Processing) с открытым исходным кодом. Разработана Яндексом в 2009 году для внутренних нужд Метрики, в 2016 году выложена в open source. Сейчас развивается компанией ClickHouse Inc. и активным сообществом.

Ключевые характеристики

  • Колоночное хранение: данные каждой колонки хранятся отдельно, что минимизирует I/O при агрегирующих запросах.
  • Векторизованное исполнение: обработка данных блоками по 8 192 строк с использованием SIMD-инструкций (SSE4.2, AVX2, AVX-512).
  • Сжатие: по умолчанию LZ4; поддерживаются ZSTD, Gorilla, Delta, T64 и другие кодеки на уровне колонки.
  • SQL-диалект: богатый SQL с расширениями (ARRAY JOIN, WITH ROLLUP, WINDOW FUNCTIONS, ASOF JOIN).
  • Масштабирование: горизонтальное — через Distributed-таблицы и шардирование; вертикальное — многопоточное исполнение одного запроса.

Движки хранения

Главное семейство — MergeTree и его производные:

  • MergeTree — базовый движок, первичный ключ + партиционирование.
  • ReplicatedMergeTree — репликация через ZooKeeper/ClickHouse Keeper.
  • SummingMergeTree — суммирует числовые колонки при мерже.
  • AggregatingMergeTree — хранит промежуточные состояния агрегатов.
  • ReplacingMergeTree — дедупликация строк по ключу при мерже.
  • CollapsingMergeTree / VersionedCollapsingMergeTree — инкрементальные обновления через sign-колонку.

Быстрый старт

-- Создание таблицы с партиционированием по месяцам
CREATE TABLE page_views (
    view_id     UUID DEFAULT generateUUIDv4(),
    user_id     UInt64,
    page_path   String,
    duration_ms UInt32,
    event_ts    DateTime,
    country     LowCardinality(String)
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_ts)
ORDER BY (country, event_ts, user_id)
TTL event_ts + INTERVAL 1 YEAR DELETE;

-- Вставка данных (batch INSERT — лучше всего)
INSERT INTO page_views (user_id, page_path, duration_ms, event_ts, country)
VALUES
    (1001, '/home', 1200, now(), 'RU'),
    (1002, '/jobs', 3400, now(), 'US'),
    (1001, '/profile', 800, now(), 'RU');

-- Аналитический запрос
SELECT
    country,
    toDate(event_ts)    AS date,
    count()             AS views,
    uniq(user_id)       AS unique_users,
    avg(duration_ms)    AS avg_duration_ms
FROM page_views
WHERE event_ts >= now() - INTERVAL 30 DAY
GROUP BY country, date
ORDER BY views DESC
LIMIT 20;

Запуск через Docker

docker run -d \
  --name clickhouse-server \
  -p 8123:8123 \
  -p 9000:9000 \
  -e CLICKHOUSE_DB=analytics \
  -e CLICKHOUSE_USER=user \
  -e CLICKHOUSE_PASSWORD=secret \
  clickhouse/clickhouse-server:latest

# Подключение через CLI
docker exec -it clickhouse-server clickhouse-client --user user --password secret

Что ClickHouse не умеет (или умеет плохо)

  • OLTP: точечные UPDATE/DELETE строк — дорогие асинхронные операции.
  • Транзакции: ограниченная поддержка (ACID только для одной таблицы).
  • Высокочастотные одиночные INSERT: каждая вставка создаёт part; нужны batch-вставки (минимум 1 000 строк).

Подводные камни

  • Частые маленькие INSERT: каждый INSERT создаёт новый part; при >1 вставки/сек ClickHouse начинает ругаться на "too many parts" — используйте Buffer-таблицы или очереди (Kafka engine, Async insert).
  • ORDER BY ≠ PRIMARY KEY: в ClickHouse первичный ключ — это только sparse index поверх ORDER BY; дублирующиеся ключи допустимы (в отличие от PostgreSQL).
  • NULL обработка: тип Nullable(T) замедляет обработку из-за отдельного битового массива null-флагов; избегайте Nullable в ORDER BY колонках.
  • JOIN — не сильная сторона: ClickHouse загружает правую таблицу JOIN в память каждого потока; для больших таблиц используйте словари или денормализацию.
  • SELECT COUNT(*) без WHERE: читает метаданные part-ов и быстр, но SELECT COUNT(col) читает саму колонку — разные планы исполнения.
  • Время: ClickHouse по умолчанию хранит DateTime в UTC; локальное время сервера влияет на toStartOfDay — всегда явно указывайте таймзону: toStartOfDay(ts, 'Europe/Moscow').

Common mistakes

  • Объяснять clickhouse как column-oriented olap субд как OLTP-механику row-store базы вместо аналитической колоночной модели ClickHouse.
  • Путать primary key ClickHouse с уникальным constraint из PostgreSQL или MySQL.
  • Игнорировать parts, merges, ORDER BY, sparse index и стоимость маленьких вставок.
  • Предлагать синтаксис или транзакционное поведение, которого в ClickHouse нет.

What the interviewer is testing

  • Кандидат объясняет clickhouse как column-oriented olap субд через реальный механизм ClickHouse, а не общими словами.
  • Приводит корректный SQL или диагностический запрос для этой СУБД.
  • Называет ограничения, версионные отличия или эксплуатационные последствия.
  • Связывает ответ с проектированием приложения, производительностью, надежностью или безопасностью.

Sources

Related topics