Чем строковое хранение отличается от колоночного?
- Почему ClickHouse быстрее PostgreSQL на аналитике?
- Что такое OLTP и OLAP?
- Зачем нужно колоночное хранилище?
Строковое: строка лежит целиком подряд — быстро прочитать или изменить одну запись (OLTP). Колоночное: каждая колонка лежит отдельно — быстро посчитать агрегат по нескольким колонкам миллиардов строк (OLAP).
- Аналитический запрос читает 3 колонки из 100 — колоночное хранилище читает 3%
- Колонка однотипна и похожа сама на себя — сжимается в разы лучше
- Обработка векторами: одна операция над тысячами значений
А ещё Цена — точечные вставки и обновления дорогие, поэтому пишут пачками
Подробно
OLTP (online transaction processing) — много коротких операций над отдельными записями: оформить заказ, обновить профиль. Нужно быстро достать или изменить всю строку по ключу. OLAP (analytics) — мало тяжёлых запросов по огромным объёмам: выручка по дням и регионам за год. Нужно прочитать несколько колонок у миллиардов строк.
Строковое хранение (PostgreSQL, MySQL): все поля строки лежат рядом на странице. Чтение строки по ключу — одна страница. Но запрос SUM(amount) GROUP BY day прочитает все страницы целиком, включая десятки ненужных колонок.
Колоночное хранение (ClickHouse, Vertica, BigQuery, Parquet): значения каждой колонки хранятся отдельно и подряд. Выигрыш:
- читаем только нужные колонки — запрос по 3 колонкам из 100 читает в ~30 раз меньше;
- сжатие — значения одного типа и часто повторяются (статус, страна, дата): кодирование словарём, RLE, дельта-кодирование для времени дают сжатие в 5–20 раз, а значит, ещё меньше чтения с диска;
- векторное выполнение — обработка блоками по тысячам значений с SIMD-инструкциями, мало ветвлений, хороший кэш;
- разреженные индексы и сортировка по ключу позволяют пропускать целые блоки по min/max.
Цена: вставить одну строку — значит дописать в каждую колонку; изменить или удалить — дорого. Поэтому данные пишут пачками (тысячи строк за раз), а изменения реализуют асинхронными мутациями или схемами вроде ReplacingMergeTree. Точечный запрос «одна строка по id» тоже хуже, чем в строковой базе.
Как сочетают на практике: транзакции — в PostgreSQL, оттуда поток изменений (CDC, Kafka) — в ClickHouse для отчётов и дашбордов. Для озера данных — файлы Parquet в объектном хранилище. Есть и гибриды: колоночные расширения для PostgreSQL, HTAP-системы.
Пример
Таблица events: 2 млрд строк, 60 колонок, ~1,2 ТБ в строковом виде.
SELECT toDate(ts), count(), uniq(user_id) FROM events
WHERE ts >= now() - INTERVAL 30 DAY GROUP BY 1;
Строковое: прочитать ~1,2 ТБ (или индекс + случайный доступ).
Колоночное: ts и user_id за 30 дней, сжатые, ~6 ГБ → секунды.Что хотят услышать
- Разница раскладки на диске и почему она важна для OLTP и OLAP.
- Чтение только нужных колонок, сжатие, векторная обработка.
- Цена: дорогие точечные вставки и изменения, запись пачками.
- Типичная архитектура: OLTP-база → CDC → колоночное хранилище.
Частые ошибки
- Предлагать ClickHouse как основную базу для транзакций.
- Вставлять в колоночное хранилище по одной строке.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✓Строковое хранение — для частых записей и чтения отдельных строк (OLTP); колоночное — для агрегатов по нескольким колонкам огромных таблиц (OLAP)
- ✗Колоночное хранение быстрее для обновления одной записи и для OLTP, а строковое лучше сжимается и выгоднее для агрегатов по огромным таблицам
- ✗Колонки сжимаются хуже строк
- ✗Аналитический запрос в колоночной базе читает все колонки таблицы
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.