Является ли каждая команда DDL SQL обратимой? [контроль версий базы данных]
Я хочу настроить механизм отслеживания изменений схемы БД, такой как описанный в этом ответе:
Для каждого изменения, которое вы вносите в базу данных, вы пишете новую миграцию. Миграции обычно имеют два метода: метод "вверх", в котором применяются изменения, и метод "вниз", в котором изменения отменяются. Одна команда обновляет базу данных, а также может использоваться для приведения базы данных к определенной версии схемы.
Мой вопрос заключается в следующем: обратимы ли все команды DDL в методе "вверх"? Другими словами, можем ли мы всегда предоставлять метод "down"? Можете ли вы представить какую-либо команду DDL, которая не может быть "вниз"?
Пожалуйста, не учитывайте типичную проблему переноса данных, когда во время метода "вверх" мы теряем данные: например, изменение типа поля с datetime
(DateOfBirth
) чтобы int
(YearOfBirth
) мы теряем данные, которые невозможно восстановить.
3 ответа
На сервере sql каждая команда DDL, о которой я знаю, является парой вверх / вниз.
Помимо потери данных, каждая миграция, которую я когда-либо делал, является обратимой. Тем не менее, Rails предлагает способ пометить миграцию как "разрушительную":
Некоторые преобразования разрушительны таким образом, что не могут быть обращены вспять. Подобные миграции должны вызывать исключение ActiveRecord::IrreversibleMigration в их методе down.
Смотрите документацию по API здесь.
Да, вы определили случаи, когда вы теряете данные, либо преобразуя их, либо просто УДАЛЯЙТЕ КОЛОННУ в миграции "вверх".
Другой пример - вы можете удалить объект SEQUENCE, потеряв при этом его состояние. Миграция "вниз" воссоздаст последовательность, но она начнется заново с 1. Это может привести к созданию повторяющихся значений в последовательности. Не проблема, если вы выполняете миграцию в пустой базе данных и хотите, чтобы последовательность все равно начиналась с 1, но если у вас есть некоторое количество строк данных, вы бы хотели, чтобы последовательность была сброшена до наибольшего значения используется в настоящее время, что трудно сделать надежно, если только у вас нет эксклюзивной блокировки на этой таблице.
Любой другой DDL, который зависит от состояния данных в базе данных, имеет аналогичные проблемы. Во-первых, это, вероятно, не очень хороший дизайн схемы, я просто пытаюсь придумать любые случаи, которые соответствуют вашему вопросу.