Реляционные базы данных: SQL, ACID и всё, что влияет на производительность
Реляционные базы данных — одна из тех технологий, которые кажутся «базой из базы», но именно на них чаще всего ломается продакшн. Почти любой разработчик пишет SQL-запросы, но далеко не каждый понимает, как именно база исполняет эти запросы, почему иногда всё работает быстро, а иногда внезапно медленно, и что вообще стоит за словами вроде ACID или нормализация.
Разобраться в этом полезно не только backend-разработчикам. Любой, кто работает с данными, от фронтенда до аналитики, выигрывает, когда понимает, как устроена реляционная модель.
Начнём с самого фундамента.
Что вообще значит «реляционная» база
Реляционная модель — это способ хранения данных в виде таблиц, связанных между собой через ключи. Каждая таблица — это сущность (например, пользователи), а строки — её экземпляры. Связи между таблицами задаются через внешние ключи. На практике это выглядит так:
users - id - name
orders - id - user_id - amount
user_id в таблице orders ссылается на users.id. Это и есть реляционная связь.
Важно: реляционная модель — это не просто таблицы, а строгая математическая модель. И именно из неё вытекают SQL, нормальные формы и всё остальное.
ANSI SQL: общий язык, но с акцентами
SQL — это стандартный язык работы с реляционными базами. ANSI SQL — попытка сделать единый стандарт, чтобы один и тот же запрос работал в разных СУБД.
Простой пример:
Он будет работать почти везде: PostgreSQL, MySQL, SQLite. Но на практике каждая СУБД добавляет свои особенности:
• PostgreSQL: мощная работа с JSON, оконные функции • MySQL: упрощённые конструкции, но исторически слабее с транзакциями (в старых версиях) • SQLite: лёгкость и встраиваемость
Поэтому важно понимать: SQL — один, но диалекты разные. Если вы пишете сложную бизнес-логику на уровне базы, вы привязываетесь к конкретной СУБД.
ACID: гарантия того, что база не «сломается»
ACID — это четыре свойства, которые делают транзакции надёжными:
• Atomicity (атомарность): всё или ничего • Consistency (согласованность): данные всегда валидны • Isolation (изолированность): транзакции не мешают друг другу • Durability (надёжность): после коммита данные не исчезнут
На практике ACID — это не абстракция, а вполне конкретные гарантии, которые спасают от трудноуловимых багов. Например, при работе с платежами или балансами пользователей нарушение атомарности или согласованности почти гарантированно приведёт к некорректным данным.
Транзакции: когда «либо всё, либо ничего»
Транзакция — это группа операций, которая должна выполниться целиком или не выполниться вообще.
Классический пример — перевод денег:
Если что-то пошло не так — откат:
Без транзакций вы рискуете получить ситуацию, где деньги списались, но не зачислились.
Нормальные формы: почему «разбивать таблицы» — это не занудство
Нормализация — это способ структурировать данные так, чтобы не было дублирования и не возникало аномалий при обновлении.
Самые важные формы:
1NF (первая нормальная форма): нет массивов и повторяющихся полей
Плохо:
user: "phones = 123, 456"
Хорошо:
user_phones: - user_id - phone
2NF — убираем зависимость от части ключа 3NF — убираем транзитивные зависимости
Пример проблемы без нормализации:
orders - user_name - user_email
Если пользователь меняет email, вам нужно обновить его во всех заказах.
После нормализации структура становится явной и предсказуемой:
users - id - name - email
orders - id - user_id
Теперь данные пользователя хранятся в одном месте, а заказы лишь ссылаются на него через user_id. Это устраняет дублирование и избавляет от необходимости синхронно обновлять одни и те же данные в разных строках.
Изоляция транзакций: почему данные «ведут себя странно»
Изоляция — это то, как база ведёт себя, когда несколько транзакций выполняются одновременно. И именно здесь чаще всего возникают неочевидные баги.
Существует несколько уровней изоляции:
• Read Uncommitted: можно читать незакоммиченные данные • Read Committed: видны только подтверждённые изменения • Repeatable Read: строки не меняются в рамках транзакции • Serializable: поведение как будто транзакции выполняются по очереди
Чем выше уровень изоляции, тем меньше аномалий, но тем выше нагрузка на базу.
Простой пример:
Два пользователя одновременно покупают последний товар. Без достаточной изоляции обе транзакции могут «увидеть», что товар есть в наличии, и обе успешно его купят. Именно поэтому уровень изоляции — это всегда компромисс между корректностью и производительностью, который выбирается под конкретную задачу.
Индексы: почему один запрос работает 1 мс, а другой — 10 секунд
Индекс — это структура данных, которая ускоряет поиск.
Без индекса:
База делает полный перебор (full scan).
С индексом:
Теперь поиск идёт через структуру вроде B-дерева. Но есть нюанс: индексы ускоряют чтение, но замедляют запись (INSERT/UPDATE)
Практическая ошибка: разработчик добавляет индекс на каждое поле → база начинает тормозить при записи.
Как всё сходится в реальной системе
В реальном проекте всё взаимосвязано:
• Плохо спроектированная схема → лишние JOIN → медленные запросы • Отсутствие индексов → full scan → нагрузка на CPU • Неправильные транзакции → гонки данных • Игнорирование ACID → баги, которые сложно воспроизвести
Простой пример:
Вы делаете ленту постов:
Чтобы это работало быстро, нужен составной индекс: (user_id, created_at)
Иначе база сначала отфильтрует, потом отсортирует, что дорого.
Когда теория начинает помогать
Понимание реляционных БД даёт неожиданные бонусы:
• Вы начинаете читать execution plan и понимать, что именно делает база при выполнении запроса. Посмотреть его можно с помощью EXPLAIN или EXPLAIN ANALYZE, и вместо догадок вы видите, используются ли индексы, сколько строк перебирается и где возникают узкие места • Можете объяснить, почему API тормозит • Проектируете схемы, которые не разваливаются через полгода • Спокойно обсуждаете архитектуру с backend и DevOps
И самое важное — перестаёте «гадать» и начинаете контролировать поведение базы.
Реляционные базы данных — это не просто SQL-запросы. Это:
• Строгая модель данных • Механизмы гарантии целостности • Инструменты оптимизации
Если кратко:
• SQL — это язык • ACID — это надёжность • Нормализация — это структура • Индексы — это скорость
И всё это вместе определяет, будет ли ваша система работать стабильно или начнёт сыпаться под нагрузкой.
Хотите узнать больше? Изучите другие статьи из раздела: