SQL

БЛОК 10. Сравнение СУБД — 25. PostgreSQL vs MySQL — архитектура (облегчённая)

📚 24 вопросовПройти тест →
Лекция

БЛОК 10. Сравнение СУБД — 25. PostgreSQL vs MySQL — архитектура (облегчённая)

SQL

25. PostgreSQL vs MySQL — архитектура (облегчённая)

🧭 Введение: зачем junior понимать архитектуру СУБД

Когда мы сравниваем PostgreSQL и MySQL, чаще всего обсуждают синтаксис запросов.
Но в реальной работе поведение системы определяется ещё и архитектурой: как СУБД хранит версии строк, какие есть движки хранения, как устроены автоинкрементные ключи и работа с JSON.
В этой теме разбираем архитектуру на прикладном уровне, без перегруза:
  • философия PostgreSQL и MySQL;
  • MVCC простыми словами;
  • storage engines и роль InnoDB;
  • SERIAL vs AUTO_INCREMENT;
  • JSON vs JSONB.
💡 Совет: Не учите архитектуру «ради теории». Привязывайте каждый пункт к вопросу: как это влияет на код и схему.
Вывод: Даже облегчённое понимание архитектуры резко снижает количество ошибок при проектировании и миграциях.

⚠️ Проблема -> решение

Типичная проблема:
  1. команда пишет SQL «по памяти», но не учитывает архитектурные различия СУБД;
  2. решения, которые хорошо работают в PostgreSQL, переносят в MySQL без адаптации (и наоборот);
  3. на проде появляются неожиданные эффекты: блокировки, разная работа JSON, разный подход к ключам.
Решение:
  1. знать базовую карту архитектурных отличий;
  2. при проектировании сразу выбирать диалектный паттерн (id, JSON, движок хранения);
  3. фиксировать в документации команды, почему выбран именно такой путь.
🟢 Если совсем просто: Один и тот же SQL может вести себя по-разному, потому что «под капотом» PostgreSQL и MySQL устроены не одинаково.
🎯 Как понять, что этап прошёл успешно: Вы можете объяснить ключевые отличия без сложных терминов и сразу показать прикладной выбор для проекта.

🛠️ Чем помогает и как работает

Архитектурное понимание нужно, чтобы писать предсказуемый код и не лечить проблемы уже после релиза.
Оно особенно важно в задачах миграции, multi-DB окружениях и системах с высокой нагрузкой на чтение/запись.
🟢 Если совсем просто: Вы заранее понимаете, какие решения «нативны» для PostgreSQL, а какие для MySQL.
🎯 Как понять, что этап прошёл успешно: В архитектурных обсуждениях вы аргументируете решения через поведение СУБД, а не через «мне так привычнее».
Чем помогает:
  • уменьшает риск неверного выбора типа данных;
  • ускоряет code review схемы;
  • делает миграции более предсказуемыми;
  • помогает корректно выбирать индексы и формат хранения данных.
Как это работает:
  • Шаг 1: фиксируем бизнес-задачу (транзакционность, тип нагрузки, интеграции);
  • Шаг 2: выбираем архитектурные решения под целевую СУБД;
  • Шаг 3: закладываем ограничения и формат данных в схему;
  • Шаг 4: проверяем на реальных сценариях чтения/записи.
Вывод: Архитектура СУБД — это не отдельная «академическая тема», а часть ежедневного инженерного выбора.

📚 Ключевые термины (простыми словами)

Перед практикой синхронизируем словарь.
🟢 Если совсем просто: Одинаковые термины в PostgreSQL и MySQL иногда означают разные механики.
🎯 Как понять, что этап прошёл успешно: Вы уверенно объясняете эти слова на рабочем языке команды, без перегруза формулами.
  • Философия СУБД — общий подход продукта: как база развивает возможности и какие компромиссы делает.
  • MVCC (Multi-Version Concurrency Control) — хранение версий строк, чтобы чтение и запись меньше блокировали друг друга.
  • Storage Engine — подсистема хранения/транзакций в MySQL (например, InnoDB).
  • SERIAL — удобная обёртка в PostgreSQL для автоинкрементного числового id.
  • AUTO_INCREMENT — автоувеличение числового id в MySQL.
  • JSONB — бинарный формат JSON в PostgreSQL с лучшей поддержкой индексов и операций.
Вывод: Термины дают общую инженерную рамку: как мыслить про поведение СУБД, а не только про синтаксис.

🧩 1. Философия PostgreSQL и MySQL

PostgreSQL обычно воспринимают как систему с акцентом на расширяемость, строгие возможности SQL и богатый функционал «из коробки».
MySQL часто выбирают за простоту старта, широкую распространённость и практичный фокус на веб-нагрузках.
🟢 Если совсем просто: PostgreSQL чаще про «богатый toolkit», MySQL — про «простой и понятный путь для типовых задач».
🎯 Как понять, что этап прошёл успешно: Вы не спорите «что лучше», а связываете выбор с конкретной задачей проекта.
Назначение: Понять, почему в двух СУБД разные «дефолтные» решения считаются нормой.
Простыми словами: Философия влияет на то, какие паттерны команда использует чаще всего.
Для новичка: Нельзя переносить архитектурные привычки 1-в-1 без проверки на целевой СУБД.
Аналогия: Две машины могут ехать одинаково быстро, но одна рассчитана на бездорожье, другая на город.
Пример:
-- PostgreSQL: расширенные возможности в одном запросеSELECT  u.id,  jsonb_build_object('email', u.email) AS profile_jsonFROM users u;
-- MySQL: похожая задача, но через свой набор функцийSELECT  u.id,  JSON_OBJECT('email', u.email) AS profile_jsonFROM users u;
🔎 Как это происходит на практике:
  • Контекст: команда проектирует новый сервис с аналитическими отчётами и API.
  • Действия: сравнивают не только скорость CRUD, но и встроенные возможности платформы.
  • Результат: архитектурные решения становятся осознанными, а не «по привычке».
Характеристики:
  • философия влияет на формат схем и запросов;
  • переносимость достигается через адаптацию, а не копипаст;
  • цена ошибки — рост техдолга при миграциях.
Когда использовать: На этапе выбора стека и при ревью архитектурных решений.
Вывод: Понимание философии СУБД помогает выбирать корректные компромиссы ещё до написания большого объёма SQL.

🧪 2. MVCC на простом уровне

MVCC — ключевая идея для конкурентной работы: чтения не должны останавливать записи, а записи не должны парализовать чтения.
И PostgreSQL, и InnoDB в MySQL используют версионный подход, но детали реализации отличаются.
🟢 Если совсем просто: MVCC = база хранит версии строк, чтобы параллельные запросы меньше мешали друг другу.
🎯 Как понять, что этап прошёл успешно: Вы можете объяснить, почему при высокой нагрузке важны не только индексы, но и модель конкурентности.
Назначение: Снизить взаимные блокировки между читателями и писателями.
Простыми словами: Пока одна транзакция меняет строку, другая может читать «подходящую» версию.
Для новичка: MVCC не отменяет блокировки полностью, но сильно уменьшает количество конфликтов в типовых сценариях.
Аналогия: Это как читать копию документа, пока редактор вносит изменения в новую версию.
Пример:
BEGIN;UPDATE accountsSET balance = balance - 100WHERE id = 10;-- COMMIT позже
-- Транзакция B в это же время читает данныеSELECT  a.id,  a.balanceFROM accounts aWHERE a.id = 10;
🔎 Как это происходит на практике:
  • Контекст: API с частыми чтениями профилей и периодическими обновлениями.
  • Действия: проектируют запросы и транзакции с учётом MVCC-модели.
  • Результат: меньше «зависаний» из-за лишних блокировок.
Характеристики:
  • подход версионности есть в обеих СУБД;
  • поведение зависит от уровня изоляции и типа запроса;
  • архитектурно это база для стабильной OLTP-нагрузки.
Когда использовать: Всегда, когда в системе много параллельных чтений и записей.
Вывод: MVCC — базовый must-know для понимания «почему база иногда ведёт себя не так, как ожидают без учёта конкурентности».

🏗️ 3. Storage engines в MySQL и роль InnoDB

В PostgreSQL архитектура хранения более монолитная: нет ежедневного выбора «движка» для каждой таблицы.
В MySQL historically важная тема — storage engines, и в современных OLTP-проектах почти всегда берут InnoDB.
🟢 Если совсем просто: Для MySQL по умолчанию думайте про InnoDB, если нужен нормальный транзакционный OLTP.
🎯 Как понять, что этап прошёл успешно: Вы чётко знаете, почему в проекте выбран InnoDB и какие риски у несоответствующего engine.
Назначение: Выбрать корректный механизм хранения и транзакционного поведения в MySQL.
Простыми словами: Engine определяет, как таблица хранится и как работает с транзакциями/блокировками.
Для новичка: Если без особых причин выбран не InnoDB, это повод проверить архитектурное решение.
Аналогия: Это как выбрать тип коробки передач для машины: внешне поездка та же, но поведение под нагрузкой разное.
Пример:
-- MySQL: явно фиксируем engine при создании таблицыCREATE TABLE orders (  id BIGINT AUTO_INCREMENT PRIMARY KEY,  user_id BIGINT NOT NULL,  status VARCHAR(32) NOT NULL) ENGINE=InnoDB;
-- Проверка движка таблицы в MySQLSHOW TABLE STATUS LIKE 'orders';
🔎 Как это происходит на практике:
  • Контекст: у команды проблемы с целостностью/блокировками после legacy-настроек.
  • Действия: инвентаризируют таблицы и приводят engine к InnoDB.
  • Результат: поведение транзакций становится предсказуемым.
Характеристики:
  • InnoDB — де-факто стандарт для транзакционных нагрузок в MySQL;
  • выбор engine влияет на возможности и ограничения;
  • при миграции legacy-проектов нужно отдельно проверять эту часть.
Когда использовать: При проектировании MySQL-схемы и аудите существующих таблиц.
Вывод: Storage engine в MySQL — это архитектурный выбор, а не «деталь, которую можно игнорировать».

🔢 4. SERIAL vs AUTO_INCREMENT

И PostgreSQL, и MySQL умеют автоинкрементные id, но синтаксис и механика отличаются.
В PostgreSQL SERIAL — исторический сахар над sequence, а в MySQL используется AUTO_INCREMENT.
🟢 Если совсем просто: Смысл один: числовой id растёт автоматически, но оформляется в разных диалектах по-разному.
🎯 Как понять, что этап прошёл успешно: Вы уверенно переводите схему id между PostgreSQL и MySQL без потери семантики.
Назначение: Обеспечить простой и стабильный генератор первичных ключей.
Простыми словами: База сама выдаёт следующий id при вставке.
Для новичка: В PostgreSQL в новых схемах часто выбирают GENERATED ... AS IDENTITY, но SERIAL всё ещё широко встречается.
Аналогия: Это как электронная очередь: номер выдаётся автоматически, оператор его вручную не назначает.
Пример:
-- PostgreSQL: классический вариантCREATE TABLE users (  id SERIAL PRIMARY KEY,  email TEXT NOT NULL UNIQUE);
-- MySQL: автоинкремент на колонкеCREATE TABLE users (  id BIGINT AUTO_INCREMENT PRIMARY KEY,  email VARCHAR(255) NOT NULL UNIQUE);
🔎 Как это происходит на практике:
  • Контекст: миграция схемы пользователей между двумя СУБД.
  • Действия: адаптируют DDL под нативный стиль id-генерации.
  • Результат: CRUD работает предсказуемо, без ручной генерации ключей.
Характеристики:
  • идея автоинкремента одинакова;
  • синтаксис и детали DDL различаются;
  • важно учитывать стратегию id в API и интеграциях.
Когда использовать: В большинстве внутренних OLTP-таблиц.
Вывод: SERIAL и AUTO_INCREMENT решают одну задачу, но требуют диалектно корректного оформления.

🧾 5. JSON vs JSONB

В MySQL есть тип JSON, в PostgreSQL есть JSON и JSONB.
На практике в PostgreSQL для рабочих нагрузок часто выбирают JSONB, потому что он удобнее для индексации и поиска.
🟢 Если совсем просто: Если по JSON нужно часто фильтровать, в PostgreSQL обычно берут JSONB.
🎯 Как понять, что этап прошёл успешно: Вы можете обосновать, когда JSON оставляем как «payload», а когда поля выносим в отдельные колонки.
Назначение: Хранить полуструктурированные данные без мгновенного взрыва числа колонок.
Простыми словами: JSON удобен для гибких атрибутов, но не должен заменять нормальную реляционную модель.
Для новичка: Ключевые связи (user_id, order_id, статусы домена) не прячем в JSON-полях.
Аналогия: JSON — это «дополнительная папка с вложениями», а не место для основного договора.
Пример:
-- PostgreSQL: JSONB + индекс под фильтрациюCREATE TABLE events (  id BIGSERIAL PRIMARY KEY,  payload JSONB NOT NULL); CREATE INDEX idx_events_payload_ginON events USING GIN (payload);
-- MySQL: JSON-колонка с выборкой через путьSELECT  e.id,  JSON_EXTRACT(e.payload, '$.source') AS sourceFROM events e;
🔎 Как это происходит на практике:
  • Контекст: система принимает внешние события с неполной схемой.
  • Действия: метаданные кладут в JSON/JSONB, ключевые поля оставляют реляционными.
  • Результат: схема остаётся управляемой, а гибкость не теряется.
Характеристики:
  • JSON удобен для гибких атрибутов;
  • JSONB в PostgreSQL обычно лучше для частых фильтров;
  • при активной фильтрации по одному полю часто выгодно вынести его в отдельную колонку.
Когда использовать: Для event payload, metadata и умеренно динамичных атрибутов.
Вывод: JSON-поля полезны как дополнение к модели, но не как замена нормальной структуре таблиц.

🧪 6. Краткое сравнение по теме

КейсPostgreSQLMySQL
Общая философияБогатый SQL toolkit, расширяемостьПростота старта, прагматичный web-фокус
КонкурентностьMVCC (свои детали реализации)MVCC в InnoDB
ХранениеЕдиная архитектура движкаStorage engines, в OLTP обычно InnoDB
АвтоинкрементSERIAL / IDENTITYAUTO_INCREMENT
JSONJSON, JSONB (часто выбирают JSONB)JSON
Вывод: Различия архитектуры не отменяют переносимость, но требуют осознанных диалектных решений.

🧠 Must-Know (запомнить)

  • Архитектура СУБД влияет на поведение запросов не меньше, чем синтаксис.
  • MVCC в обеих СУБД важен для конкурентной OLTP-нагрузки.
  • В MySQL для транзакционных таблиц ориентир — InnoDB.
  • SERIAL и AUTO_INCREMENT решают одну задачу, но оформляются по-разному.
  • В PostgreSQL SERIAL исторический сахар; в новых схемах часто используют IDENTITY.
  • В PostgreSQL JSONB обычно практичнее для фильтрации и индексов.
  • Ключевые реляционные связи не должны жить внутри JSON.
  • Архитектурные решения нужно документировать в команде.
Вывод: Junior-уровень по архитектуре = понимать базовые механики и выбирать безопасные дефолты.

❌ Частые мифы

Миф: PostgreSQL и MySQL отличаются только синтаксисом. ✅ Как правильно: Архитектурные решения (MVCC, engine, JSON-модель) тоже сильно влияют на поведение системы. 📎 Почему это важно: Иначе миграции и ревью схемы превращаются в серию неожиданных багов.
Миф: MVCC полностью убирает блокировки. ✅ Как правильно: MVCC снижает конфликты, но блокировки и конфликты транзакций всё равно возможны. 📎 Почему это важно: Неправильные ожидания ведут к неверному проектированию транзакций.
Миф: В MySQL engine не имеет значения. ✅ Как правильно: Для OLTP engine критичен; в большинстве случаев нужен InnoDB. 📎 Почему это важно: Неверный engine бьёт по транзакционности и предсказуемости.
Миф: JSON можно использовать вместо нормализации везде. ✅ Как правильно: JSON полезен для гибких полей, но ключевые данные и связи храним реляционно. 📎 Почему это важно: Иначе ломаются индексы, целостность и поддерживаемость модели.

🎤 Часто спрашивают на собеседованиях

Вопрос: В чём философская разница PostgreSQL и MySQL на прикладном уровне? ✅ Ответ: PostgreSQL чаще выбирают за богатый SQL/расширяемость, MySQL — за практичную простоту и массовый production-опыт в веб-системах.
Вопрос: Что такое MVCC простыми словами? ✅ Ответ: Это модель, где СУБД работает с версиями строк, чтобы чтения и записи меньше блокировали друг друга.
Вопрос: Зачем в MySQL вообще знать про storage engines? ✅ Ответ: Потому что engine определяет важные свойства таблиц; для OLTP обычно нужен InnoDB.
Вопрос: Чем отличается SERIAL от AUTO_INCREMENT? ✅ Ответ: Оба дают автоинкрементный id, но SERIAL — PostgreSQL-обёртка над sequence, а AUTO_INCREMENT — механизм MySQL.
Вопрос: Почему в PostgreSQL часто выбирают JSONB? ✅ Ответ: Обычно из-за удобной индексации и более практичной работы с частыми JSON-фильтрами.
Вопрос: Можно ли хранить внешние ключи в JSON? ✅ Ответ: Технически можно, но это плохая практика: теряется явная реляционная целостность и усложняется поддержка.
Вопрос: Что важнее при выборе между PostgreSQL и MySQL: синтаксис или архитектура? ✅ Ответ: Важны оба слоя, но архитектура задаёт долгосрочное поведение системы под нагрузкой.

🚨 Типичные ошибки

  • Считать, что перенос SQL между PostgreSQL и MySQL — это только замена синтаксиса.
  • Игнорировать MVCC и проектировать транзакции без учёта конкурентности.
  • Не проверять engine таблиц в MySQL.
  • Путать SERIAL и AUTO_INCREMENT при миграциях схемы.
  • Складывать ключевые доменные поля в JSON вместо нормальных колонок.
  • Не документировать архитектурные решения команды.
Вывод: Большинство проблем в теме связаны не со «сложностью SQL», а с неявными архитектурными допущениями.

✅ Best Practices

  • Для новой команды фиксируйте короткую архитектурную памятку: MVCC, engine, id-стратегия, JSON-правила.
  • В MySQL-проектах явно проверяйте, что транзакционные таблицы работают на InnoDB.
  • В PostgreSQL для новых схем рассматривайте IDENTITY как современную альтернативу SERIAL.
  • Для JSON-полей заранее определяйте: это payload или рабочий фильтр с индексом.
  • Ключевые связи и бизнес-инварианты храните в реляционных колонках.
  • Архитектурные решения проверяйте на реальных сценариях чтения/записи, а не только на синтаксисе DDL.
Вывод: Правильные дефолты в архитектуре дают больше эффекта, чем точечные оптимизации в конце проекта.

🧾 Заключение

Эта тема закрывает базовый архитектурный минимум для сравнения PostgreSQL и MySQL без перегруза.
Если вы понимаете философию платформ, роль MVCC, InnoDB, отличия автоинкремента и выбор JSON-формата, вы уже принимаете более зрелые инженерные решения.
Вывод: Архитектурная грамотность уровня junior+ — это умение выбрать безопасный дефолт и объяснить его команде.
🎯

Проверьте знания

Закрепите материал — пройдите тест по теме «БЛОК 10. Сравнение СУБД — 25. PostgreSQL vs MySQL — архитектура (облегчённая)»

Пройти тест →