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











