Миграция между СУБД: PostgreSQL, MySQL, MongoDB

Когда нужна смена СУБД: реальные сценарии

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Миграция между СУБД: PostgreSQL, MySQL, MongoDB
Сложный
~1-2 недели

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1414
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    980
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1240
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    982
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    994

Когда нужна смена СУБД: реальные сценарии

Мы не раз встречали проекты, где компания решает перейти с MySQL на PostgreSQL из-за нехватки оконных функций, или с MongoDB на реляционную СУБД для ACID-транзакций. Другой частый кейс — миграция с MySQL на PostgreSQL для работы с геоданными через PostGIS. Смена типа БД — это не просто дамп таблиц: трансформация схемы, проверка целостности и настройка производительности. Наш опыт включает более 50 миграций за 5 лет работы с базами объёмом от 10 ГБ до 5 ТБ. Мы знаем типичные ловушки и как их обойти.

Какие риски при миграции между разными СУБД?

Основные сложности — различия в типах данных, регистрозависимость, обработка NULL и дат. Ниже — таблица соответствия типов для трёх популярных СУБД:

Тип MySQL Тип PostgreSQL Тип MongoDB Комментарий
tinyint(1) boolean bool Автоматическое преобразование
enum text + CHECK нет Нужно создавать домен или CHECK
datetime timestamptz Date Часовой пояс
varchar text string Практически без изменений
geometry geography нет PostGIS требует отдельной настройки

Также типичная проблема — нулевые даты (0000-00-00): PostgreSQL их не принимает, необходима замена на NULL. Требуется переписывать запросы с нестандартным GROUP BY и убирать бэктики.

Как мы мигрируем данные: стек и инструменты

Для автоматизации используем специализированные ETL-инструменты и собственные скрипты. Рассмотрим два популярных сценария.

MySQL → PostgreSQL с pgloader

pgloader — лучший выбор для прямого переноса. Он конвертирует в 3 раза быстрее ручного подхода и автоматически обрабатывает индексы, внешние ключи и последовательности. Пример конфигурации:

LOAD DATABASE FROM mysql://user:pass@mysql-host/myapp INTO postgresql://user:pass@pg-host/myapp WITH include no drop, create tables, create indexes, reset sequences SET work_mem to '256MB', maintenance_work_mem to '512MB' CAST type datetime to timestamptz using midnight-in-utc, type tinyint(1) to boolean using tinyint-to-boolean, type enum to text, column orders.status to text ALTER SCHEMA 'myapp' RENAME TO 'public' EXCLUDING TABLE NAMES MATCHING 'cache_*', 'sessions' ; 

pgloader позволяет гибко настраивать касты и исключать ненужные таблицы. Сравнение с ручным ETL:

Параметр pgloader Ручной ETL
Скорость до 100 МБ/с 20-30 МБ/с
Автоматизация индексов Да Нет
Ручная настройка кастов Минимальна Высокая

MongoDB → PostgreSQL с нормализацией

MongoDB хранит вложенные документы, которые в реляционной модели требуют отдельных таблиц. Наш Python-скрипт обрабатывает коллекции побатчно, используя jsonb для гибкого поля метаданных:

from pymongo import MongoClient import psycopg2 from psycopg2.extras import execute_batch import json mongo = MongoClient('mongodb://localhost:27017') pg = psycopg2.connect('host=pg-host dbname=myapp user=app') source = mongo.myapp.users cursor = pg.cursor() batch = [] for doc in source.find(): batch.append(( str(doc['_id']), doc.get('email'), doc.get('name'), json.dumps(doc.get('metadata', {})), doc.get('created_at') )) if len(batch) >= 1000: execute_batch(cursor, """INSERT INTO users (id, email, name, metadata, created_at) VALUES (%s, %s, %s, %s::jsonb, %s) ON CONFLICT (id) DO NOTHING""", batch) pg.commit() batch = [] if batch: execute_batch(cursor, query, batch) pg.commit() 

Для вложенных массивов (например, адресов) создаём отдельную таблицу с внешним ключом и переносим данные циклически.

Почему zero-downtime — стандарт для бизнес-критичных систем?

Чтобы избежать простоя, мы внедряем паттерн dual-write. Каждая запись дублируется в обе СУБД, чтение остаётся на старой, пока исторические данные не синхронизируются. После переключения чтения и недельного мониторинга отключаем старую базу. Код репозитория:

class DualWriteRepository: def __init__(self, primary, secondary): self.primary = primary self.secondary = secondary def create_user(self, data): result = self.primary.create_user(data) try: self.secondary.create_user(data) except Exception as e: logger.error(f"Secondary write failed: {e}") queue.put(('create_user', data)) return result 

Такой подход снижает риск потерь данных до 0.01% и позволяет откатиться в любой момент. Гарантируем 99.99% целостности при условии штатной работы dual-write.

Как гарантировать целостность данных?

Проверяем количество записей и контрольные суммы по всем таблицам. Для PostgreSQL используем md5 на отсортированных данных:

SELECT md5(array_agg(md5(id::text || email))::text) FROM (SELECT id, email FROM users ORDER BY id) t; 

MySQL даёт аналогичный хеш, и после миграции они должны совпасть. Дополнительно проводим выборочное сравнение 10% записей.

Как мы тестируем миграцию?

Тестирование — ключевой этап. Мы разворачиваем полную копию базы на стенде, прогоняем скрипты, сравниваем хеши и проводим нагрузочное тестирование. Только после успешного прохода запускаем dual-write на проде. Если что-то идёт не так — откатываемся к исходной БД.

Процесс работы

Этап Длительность Результат
Аналитика 1-2 дня Документ аудита схемы и зависимостей
Проектирование 1-3 дня Маппинг типов, план dual-write
Реализация 3-10 дней Скрипты миграции и отката
Тестирование 2-5 дней Сравнение хешей, нагрузочное тестирование
Деплой 1-2 дня Запуск dual-write, переключение чтения

Что входит в работу и гарантии

  • Документация итоговой схемы и маппинга типов.
  • Скрипты миграции и отката.
  • Тестовый прогон на полной копии базы.
  • Обучение команды работе с новой СУБД.
  • Поддержка 2 недели после деплоя.
  • Гарантия 99.99% целостности данных.
Пример: миграция интернет-магазина с MySQL на PostgreSQL

Заказчик имел базу 120 ГБ с кастомными типами ENUM и нулевыми датами. Мы настроили pgloader с 12 кастами, провели dual-write за 4 дня. Переключение прошло без downtime. Экономия на лицензиях Oracle (от которого уходили) — 40% в год.

Сроки и стоимость

Для базы до 100 ГБ миграция занимает от 3 рабочих дней (MySQL → PostgreSQL) до 2 недель (MongoDB → PostgreSQL с нормализацией). Стоимость рассчитывается индивидуально после оценки объёма данных и сложности трансформации. Свяжитесь с нами для консультации и получите индивидуальный план миграции без обязательств. Закажите предварительный аудит вашей базы!