← назад к разделу

После знакомства с разными базами возникает главный вопрос: что выбрать для своей задачи? Универсально лучшего хранилища нет. Одна база быстро читает документ целиком, другая соединяет таблицы, третья ищет по тексту, четвертая агрегирует миллиарды событий. Поэтому выбирают не технологию по известности, а модель данных и гарантии под конкретные запросы.

Сравнительная таблица

ХранилищеТип данныхКогда выбиратьКогда не выбирать
PostgreSQLТаблицы, строки, jsonbОсновная база приложения, заказы, платежи, связи, JOIN, транзакции, отчеты среднего размераОгромный поток событий без обновлений, файлы целиком, специализированный поисковый или аналитический контур
MongoDBДокументыОбъект читается целиком, структура документов меняется, вложенные атрибуты, каталог с разными типами товаровМного связей и соединений, строгая целостность между сущностями, сложные транзакции по всей системе
RedisКлюч-значение и структуры в памятиКэш, сессии, счетчики, короткие очереди, блокировки, рейтинги, быстрый доступ по известному ключуЕдинственное хранилище критичных данных без продуманной долговечности, произвольные запросы по содержимому
ElasticsearchПоисковый индекс документовПолнотекстовый поиск, релевантность, опечатки, фасеты, поисковые подсказки, логиОсновная база заказов и платежей, строгие транзакции, запись как единственный источник истины
ClickHouseКолонки и большие наборы событийАналитика, витрины, агрегаты по миллионам и миллиардам строк, метрики, события, OLAPЧастые точечные обновления, короткие транзакции, чтение одной карточки по всем колонкам
CassandraШирокие строки по ключу разделаОчень большой поток записи, события и телеметрия, предсказуемые запросы, работа в нескольких регионахПроизвольные запросы, JOIN, аналитика, транзакции между строками, неизвестная заранее модель чтения
Neo4jУзлы и связи графаМногошаговые обходы, рекомендации, антифрод, социальные связи, граф знаний, GraphRAGПростые сущности без важных связей, обычные фильтры и агрегаты, где хватает реляционных таблиц
S3 и object storageФайлы и объектыИзображения, видео, архивы, резервные копии, выгрузки, Parquet и озеро данныхЗапросы к отдельным полям записи, транзакции, быстрые обновления одной строки

Таблица не отвечает, какая база лучше. Она помогает отбросить явно неподходящие варианты. Финальный выбор делают по реальным запросам и нагрузке.

Ориентиры по TPS и объему

TPS здесь означает операции в секунду: чтение по простому ключу или простая запись. Диапазоны нужны только для первой прикидки класса решения. Это не предельные характеристики и не обещание производительности.

Допущения: современный сервер с SSD или небольшой кластер, короткие операции, индексы под запросы, пакетная запись там, где она допустима. Сложный JOIN, большой документ, строгая согласованность или синхронная репликация уменьшают эти числа на порядки.

ХранилищеЧтение, TPSЗапись, TPSРабочий объем
PostgreSQL10 000-100 000 точечных1 000-10 000 транзакцийСотни ГБ - несколько ТБ на узел
MongoDB10 000-100 000 документов1 000-10 000 документовСотни ГБ - десятки ТБ
Redis50 000-500 000 операций50 000-500 000 операцийДесятки - сотни ГБ оперативной памяти
Elasticsearch100-5 000 поисковых запросов5 000-50 000 документов на индексациюСотни ГБ - десятки ТБ индексов
ClickHouse10-1 000 аналитических запросов50 000-1 000 000 строк пакетамиТБ - сотни ТБ событий
Cassandra1 000-50 000 партиций5 000-100 000 строкТБ - сотни ТБ на кластер
Neo4j100-5 000 обходов100-5 000 транзакцийДесятки ГБ - несколько ТБ графа
S3 и object storage100-5 000 объектов100-5 000 объектовОт КБ до ТБ на объект, общий объем практически не ограничен

Числа нельзя сравнивать как скорость автомобилей. Аналитический запрос ClickHouse сканирует миллионы строк, обход Neo4j проходит переменное число связей, а чтение Redis возвращает маленькое значение по ключу. Поэтому сначала выбирают модель операции, а диапазон используют как проверку реалистичности.

Механизмы масштабирования по размеру

Размер и нагрузкаЧто применять в первую очередь
Горячие данные помещаются в памятьИндексы, пул соединений, компактные ответы, кэш повторных чтений в Redis
Сотни ГБ, чтение по известным ключамСоставные и покрывающие индексы, разделение горячих и холодных данных, реплики чтения
Тысячи записей в секундуПакетная запись, меньше индексов на запись, быстрые диски, очередь перед базой для сглаживания пиков
ТБ историиПартиционирование по времени или ключу, срок хранения, агрегаты, доставка истории в ClickHouse
Десятки ТБ и большеШардинг по осмысленному ключу, отдельный аналитический контур, object storage для сырых данных
Десятки тысяч записей непрерывноПакеты и очереди, Cassandra при предсказуемых чтениях по ключу раздела, ClickHouse для аналитического потока
Большие файлыS3 плюс CDN, в базе только метаданные и ссылка на объект

Это не жесткие пороги. Сотня ГБ с плохим запросом может быть проблемой раньше, чем десять ТБ хорошо партиционированных событий. Смотрят на рабочий набор, а не только на общий размер базы.

Как посчитать требуемый TPS

Формула для первой оценки:

Требуемый TPS = средний TPS в час пик × коэффициент пиковой нагрузки × запас на рост и сбои

Обычно берут пик в 5-10 раз выше среднего и запас 1,5-2 раза. Например, в час пик приложение читает 200 операций в секунду, а пишет 40:

Чтение: 200 × 8 × 2 = 3 200 TPS
Запись:   40 × 5 × 2 =   400 TPS

Одна PostgreSQL с подходящими индексами вполне кандидат на такой профиль. Но решение подтверждают нагрузочным тестом: смотрят не только TPS, а задержку p95 и p99, ошибки, память, диск и длину очереди. Если при этом чтение упирается в повторы, добавляют кэш. Если запись растет быстрее одного узла, сначала оптимизируют пакеты и индексы, а уже потом шардируют.

Пример объема: 80 ТБ фотографий

Есть 50 млн карточек, по 4 фотографии размером 400 КБ:

50 000 000 × 4 × 400 КБ = 80 000 000 000 КБ ≈ 80 ТБ

Байты изображений держат в S3, в PostgreSQL оставляют идентификатор товара, адрес объекта, порядок снимка и технические метаданные. Для раздачи ставят CDN, иначе 20 000 запросов изображений в секунду превратятся в дорогой поток через приложение и хранилище. Если часть снимков удаляется или меняется, отдельно проектируют очистку старых объектов и ссылку в базе.

Алгоритм выбора

1. Выписать главные операции

Возьмите пять самых частых чтений и три самые важные записи. Не «пользователь работает с заказами», а конкретно:

  • найти заказ по номеру со всеми позициями;
  • показать последние двадцать заказов покупателя;
  • посчитать продажи по дням и категориям;
  • найти товары по названию и атрибутам;
  • списать остаток и записать платеж одной транзакцией.

По этому списку видно модель доступа: чтение по ключу, обход связей, поиск по тексту или сканирование большого набора событий.

2. Определить основной тип нагрузки

  • Заказы, платежи, остатки и другие операционные записи - OLTP, обычно PostgreSQL.
  • Объекты с изменчивой структурой и чтением целиком - документная база.
  • Быстрые временные данные по ключу - Redis рядом с основной базой.
  • Поиск по тексту - поисковый индекс, не обязательно отдельная основная база.
  • Агрегаты по большой истории - аналитическое хранилище.
  • Обход связей на несколько шагов - графовая модель.
  • Большие файлы - object storage.

Основной тип нагрузки один, даже если в системе есть задачи всех видов. Именно он определяет источник истины.

3. Записать обязательные гарантии

Ответьте на четыре вопроса:

  1. Какие операции обязаны быть атомарными?
  2. Можно ли читать данные с задержкой, и сколько она допустима?
  3. Что страшнее потерять: доступность системы или последнюю запись?
  4. Какая схема и какие ограничения должны проверяться самой базой?

Если списание денег и изменение остатка должны произойти вместе, это требование важнее моды на NoSQL. Если поисковый индекс можно перестроить из основной базы, его отставание в секунды обычно допустимо.

4. Подставить числа

Оцените объем данных, записей в секунду, чтений в секунду, срок хранения, допустимую задержку и рост за год. Слова «много» и «быстро» не помогают выбрать модель.

Например, сто заказов в секунду и отчеты за неделю - не повод сразу строить кластер Cassandra. Аналитика по десяти событиям на заказ за пять лет - уже причина отделить историю от операционной базы.

5. Сначала проверить существующую базу

PostgreSQL часто закрывает больше задач, чем кажется: jsonb для изменчивых атрибутов, полнотекстовый поиск и pg_trgm для каталога, рекурсивные запросы для иерархий, партиционирование для больших таблиц. Это не призыв натягивать одну базу на все, а способ не покупать распределенную сложность раньше времени.

Отдельное хранилище появляется после измеренного ограничения, а не после фразы «вдруг вырастем».

6. Посчитать цену второй базы

Вторая база - это еще и конвейер данных, отставание копии, сверка, резервное восстановление, мониторинг и новые навыки команды. Сравнивайте не стоимость лицензий, а полный вариант: железо, облачные услуги, часы эксплуатации и риск расхождения данных.

Если задачу можно решить индексом или настройкой существующей базы, второе хранилище обычно дороже.

Пример: маркетплейс

У магазина есть заказы, каталог, поиск, рекомендации, изображения и аналитика. Одна база на все необязательна, но источник истины должен быть понятен.

  • Заказы, покупатели, остатки и платежи - PostgreSQL.
  • Изменчивые атрибуты товаров - сначала jsonb, отдельная MongoDB только при доказанной необходимости.
  • Кэш карточек и временные счетчики - Redis.
  • Поиск по названию и описанию - сначала PostgreSQL FTS, затем Elasticsearch при нехватке релевантности или масштаба.
  • Изображения и видео - S3, в PostgreSQL только метаданные и ссылки.
  • История событий и тяжелые отчеты - ClickHouse с отдельной доставкой данных.
  • Рекомендации через цепочки связей - Neo4j, если графовые обходы действительно нужны.

Cassandra появляется здесь только при очень большом и предсказуемом потоке событий, когда операционная база уже не справляется с записью.

Признаки ошибочного выбора

  • Базу выбрали до списка запросов.
  • Новую технологию взяли, потому что она популярна.
  • Для обычного CRUD сразу завели несколько хранилищ.
  • Основные деньги и заказы записывают только в кэш или поисковый индекс.
  • Вторую базу добавили, но не решили, как синхронизировать и восстанавливать данные.
  • Графовую или аналитическую базу используют как универсальную.

Что почитать дальше

Коротко

  • Выбор начинается с запросов, гарантий и чисел, а не с названия базы.
  • PostgreSQL - разумная основа большинства приложений, остальные хранилища добавляют под специализированную нагрузку.
  • Кэш, поисковый индекс и аналитическая копия не заменяют источник истины.
  • Вторая база оправдана измеренным ограничением и готовностью поддерживать синхронизацию данных.