2008-09-24 7 views
3

Я хочу, чтобы настроить механизм для отслеживания изменений DB схемы, такой описанной в this answer:Является ли каждая команда DDL SQL обратимой? [База данных управления версиями]

Для каждого изменения, внесенные в базу данных , вы пишете новую миграцию. Миграции обычно имеют два метода: метод «вверх», в котором применяются изменения , а метод «вниз» - в , изменения которого отменены. Одна команда возвращает базу данных до , а также может использоваться для приведения базы данных к определенной версии схемы.

Мой вопрос следующий: Является ли каждая команда DDL методом «вверх» обратимой? Другими словами, можем ли мы всегда предоставлять метод «вниз»? Можете ли вы представить какую-либо команду DDL, которая не может быть «опущена»?

Пожалуйста, не учитывайте типичную проблему миграции данных, когда во время метода «вверх» мы имеем потерю данных: например, изменяя тип поля от datetime (DateOfBirth) до int (YearOfBirth), мы теряем данные, которые невозможно восстановить.

ответ

4

в sql сервере каждая команда DDL, которую я знаю, представляет собой пару вверх/вниз.

2

Помимо потери данных, каждая миграция, которую я когда-либо делал, является обратимой. Тем не менее, Rails предлагает способ отметить миграцию как «разрушительный»:

Некоторые преобразования являются разрушительными в манере, которая не может быть отменено. Миграции такого рода должны поднять ActiveRecord :: IrreversibleMigration Исключение в их методе down.

См. Документацию по API here.

+0

Даже данные могут быть обратимыми, если вы храните их где-то как с локальными yml-файлами (см. Https://github.com/tomkurt/Reversable-Data-Migration). – 2012-02-12 16:20:55

2

Да, вы идентифицировали случаи, когда вы теряете данные, либо путем его преобразования, либо просто DROP COLUMN в «вверх» миграции.

Другим примером является то, что вы можете удалить объект SEQUENCE, потеряв его состояние. Миграция «вниз» воссоздает последовательность, но она начнется с 1. Это может привести к созданию повторяющихся значений в последовательности. Не проблема, если вы выполняете перенос в пустой базе данных, и вы хотите, чтобы последовательность начиналась с 1 в любом случае, но если у вас есть несколько строк данных, вам нужно, чтобы последовательность была сброшена до наибольшего значения в настоящее время используется, что трудно сделать надежно, если только у вас нет эксклюзивной блокировки для этой таблицы.

Любые другие DDL, которые зависят от состояния данных в базе данных, имеют схожие проблемы. Во-первых, это, вероятно, не очень хороший дизайн схемы, я просто пытаюсь думать о любых случаях, которые соответствуют вашему вопросу.