Что такое колоночные базы данных и почему они лучше для аналитики
Что проверяют
Понимаете ли вы, что скорость запроса определяется не только индексами, но и раскладкой данных на диске. Для питониста это прикладной вопрос: от выбора хранилища зависит, считается ли агрегат по сотне миллионов строк секунды или минуты, и есть ли вообще смысл тянуть эти строки в pandas.
Как отвечать
Начните с механики. В строковом хранилище значения одной записи лежат рядом, поэтому дёшево достать или изменить запись целиком. В колоночном рядом лежат значения одного поля всех записей, поэтому запрос вида «сумма по одному полю с фильтром по второму» читает с диска два поля из пятидесяти, а не всю таблицу.
Отсюда три источника выигрыша:
- меньше ввода-вывода, читаются только затронутые колонки;
- лучше сжатие, в колонке однородные значения одного типа, работают словарное кодирование, RLE, дельта-кодирование;
- векторизация, движок обрабатывает блок значений одного типа целиком вместо строки за строкой.
Примеры стоит назвать точные: ClickHouse, Vertica, Greenplum, DuckDB, форматы Parquet и ORC, облачные BigQuery и Redshift. В Python это ровно тот стык, где pyarrow и polars читают Parquet по нужным колонкам и с отсечением кусков по статистике, а read_csv тянет всё подряд.
Закончите границей применимости: на точечной выборке по ключу и на частых обновлениях одной записи колоночное хранилище проигрывает строковому.
Где спотыкаются
Называют Cassandra примером колоночной аналитической базы. Это хранилище с широкими колонками: данные группируются по ключу партиции, раскладка ближе к строковой, нагрузка точечная. Термин похож, суть другая, и интервьюер это слышит сразу.
Противопоставляют колоночное хранилище реляционному. Это разные оси: модель данных отдельно, физическая раскладка отдельно. ClickHouse и Redshift реляционные и говорят на SQL, просто хранят поля по колонкам.
Делают вывод «положим в Parquet и станет быстро». Выигрыш появляется, когда запрос берёт подмножество колонок и фильтрует по полю, по которому данные упорядочены. Привычный SELECT * по всей таблице отдаёт преимущество обратно.