Получить доступ

Чем строковое хранение отличается от колоночного?

MiddleХранение данных
Ещё спрашивают так:
  • Почему ClickHouse быстрее PostgreSQL на аналитике?
  • Что такое OLTP и OLAP?
  • Зачем нужно колоночное хранилище?
Коротко

Строковое: строка лежит целиком подряд — быстро прочитать или изменить одну запись (OLTP). Колоночное: каждая колонка лежит отдельно — быстро посчитать агрегат по нескольким колонкам миллиардов строк (OLAP).

  • Аналитический запрос читает 3 колонки из 100 — колоночное хранилище читает 3%
  • Колонка однотипна и похожа сама на себя — сжимается в разы лучше
  • Обработка векторами: одна операция над тысячами значений

А ещё Цена — точечные вставки и обновления дорогие, поэтому пишут пачками

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

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 как основную базу для транзакций.
  • Вставлять в колоночное хранилище по одной строке.

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем