PostgreSQL vs MySQL: сравнение для аналитика

PostgreSQL и MySQL — две главные open-source реляционные СУБД, и почти в каждой вакансии аналитика встречается одна из них. С точки зрения аналитики разница ощутима: PostgreSQL исторически богаче на аналитические возможности — оконные функции появились в нём намного раньше, есть развитый JSON/JSONB, массивы, CTE, `FILTER`, богатая система типов и расширения вроде PostGIS. MySQL долго был проще и быстрее на простых read-запросах, а полноценные оконные функции и CTE получил только в версии 8.0 (2018). Для собеседования важно понимать поведение по умолчанию: регистрозависимость строк, деление целых чисел, обработку `NULL` в уникальных индексах, разницу в диалекте (`LIMIT` vs `FETCH`, `::` cast, `RETURNING`). Эти нюансы любят спрашивать. Потренировать оба диалекта на реальных задачах можно в [SQL-тренажёре](/sql-sandbox) — там доступны и PostgreSQL 16, и SQLite-режим.

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

Параметр Postgresql Mysql
Оконные функцииЕсть с версии 8.4 (2009), полный набор: RANK, LEAD/LAG, FILTER, рамки RANGE/ROWSПоявились только в MySQL 8.0 (2018); до этого эмулировались через переменные @
CTE и рекурсияWITH и WITH RECURSIVE с версии 8.4; поддержка материализацииCTE и рекурсивные CTE только с 8.0
Работа с JSONТипы json и jsonb (бинарный, индексируемый через GIN), богатый набор операторовТип JSON есть с 5.7, но без бинарного индексируемого варианта и с более скромным API
Система типовМассивы, ENUM, диапазоны, гео (PostGIS), UUID, hstore, пользовательские типыБазовый набор + ENUM и SET; массивов и диапазонов нет
РасширяемостьРасширения (CREATE EXTENSION), свои типы, операторы, языки (PL/pgSQL, PL/Python)Плагины хранилищ и UDF, но экосистема расширений заметно уже
Регистр строк по умолчаниюСравнение строк регистрозависимое (case-sensitive)По умолчанию collation ci — сравнение регистронезависимое
Деление целых5/2 = 2 (целочисленное); для дроби нужен явный cast5/2 = 2.5 (возвращает дробь по умолчанию)
Транзакции и DDLТранзакционный DDL: ALTER/CREATE можно откатить в транзакцииDDL обычно вызывает неявный commit; откатить нельзя
Профиль производительностиСильнее на сложных JOIN, аналитике, параллельных планах и конкурентной записи (MVCC)Традиционно быстр на простых чтениях и высокой нагрузке простых запросов
Диалект и удобствоRETURNING, DISTINCT ON, generate_series, ::cast, богатые агрегатыПроще синтаксис, но меньше аналитических конструкций; есть свои функции дат
Экосистема и стоимостьПолностью open-source (лицензия PostgreSQL), нет коммерческого владельцаOpen-source (GPL) под управлением Oracle; есть форк MariaDB

Когда что использовать

Когда Postgresql

  • Выбирайте PostgreSQL, если работаете с аналитикой: сложные JOIN, оконные функции, CTE, работа с JSONB, массивами и геоданными
  • Это выбор по умолчанию для дата-команд, аналитических витрин и продуктовой аналитики
  • Также он удобнее, когда нужна строгая типизация, транзакционный DDL и расширяемость

Когда Mysql

  • Выбирайте MySQL, если у вас типичный веб-бэкенд с большим числом простых read-запросов, унаследованная кодовая база или требования инфраструктуры (например, широкая поддержка в хостинге и репликации для веба)
  • Для нового аналитического проекта в 2026 году, впрочем, PostgreSQL чаще предпочтительнее, а MySQL 8.0 уже закрыл большинство исторических пробелов по SQL

FAQ

Чем оконные функции в PostgreSQL исторически отличались от MySQL?

PostgreSQL поддерживает оконные функции с версии 8.4 (2009), а MySQL получил их только в 8.0 (2018). До этого в MySQL их эмулировали через пользовательские переменные (@row := ...), что было хрупко и плохо читалось. Поэтому в старых MySQL-проектах RANK, ROW_NUMBER и LAG/LEAD часто отсутствуют — это частый вопрос на собеседовании.

Почему 5/2 даёт разный результат в PostgreSQL и MySQL?

В PostgreSQL деление двух целых чисел возвращает целое: 5/2 = 2, и для дробного результата нужен явный cast, например 5::numeric/2. В MySQL 5/2 по умолчанию вернёт 2.5. Об этом легко споткнуться при расчёте конверсий и долей — всегда приводите тип явно.

В чём разница между JSON и JSONB в PostgreSQL и что есть в MySQL?

В PostgreSQL json хранит текст как есть, а jsonb — бинарное представление, которое быстрее читается, поддерживает индексы GIN и операторы поиска. В MySQL есть тип JSON с 5.7, но без разделения на текст/бинарь и с более скромным набором функций. Для аналитики полуструктурированных данных PostgreSQL с jsonb обычно удобнее.

Что важнее знать аналитику: PostgreSQL или MySQL?

Знать нужно сам SQL, а не конкретную СУБД — базовые SELECT, JOIN, GROUP BY, оконные функции переносимы. Но PostgreSQL чаще встречается в дата-командах и богаче на аналитические конструкции, поэтому его стоит освоить в первую очередь и помнить о диалектных различиях. Потренироваться на реальных задачах и вопросах с собеседований можно в /sql-sandbox и в разделе /interviews.

Источники

Практика по теме → Полный гайд в блоге →

Другие сравнения

Postgresql vs Clickhouse · Pandas vs Polars · Tableau vs Powerbi Datalens Superset · SQL vs Pandas · Dbt vs Airflow · Redshift vs Bigquery vs Snowflake · Airflow vs Dagster vs Prefect · Greenplum vs Clickhouse · Excel vs SQL · Sqlite vs Postgresql · Spark vs Pandas · Power Bi vs Excel · Clickhouse vs Druid · Python vs R