Learning Platform
Глоссарий Troubleshooting
Урок 08.07 · 15 мин
Средний
Data ModelingDecision FrameworkDenormalizationTime-SeriesLog AnalyticsSCDNestedDeduplicationSummary

Итоги модуля: Data Modeling Patterns

Модуль 07 покрывает шесть фундаментальных паттернов моделирования данных в ClickHouse. Каждый паттерн решает конкретный класс задач: от аналитики событий до управления dimension-таблицами.

Этот урок связывает все шесть паттернов в единую систему принятия решений.


Краткий обзор паттернов

Урок 1: Денормализация и широкие таблицы (OBT)

Главный принцип: JOIN при INSERT, а не при SELECT. В ClickHouse JOIN загружает правую таблицу целиком в RAM, поэтому денормализация (One Big Table) устраняет JOINs из аналитических запросов. ETL pipeline обогащает факты dimension-данными при записи. Компромисс — dictGet() для dimension enrichment без полной денормализации. Не подходит для часто обновляемых dimensions (high churn).

Урок 2: Моделирование временных рядов

Ключевые решения: кодеки и ORDER BY. Codec chains: Delta+ZSTD для timestamps, Gorilla+LZ4 для float-значений, DoubleDelta+ZSTD для монотонных счётчиков. ORDER BY (metric_name, timestamp) — metric first для cardinalitу ordering, timestamp second для range-сканов. DateTime64(3) для миллисекундной гранулярности. PARTITION BY toYYYYMM() для lifecycle management через TTL.

Урок 3: Схемы для лог-аналитики

ClickHouse как замена ELK/Loki: столбцовое хранение + text index + TTL. LowCardinality для уровней и сервисов, text index (GA 26.2) для полнотекстового поиска по message, bloom_filter для trace_id корреляции, Map(LowCardinality(String), String) для переменных атрибутов (Kubernetes labels). Daily partitions + TTL для агрессивного retention. 5-10x экономия места по сравнению с Elasticsearch.

Урок 4: Медленно меняющиеся измерения (SCD)

ReplacingMergeTree для SCD Type 1 (overwrite): version column + FINAL при чтении. SCD Type 2 (full history) через plain MergeTree с valid_from/valid_to. is_deleted для soft-delete в ReplacingMergeTree (24.x+). Критическая деталь: дедупликация происходит при merge, а не при INSERT — между merges видны все версии.

Урок 5: Nested, Map и плоские схемы для событий

Четыре подхода к хранению event properties: Nested (параллельные массивы, ARRAY JOIN для разворачивания), плоская схема (фиксированные столбцы, максимальная производительность запросов), Map (переменные ключи, динамические атрибуты), JSON type (GA 25.3, полностью semi-structured). Nested — для известных ключей с умеренной кардинальностью. Плоская — для фиксированной схемы. Map — для переменных атрибутов. JSON — для полностью динамических данных.

Урок 6: Стратегии дедупликации

Четыре стратегии: ReplacingMergeTree + FINAL (простейший паттерн, дедупликация при чтении), argMax/argMin (query-time dedup через GROUP BY, без зависимости от merge state), Deduplicated MV (AggregatingMergeTree + argMaxState, insert-time dedup, лучшая производительность чтения), OPTIMIZE TABLE FINAL (batch cleanup, O(all data), только для maintenance).


Decision framework: какой паттерн выбрать?

Decision Framework: 6 паттернов Data Modeling
Денормализация (OBT)Денормализация (OBT): аналитика событий + dimension enrichment. JOIN при INSERT через ETL. Сотни столбцов -- норма для ClickHouse. Используй когда: основная нагрузка -- GROUP BY / WHERE по нескольким полям из разных сущностей.
Временные рядыВременные ряды: метрики, IoT, финансовые данные. Delta/Gorilla/DoubleDelta кодеки для 10-100x сжатия. ORDER BY (metric, ts) для range-сканов. Используй когда: данные -- числовые значения с монотонным timestamp.
Лог-аналитикаЛог-аналитика: application logs, traces, audit. text index для полнотекстового поиска, bloom_filter для корреляции, Map для переменных атрибутов. Используй когда: неструктурированный текст + trace correlation + агрессивный TTL.
SCD (Dimensions)SCD (Slowly Changing Dimensions): справочники клиентов, продуктов, тарифов. ReplacingMergeTree для Type 1 (перезапись), MergeTree с valid_from/valid_to для Type 2 (история). Используй когда: dimension обновляется редко, но нужна актуальная версия при запросе.
Nested / Map / FlatNested / Map / Flat: моделирование свойств событий. Плоская -- максимальная производительность, Nested -- известные ключи с ARRAY JOIN, Map -- переменные атрибуты, JSON -- полностью динамические. Используй когда: событие несёт набор свойств (properties), и нужно выбрать формат хранения.
ДедупликацияДедупликация: устранение дублей из append-only потока. ReplacingMergeTree+FINAL (простота), argMax (гибкость), MV+argMaxState (производительность чтения), OPTIMIZE FINAL (batch cleanup). Используй когда: CDC/Kafka доставляет дубликаты, и нужно гарантировать уникальность.

Матрица выбора паттерна

Ваши данныеРекомендуемый паттернКлючевой механизм
Факты + dimensions, аналитические запросыДенормализация (OBT)ETL JOIN при INSERT, dictGet() для dimension enrichment
Числовые значения с timestampsВременные рядыDelta/Gorilla кодеки, ORDER BY (metric, ts)
Текстовые логи, tracesЛог-аналитикаtext index, bloom_filter, Map, TTL
Справочники с редкими обновлениямиSCDReplacingMergeTree + FINAL или MergeTree + valid_from/valid_to
События со свойствамиNested / Map / FlatЗависит от динамичности схемы
Потоки с дубликатами (CDC, Kafka)ДедупликацияReplacingMergeTree, argMax, MV, OPTIMIZE

Связь с другими модулями

Паттерны модуля 07 опираются на механизмы, изученные ранее:

  • Модуль 01 (Storage Engine): parts, merges, кодеки — фундамент для всех паттернов. Codec chains из Урока 2 работают благодаря per-column compression в MergeTree parts.
  • Модуль 03 (Engine Family): ReplacingMergeTree, SummingMergeTree, AggregatingMergeTree — движки для SCD и дедупликации. Выбор движка определяет паттерн.
  • Модуль 04 (Materialized Views): MV + AggregatingMergeTree — основа для Deduplicated MV (стратегия 3 из Урока 6). Также MV для pre-aggregation в time-series.
  • Модуль 05 (Skip Indexes): text index для лог-аналитики, bloom_filter для trace correlation — механизмы индексации из Модуля 05 применяются в паттернах Модуля 07.

Ключевые выводы

  1. Денормализация — основной паттерн для аналитики в ClickHouse. JOIN при INSERT через ETL, а не при каждом SELECT. dictGet() — компромисс для часто обновляемых dimensions.

  2. Codec chains определяют эффективность time-series: Delta+ZSTD для timestamps, Gorilla+LZ4 для float. ORDER BY (metric, ts) — metric first для cardinality ordering.

  3. text index (GA 26.2) заменяет ngrambf_v1/tokenbf_v1 для полнотекстового поиска в логах. Map — для переменных атрибутов. Daily partitions + TTL для retention.

  4. ReplacingMergeTree — инструмент для SCD Type 1. Дедупликация при merge, а не при INSERT. FINAL для чтения актуальной версии. is_deleted для soft-delete.

  5. Выбор формата event properties зависит от динамичности схемы: Flat (максимум производительности), Nested (известные ключи), Map (переменные), JSON (динамические).

  6. Четыре стратегии дедупликации покрывают весь спектр: от простого FINAL до MV с argMaxState. OPTIMIZE TABLE FINAL — только для batch maintenance, никогда в application code.

Проверьте понимание

Результат: 0 из 0
Аналитический
Вопрос 1 из 4. Компания получает 500 миллионов событий в день. Каждое событие содержит user_id, product_id, event_type. Для аналитики нужны user.country и product.category в каждом запросе. user-таблица -- 50 миллионов строк, product-таблица -- 1 миллион строк. Какая комбинация паттернов оптимальна?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 7