Что такое движки таблиц, MergeTree, Log, Memory, File, Table, Null, различия и применение
От Log до MergeTree: понимание фундаментальных движков ClickHouse
Движок таблиц (table engine) в ClickHouse определяет:
Синтаксис:
CREATE TABLE table_name (columns) ENGINE = EngineName(parameters);| Семейство | Назначение | Production |
|---|---|---|
| MergeTree | Основное семейство для аналитики | ✅ Да |
| Log | Простые временные таблицы | ❌ Нет |
| Memory | Данные в RAM | ❌ Нет |
| Интеграция | Внешние источники | ⚠️ Специфично |
| Специальные | Null, File, URL | ⚠️ Специфично |
MergeTree — семейство движков, разработанное специально для ClickHouse. Это выбор по умолчанию для production-нагрузок.
Возможности:
CREATE TABLE events
(
event_time DateTime,
user_id UInt64,
event_type String,
value Decimal(10, 2)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_time)
ORDER BY (event_time, user_id)
PRIMARY KEY (event_time, user_id)
SETTINGS index_granularity = 8192;Обязательный параметр! Определяет порядок сортировки данных внутри партиции.
ORDER BY (event_time, user_id)Важно:
Правила выбора ORDER BY:
-- Хороший ORDER BY для типичных запросов:
ORDER BY (event_date, user_id, event_type)
-- Запросы будут быстрыми:
WHERE event_date = '2026-03-01'
WHERE event_date = '2026-03-01' AND user_id = 123
WHERE event_date = '2026-03-01' AND user_id = 123 AND event_type = 'click'PARTITION BY toYYYYMM(event_time) -- По месяцам
PARTITION BY toYYYYMMDD(event_time) -- По дням
PARTITION BY (year, month) -- По нескольким колонкамЗачем нужно:
ALTER TABLE DROP PARTITIONРекомендации:
toYYYYMM(event_time) — по месяцамPRIMARY KEY (event_time, user_id)В ClickHouse первичный ключ:
Как работает:
Данные отсортированы:
event_time | user_id | ...
2026-03-01 | 1 | ...
2026-03-01 | 100 | ...
2026-03-01 | 200 | ... ← Индекс: (2026-03-01, 200) → гранула 1
2026-03-01 | 300 | ...
2026-03-01 | 400 | ... ← Индекс: (2026-03-01, 400) → гранула 2
...
Запрос: WHERE event_time = '2026-03-01' AND user_id BETWEEN 250 AND 350
→ Индекс пропускает гранулы 1 и 3+, читает только гранулу 2
SETTINGS index_granularity = 8192 -- По умолчаниюГранула — минимальная единица чтения данных:
Когда менять:
CREATE TABLE page_views
(
event_time DateTime DEFAULT now(),
user_id UInt64,
session_id UInt64,
page_url String,
referer String,
country LowCardinality(String),
city LowCardinality(String),
screen_width UInt16,
screen_height UInt16,
is_mobile UInt8,
duration_ms UInt32
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_time)
ORDER BY (event_time, user_id, session_id)
PRIMARY KEY (event_time, user_id, session_id)
SETTINGS index_granularity = 8192;Обоснование:
PARTITION BY toYYYYMM — по месяцам, удобно для TTLORDER BY (event_time, user_id, session_id) — типичные запросы по времени и пользователюLowCardinality(String) для country/city — сжатиеДвижки Log предназначены для простых временных таблиц. Не рекомендуются для production.
CREATE TABLE temp_logs
(
timestamp DateTime,
message String
)
ENGINE = Log;Характеристики:
Когда использовать:
ENGINE = StripeLog; -- Общий индекс для всех колонок
ENGINE = TinyLog; -- Без индексов вообщеРазличия:
CREATE TABLE cache_table
(
key String,
value String
)
ENGINE = Memory;Характеристики:
Когда использовать:
CREATE TABLE sink_table
(
any_column String
)
ENGINE = Null;Назначение:
CREATE TABLE file_table
(
col1 UInt32,
col2 String
)
ENGINE = File(TabSeparated);Назначение:
-- Чтение из файла как из таблицы
SELECT * FROM file('data.csv', 'CSV', 'col1 UInt32, col2 String');
-- Чтение из URL
SELECT * FROM url('https://example.com/data.json', 'JSON');Назначение:
| Характеристика | MergeTree | Log | Memory |
|---|---|---|---|
| Индексы | ✅ Да | ❌ Нет | ❌ Нет |
| Сортировка | ✅ Да | ❌ Нет | ❌ Нет |
| Партиционирование | ✅ Да | ❌ Нет | ❌ Нет |
| Репликация | ✅ Да | ❌ Нет | ❌ Нет |
| Сжатие | ✅ Да | ⚠️ Минимальное | ❌ Нет |
| Сохранение на диск | ✅ Да | ✅ Да | ❌ Нет |
| Производительность вставки | Высокая | Очень высокая | Максимальная |
| Производительность чтения | Очень высокая | Низкая | Высокая |
| Production ready | ✅ Да | ❌ Нет | ❌ Нет |
Используйте MergeTree, если:
Используйте Log, если:
Используйте Memory, если:
CREATE TABLE analytics_events
(
event_time DateTime DEFAULT now(),
event_date Date DEFAULT toDate(event_time),
user_id UInt64,
event_type LowCardinality(String),
platform LowCardinality(String),
country LowCardinality(String),
properties Map(String, String)
)
ENGINE = MergeTree()
PARTITION BY event_date
ORDER BY (event_date, user_id, event_type)
SETTINGS index_granularity = 8192;CREATE TABLE system_metrics
(
timestamp DateTime DEFAULT now(),
host LowCardinality(String),
metric_name LowCardinality(String),
value Float64
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(timestamp)
ORDER BY (timestamp, host, metric_name)
SETTINGS index_granularity = 8192;CREATE TABLE staging_data
(
id UInt64,
raw_data String,
loaded_at DateTime DEFAULT now()
)
ENGINE = Log;
-- После обработки данные перемещаются в основную таблицу
INSERT INTO main_table SELECT * FROM staging_data WHERE ...;Изучим продвинутые движки семейства MergeTree: Replacing, Summing, Aggregating и другие.
Вопросы ещё не добавлены
Вопросы для этой подтемы ещё не добавлены.