Я начинаю перемещать больше логики в базу данных, используя триггеры, представления, функции, 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. Но это боль. : /
Мысли очень приветствуются. Надеюсь, я объяснил это достаточно хорошо, я сокращаю потребление кофеина и немного нервничаю.
О, я задал похожий вопрос о переполнении стека: Изменение типа столбца, используемого в других представлениях Ответом была функция, которая позволяла мне передавать:
- SQL-код для запуска
- представления базы данных для удаления и воссоздания
Функция будет получать определение представления, удалять представления, запускать код sql, а затем воссоздавать определение представления (в обратном порядке удаления). Возможно, система таких функций поможет решить проблему копирования / вставки кода SQL в файлы миграции.