Доступ к данным и переход с PHP/MySQL
Оглавление · PostgreSQL и JSONB · Redis
Задача: разделить смену языка, СУБД, способа доступа и бизнес-контракта. Нужны SQL, runtime-валидация и границы транзакции.
Четыре независимых решения
PHP → TypeScript меняет среду исполнения и код приложения. MySQL/MariaDB → PostgreSQL меняет СУБД и диалект. Прямой SQL → query builder/ORM меняет средство выражения запросов. Добавление Redis меняет топологию и правила копирования данных. Одновременность этих шагов не делает их обязательной цепочкой обновления.
Прямой SQL с параметрами — полноценный вариант современного приложения. Если существующая система удовлетворяет требованиям, переезд требует конкретной причины: нужные возможности, сопровождение или границы продукта, а не оценка «сырой SQL устарел».
Драйвер, builder и ORM
| Уровень | Что берёт на себя | Что остаётся разработчику |
|---|---|---|
| Драйвер | Соединение, параметры, передача и получение результата | SQL, схема, преобразование и граница доступа |
| Query builder | Построение SQL из операций API | Смысл запроса, план, ограничения и транзакции |
| ORM | Отображение сущностей, связи и операции хранения | Инварианты, загрузка связей, SQL и миграции |
Для статьи по slug во всех вариантах должны сохраниться: параметризованное значение, фильтр публикации, модель результата, различие отсутствия и отказа БД. Название repository не гарантирует ни одну из этих частей.
Исходник схемы
flowchart LR Input["Внешний вход"] --> Validate["Runtime-схема и доступ"] Validate --> Domain["Операция и инварианты"] Domain --> Access["Драйвер / builder / ORM"] Access --> SQL["Реальный SQL и транзакция"] SQL --> DB["Ограничения БД"]
Схема отделяет ответственность; не требует отдельного класса на каждой стрелке. TypeScript-тип результата не проверяет данные автоматически после десериализации. Если приложение принимает неизвестный JSON, проверку нельзя заменить entity.
TypeORM как предмет лаборатории
TypeORM поддерживает сущности, связи и repositories. В Active Record методы хранения связаны с entity; в Data Mapper доступ вынесен отдельно. Сравнение моделей. Это два способа организации кода, а не разные гарантии транзакций.
До подключения выберите версию и изучите сгенерированный SQL одной операции. Загрузка связи на каждой статье может дать N+1 запросов; eager-загрузка может читать ненужные данные. Граница транзакции должна охватывать все нужные команды через предназначенный для неё API, а не случайное глобальное соединение.
Миграция схемы — версионированное изменение с проверяемым SQL и порядком применения. Автоматический synchronize не заменяет продуманный production-переход. Настройка миграций. TypeORM в workspace не установлен; исполняемый пример с decorators здесь не приводится, чтобы не изображать выбранную и проверенную интеграцию.
Что проверить при смене СУБД
Переносимые идеи — ключи, связи и транзакции. Конкретные типы и SQL различаются. Составьте таблицу соответствий по документации исходной и целевой версий:
- Идентификаторы, диапазоны чисел, генерация ID и порядок выдачи.
- Даты, часовые пояса, кодировка, collation и регистр сравнения.
- NULL, уникальность, булевы значения и поведение ограничений.
- JSON, индексы, SQL-функции и параметры запросов.
- Изоляция, блокировки, повторы транзакций и пул соединений.
Это список проверки, не утверждение, что каждый пункт несовместим. Для bigint отдельно проверьте преобразование в JavaScript: целочисленная точность number ограничена, а обычная JSON-сериализация bigint требует решения. Не меняйте смысл существующих ID ради удобного типа клиента.
Перенос данных — отдельный процесс
Исходник схемы
flowchart TD Inventory["Модели, запросы и владельцы"] --> Snapshot["Согласованный снимок"] Snapshot --> Transform["Явное преобразование и отчёт"] Transform --> Rehearsal["Репетиция в отдельной среде"] Rehearsal --> Compare["Количество, связи и бизнес-проверки"] Compare --> Cutover["План финального переноса и переключения"] Cutover --> Observe["Наблюдение и согласованный откат"]
Равное число строк не доказывает сохранность: проверьте связи, даты, публикации, тексты и ответы важных запросов. Укажите, откуда берутся записи, появившиеся после снимка: пауза записи, журнал изменений или иной согласованный механизм.
Двойная запись в две БД добавляет частичные отказы; она не возникает автоматически из ORM. Откат после новых записей требует решения для этих данных, а не только возврата старого Docker-образа. Резервная копия полезна после проверки восстановления.
Для Atmanki CMS владеет схемой PostgreSQL. Сайт читает API Strapi и не добавляет TypeORM поверх её внутренних таблиц. Импорт проекта работает с dry-run, конфликтами и редакторскими правками; эта глава не запускает перенос или импорт. Redis также не принимает роль базы контента.
Практика
Возьмите вымышленный PHP-сервис: статьи, авторы и счётчик просмотров. Опишите, какой шаг решает конкретную проблему, а какие можно отложить. Сравните чтение через драйвер и ORM по реальному числу запросов и границе доверия.
Подготовьте карту переноса пяти полей и контрпример «количество строк совпало, смысл потерян». Укажите финальную синхронизацию, проверку переключения и судьбу новых данных при откате. Это проектирование лаборатории, не инструкция менять production-СУБД текущего проекта.