На обсуждение новой системы приносят два предложения. В одном — реляционная база, потому что команда уже умеет с ней работать. В другом — документная, потому что у товаров разные характеристики и ожидается рост каталога. Оба аргумента разумны. Ни один пока не отвечает на вопрос, что компания получит за дополнительные расходы.
Начинать сравнение полезнее с работы продукта. Как ищут товары? Какие изменения нужно сохранять вместе? Что случится, если два покупателя одновременно захотят последний экземпляр? Какие отчёты понадобятся сотрудникам? На таких вопросах различия между хранилищами становятся содержательными. До этого обсуждается скорее вкус команды.
Под словом NoSQL скрываются разные решения
Документная база, хранилище «ключ — значение» и графовая база устроены для разных способов работы с данными. Сравнивать их все с SQL как один вариант мало полезно. Хранилище сессий пользователя и система поиска связей между организациями могут оказаться в одной категории NoSQL, но решать совершенно разные задачи.
Реляционная модель удобна, когда есть несколько связанных сущностей и нужны разные способы их объединять. Документная модель позволяет держать рядом сведения, которые приложение обычно читает вместе. При этом граница не абсолютна: например, PostgreSQL поддерживает JSON и его индексацию. Переменный набор характеристик товара ещё не обязывает заводить отдельную технологию.
Поэтому в сравнении должны появиться конкретные продукты, режимы работы и ограничения. Фразы «SQL не масштабируется» и «в NoSQL нет транзакций» только мешают. В частности, MongoDB поддерживает многодокументные транзакции. Важно выяснить их границы, требования и стоимость в выбранной конфигурации, а не поставить галочку напротив категории базы.
Каталог и резервирование задают разные вопросы
Предположим, продукт продаёт оборудование. Для карточки насоса нужны одни характеристики, для кабеля — другие. Хранить карточку документом может быть удобно: приложение получает вместе описание, свойства и вложенные элементы. Но покупатель затем просит отфильтровать весь каталог по напряжению, производителю и наличию. Это уже конкретные запросы, для которых нужно спроектировать данные и индексы.
Гибкая структура не освобождает от договорённостей. Если часть поставщиков передала мощность числом, часть строкой, а часть в других единицах, свободный формат прекрасно сохранит все варианты. Пользоваться ими будет сложнее. Потребуются проверка входных данных, правила преобразования и поддержка старых записей после изменения модели.
Теперь покупатель резервирует товар. Системе нужно не позволить двум конкурентным операциям продать один остаток. Выбранная база должна поддерживать подходящий механизм: атомарное условное изменение, блокировку, транзакцию или другую проверяемую защиту. Наличие транзакций само по себе не исправит ошибочную последовательность «прочитать остаток, затем отдельно уменьшить».
Если оплата проходит у внешнего провайдера, его действие не попадёт автоматически в транзакцию вашей базы. Придётся согласовать состояния оплаты и заказа, повторы и восстановление. Этот вопрос останется при любом выборе SQL или NoSQL. Его легко упустить, сравнивая только скорость записи в тестовой таблице.
Удобно читать вместе — не всегда удобно менять вместе
Для быстрого чтения данные иногда дублируют. Например, название и адрес поставщика сохраняют рядом с каждой товарной карточкой. Тогда изменение адреса затрагивает несколько копий. Нужно решить, требуется ли немедленное обновление всех записей, допустимо ли отставание и как обнаружить пропущенную копию.
Бывают и намеренные исторические копии: адрес доставки в оформленном заказе не должен измениться вслед за адресом в профиле клиента. Это уже смысл данных, а не предпочтение одной технологии. Без такого различия можно потратить много сил на синхронизацию того, что синхронизировать вообще не следовало.
Новые запросы тоже имеют цену. Сегодня нужен быстрый поиск карточки по идентификатору, завтра — список клиентов, покупавших оборудование определённого поставщика и обращавшихся по гарантии. Проверять такую задачу надо на выбранной модели. Возможно, она решается обычным запросом. Возможно, потребуются отдельное представление, индекс или аналитическая система.
Второе хранилище придётся обслуживать постоянно
Сочетание технологий бывает оправданным: например, одна система хранит подтверждённые операции, другая обслуживает специализированный поиск. Но появляются доставка изменений, контроль отставания, резервное копирование, обновления и люди, способные восстановить оба компонента. Эти расходы не исчезают после успешного запуска.
Управляемый сервис снимает часть работы с инфраструктурой, но не выбирает модель данных и не проверяет восстановление приложения за команду. В смету стоит включить хранение копий и индексов, передачу данных, поддержку, подготовку специалистов и перенос информации при смене решения. Дешёвая запись может соседствовать с дорогим чтением или дорогим выходом.
Знакомая технология здесь получает обоснованное преимущество. Если она выполняет требования и команда умеет её эксплуатировать, отказ от новой базы экономит реальную работу. Это не довод против эксперимента. Это исходная точка, относительно которой эксперимент должен показать пользу.
Что должно остаться после сравнения
Для проверки достаточно ограниченного прототипа с рабочими сценариями, а не двух полноценных реализаций продукта. В него стоит включить частый запрос, тяжёлую выборку, конкурентное изменение и задачу, которой пока нет в интерфейсе, но которая уже обсуждается бизнесом. Данные должны отражать перекосы: популярный товар, крупного клиента, длинную историю. Равномерный искусственный набор многое прощает.
Полезно заранее установить, какое время ответа и какая потеря доступности допустимы. Затем сравнить результат, ресурсы и объём кода, который понадобился вокруг базы. Отдельно выполнить восстановление из резервной копии и небольшое изменение схемы. Это покажет расходы, которых не видно в демонстрации поиска.
Результат выбора можно уместить в короткую запись: какие операции защищаем, почему подходит эта модель, от чего отказываемся и при каком наблюдаемом ограничении вернёмся к решению. Так у руководителя останется основание для бюджета, а у команды — понятные условия пересмотра, а не обещание никогда больше не менять базу.