2012-03-29 7 views
4

Я начинаю перемещать больше логики в базу данных, используя триггеры, представления, функции, CTE и т. Д. Когда plv8/json выходит для postgres, я вижу, что я размещаю там много логики.Управление изменениями базы данных

У меня возникли проблемы со стандартным способом миграции баз данных в продолжении и activerecord. Оба сиквела и activerecord позволяют помещать произвольный код sql в файлы с меткой времени. Когда запускается каждый файл, таблица schema_versions обновляется с именем файла (или меткой времени в имени файла), которая сохраняет запись о том, какие миграции были применены к текущей базе данных.

Если много кодирования делаются на уровне базы данных, что означает, что изменения существующих представления, функции и т.д. следуйте приведенной ниже схеме:

миграции 1 определяет функцию и виду, который использует этот функция.

-- Migration 1 
create function calculate(x int) returns int as $$        
    return x + 1;                 
$$ language sql;                 

create view foos as (               
    select something, calculate(something) from a_table       
); 

Изменение требований, и мне нужно изменить тип функции. В Миграция 2 Мне нужно отбросить все объекты, зависящие от foo, и воссоздать их, скопировав их все тело - даже если в большинстве других кодов не было никаких изменений!

-- Migration 2                

-- Have to drop all views and functions that depend on the     
-- `calculate(int)` function.            
drop view foos;                
create or replace calculate(x bigint) returns bigint as $$     
    return x + 1;                
$$ language sql;                

-- I could do `drop function calculate(int) cascade`,      
-- but I might accidentally drop some objects that wouldn't get recreated below. 

-- Now I have to recreate foo.            
create view foos as (              
    select something, calculate(something) from a_table      
); 

Если я строй системы, основанную на представлениях и функциях и триггерах, мои миграции будут заполнены дублированным кодом, и это трудно найти самую последнюю версию кода. Вы можете сказать «не делай этого!», Но для моих целей (электронная коммерция, доставка, транзакции) я нахожу, что намного проще и быстрее обеспечить, чтобы база данных обеспечивала целостность данных, выполняя логику внутри базы данных.

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

Любые идеи о том, как решить эту проблему?

Моя лучшая идея заключается в том, как код sql содержится в их собственных канонических файлах (app/sql/orders/shipping.sql, app/sql/orders/creation.sql и т. Д.). Каждый развивается непосредственно на них. Всякий раз, когда настало время для выпуска, вам нужно создать новый файл миграции, посмотреть на все измененный код с момента предыдущего выпуска, выяснить цепочку зависимостей объектов базы данных, которые необходимо удалить и воссоздать, а затем скопировать sql из канонических файлов sql в новый файл миграции продолжения/activerecord. Но это боль. :/

Мысли приветствуются. Надеюсь, я объяснил это достаточно хорошо, я сокращаю потребление кофеина, и я немного подлый.

О, я задал подобный вопрос о переполнении стека: Changing the type of a column used in other views Ответ функция, позвольте мне передать:

  • SQL кода для запуска
  • представления базы данных, чтобы удалить и заново

Функция будет извлекать определение вида, удалять представления, запускать код sql, а затем воссоздавать определение представления (в обратном порядке отбрасывания). Возможно, такая функция поможет решить проблему копирования/вставки кода sql в файлы миграции.

+0

https://github.com/nkiraly/DBSteward выглядит как интересный подход к решению этой проблемы. –

+0

Привет, я являюсь соавтором DBSteward. Я знаю, что прошло почти четыре года с тех пор, как вы задали этот вопрос, но мы все еще активно развиваем DBSteward. Мне интересно узнать, не сделали ли вы или не использовали DBSteward, и каков ваш опыт, или почему это не решило вашу проблему. –

ответ

4

Я бы рекомендовал liquibase.

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

1

Вы можете найти блог-посты Dave Уилера интересный начиная отсюда:

http://justatheory.com/computers/databases/simple-sql-change-management.html

Моя скорость изменения базы данных достаточно мала, но я, как правило, быть небрежным и внести небольшие изменения в схему непосредственно, так Я должен был придумать немного инфраструктуры, чтобы поймать, когда я это сделал. Основными элементами являются:

  1. файл сборки, который может восстановить базу данных разработки с нуля
  2. Набор схем-файлов, разделенных на «модули» (lookups_schema.sql, lookup_data.sql)
  3. Набор обновление файлов, что переход от одной ревизии к следующему
  4. Я обычно не имею соответствующие сценарии даунгрейда, некоторые люди делают
  5. скрипта для заполнения своей базы данных с правдоподобным количеством тестовых данных
  6. Кардинальны, набор тестов через pgTAP, который проверяет мои различные функции, виды, а также сценарии обновления. Тесты обновления могут быть запущены и с живой базой данных.

Если у вас есть отдельный экземпляр PostgreSQL установлен с FSYNC Включение/отключение электронного диска и т.д., затем Перестройка всей БД и заполнение может потребоваться несколько секунд (если вы не слишком много данных тестов).

Начните с # 1, # 2, затем добавьте # 6 (pgTAP is очень прохладно), а затем остальные. Самое главное - это набор тестов, который проверяет ваш код в базе данных.

Есть инструменты, которые пытаются автоматизировать изменения схемы для вас, но они действительно хороши при добавлении нового столбца к таблице и тому подобное. Когда у вас есть код в вашем db, тогда они не очень помогают.

Смежные вопросы