Для чего используются колоночные базы данных?

Ответ

Колоночные базы данных (columnar stores) оптимизированы для сценариев OLAP (Online Analytical Processing) — сложной аналитической обработки больших объемов данных, в отличие от OLTP (Online Transaction Processing) систем, оптимизированных для множества коротких транзакций.

Ключевое преимущество: скорость выполнения агрегирующих запросов (SUM, AVG, COUNT, GROUP BY) над подмножеством столбцов по миллиардам строк.

Как это работает и почему это быстро:

  1. Хранение по столбцам: Все значения одного столбца хранятся вместе, а не строки целиком. Это позволяет:
  2. Эффективное сжатие: Данные в одном столбце однотипны (например, только INT или DATE), что позволяет применять мощные алгоритмы сжатия (например, run-length encoding, dictionary compression).
  3. Сканирование только нужных столбцов: Для запроса SELECT AVG(salary) FROM employees система читает с диска только блоки колонки salary, пропуская name, email, address.
  4. Векторизованное выполнение: Операции выполняются над целыми массивами (векторами) значений из столбца, что максимально эффективно для CPU.

Типичные use-cases:

  • Бизнес-аналитика (BI) и дашборды.
  • Анализ логов и телеметрии.
  • Хранение и запросы к большим фактологическим таблицам в хранилищах данных (Data Warehouse).

Пример на ClickHouse:

-- Создание таблицы с движком MergeTree (колоночный)
CREATE TABLE user_events (
    event_date Date,
    event_time DateTime,
    user_id UInt32,
    event_type String,
    duration_sec UInt32,
    country_code FixedString(2)
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, user_id);

-- Быстрый аналитический запрос, обрабатывающий миллиарды строк
SELECT 
    toStartOfHour(event_time) AS hour,
    country_code,
    count() AS events_count,
    avg(duration_sec) AS avg_duration
FROM user_events
WHERE event_date >= today() - 7
    AND event_type = 'page_view'
GROUP BY hour, country_code
ORDER BY hour, events_count DESC;

Популярные колоночные СУБД: ClickHouse, Amazon Redshift, Google BigQuery, Vertica. Форматы колоночного хранения: Apache Parquet, Apache ORC — используются в Hadoop/Spark экосистеме.

Недостаток: Запись данных (INSERT/UPDATE) обычно медленнее, чем в строчных базах, так как требует перезаписи целых столбцов. Поэтому они идеальны для append-only или пакетной загрузки данных.

Ответ 18+ 🔞

А, слушай, вот тебе тема про колоночные базы — это вообще отдельная песня, ебать мои старые костыли. Представь себе, есть два типа баз: одни для оперативки (OLTP), где ты постоянно что-то пишешь-читаешь, а другие — для аналитики (OLAP), где надо просеять овердохуища записей и что-то посчитать. Так вот колоночные — это как раз вторые, для аналитики.

В чём прикол, почему они быстрые?

  1. Хранят данные по столбцам. Не как обычно — строка целиком, а все значения из одного столбка лежат вместе. Это, ёпта, ключевое.
  2. Сжатие огонь. Раз в колонке один тип данных (только числа или только даты), их можно сжать так, что места будет занимать в разы меньше. Экономия диска — красота.
  3. Читает только то, что надо. Запрос типа SELECT AVG(zarplata) FROM rabotyagi — система тупо просканит только колонку zarplata, а на FIO, email и прочую хуйню даже смотреть не будет. Это же скорость, чувак!
  4. Векторизованное выполнение. Процессор не по одной записи тыкает, а сразу пачками, целыми массивами значений гоняет. CPU просто в экстазе.

Где это всё втыкают?

  • Всякие дашборды и отчёты для начальства.
  • Анализ логов, где событий — хуй с горы.
  • Большие хранилища данных (Data Warehouse), где таблицы такие, что глаза на лоб лезут.

Пример на ClickHouse:

-- Создаём таблицу на движке MergeTree (он колоночный)
CREATE TABLE user_events (
    event_date Date,
    event_time DateTime,
    user_id UInt32,
    event_type String,
    duration_sec UInt32,
    country_code FixedString(2)
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, user_id);

-- А вот запрос, который за секунды проёбывает миллиарды строк
SELECT 
    toStartOfHour(event_time) AS hour,
    country_code,
    count() AS events_count,
    avg(duration_sec) AS avg_duration
FROM user_events
WHERE event_date >= today() - 7
    AND event_type = 'page_view'
GROUP BY hour, country_code
ORDER BY hour, events_count DESC;

Что из этого популярно: ClickHouse, Amazon Redshift, Google BigQuery. Ещё есть форматы типа Apache Parquet — их в экосистеме Hadoop/Spark юзают.

Но есть, конечно, и ложка дёгтя, ядрёна вошь. Писать в них (INSERT/UPDATE) — обычно медленнее, чем в обычные строчные базы, потому что приходится переписывать целые колонки. Поэтому они идеальны для сценариев, когда данные в основном добавляются пачками (append-only), а не меняются каждую секунду. Для оперативки — не очень, а для аналитики — просто пиздец как хорошо.