Ответы пользователя по тегу Миграция базы данных
  • Что может а что не может содержать миграция?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Нормальная миграция подразумевает следующие характеристики:
    • идемпотентность - будучи запущена, серия миграций приводит к одинаковому результату
    • обратимость - любой шаг миграции можно откатить с откатом версии приложения
    • целостность - миграция переводит приложение из рабочего состояния в рабочее (баги не в счет)

    Естественное применение миграций - это CI/CD. Т.е. в большинстве случаев ожидается минимальный простой приложения во время деплоя, именно поэтому миграции в большинстве своем изменяют структуры данных.
    Но это совсем не означает того, что данные не могут быть изменены. Часто так бывает, что некоторые системные справочники требуют обновления или же данные пользователей требуют изменений. Например - для имени и фамилии использовалось одно поле, а теперь оно делится на два, как положено. Миграция данных в данном случае естественный и необходимый процесс, который может занять значительное время. Поэтому используется запланированный процесс выкатки приложения с его аннонсированием для пользователей. Запланированный даунтайм стандартная практика больших и сложных приложений, которые могут это себе позволить.
    Если ваше приложение не может себе позволить остановку обслуживания пользователей, то для таких случаев пишется вспомогательный код, который делает обработку случаев немигрированных данных и вообще всевозможные костыли, лишь бы оно работало (основной источник гемора).

    Является ли ресайз картинок частью миграции? И да и нет. Это зависит от ряда факторов - сломается ли приложение, если не будет картинки или будет старая картинка, это критичная функция или нет. Пример критичной функции - инстаграм.
    Если дизайн приложения сделан правильно и функция второстепенная, то миграция происходит лишь на уровне БД, а сам ресайз на уровне приложения (скрипта во время выкатки). Пример - новый размер юзерпика, никто не умрет, если он будет больше или меньше, может выглядеть не очень какое-то время, но в конце концов он станет нормальным. Если для нового размера добавляется новый столбец, то в него во время миграции копируются данные из другого столбца, чтобы не рушить функционал.

    Итак, мои ответы по вашим вопросам (как бы делал я):
    1. Добавил бы миграции с внесением/удалением 2 новых столбцов. Первый для email, второй email_verified. После развертывания запустил бы скрипт верификации почты (ох нескорый и ненадежный этот процесс). По-хорошему, по первому логину просил бы проверить и верифицировать email путем отправки кода на него. Думаю, вы уже поняли, что мы попадаем в серую область того, что машинная проверка здесь неуместна. Но допустим, мы использовали машинную верификацию, все проверили, все нужно сделали. В следующей версии мы удаляем столбец email_verified.
    2. Как правило, такие вещи данные в БД не изменяют, а значит нет необходимости в миграциях, достаточно скрипта. Но, если вы ок с простоем приложения, то можно вполне внести данный скрипт в миграцию, а также не забыть об откате этой миграции (удалять новые размеры, к примеру).

    Как мы все видим, миграцию можно рассматривать, как в контексте СУБД, так и в контексте приложения в целом.
    Общепринятая практика - рассматривать миграцию в контексте баз данных. Все остальное - скрипты и костыли в самом приложении.

    Универсального рецепта нет. Все завязано на бизнес-логику и реализацию кода приложения. Если нельзя отделить сложную обработку данных от процесса деплоя, то эту логику следует встраивать в код миграций. Пример такой обработки - получение какого-нибудь системного идентификатора, который используется при работе приложения, например ротация API ключей при смене системы аутентификации.
    Ответ написан
    2 комментария
  • Версионирование данных в базе?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Если у вас в таблице 500к записей, то нет абсолютно никакого смысла скачивать ее всю на телефон за исключением одной ситуации - режима работы оффлайн. В данном случае просто делается актуальный слепок, архивируется и отправляется к клиенту. Скачать 100 МБ с телефона сейчас не проблема. При наличии интернета гораздо проще делать запросы через API.

    Если подобный вариант не устраивает, то делается все очень просто - на сервере данные никогда не удаляются, но хранится признак их удаления. Помимо этого признака хранится признак последнего обновления записи.
    На клиенте хранятся специальные мета-данные с информацией о последнем обновлении (timestamp).
    При подключении клиент запрашивает обновление со временем последнего обновления и локальным временем (видел неправильно настроенные часы миллион раз), сервер отвечает обновленными данными. Для сохранения трафика данные приходят в сжатом формате, а удаленные записи передаются отдельным фрагментом с минимальной идентфицирующей строки информацией (поля: первичный ключ или уникальный индекс). Это обеспечивает минимальный объем трафика, но работает только в одну сторону.

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

    Для обычных баз данных в режиме совместной работы настраивайте мастер-мастер репликацию с транзакциями. Для мобильных приложений используйте режим тонкого клиента.
    Ответ написан
    2 комментария