Pull to refresh
9
19
Василий @nvv

User

Send message

В статье приведён запрос, который выберет и выведет все FK, у которых найдены признаки потенциальной проблемы. Посмотрите в блоке "Код проверки", выполните его.

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

Как разрешается ситуация, если два разработчика параллельно внесли изменения в структуру БД (в разные таблицы добавили по одной колонке) затрагивающие view_name, получили наборы файлов миграций m1 и m2, отправили PR каждый со своими изменениями, их изменения приняли. Порядок приёма PR может повлиять на конечный вид view_name ?
В подходе описанном в статье, когда m1 и m2 это инкрементальные изменения, а view будет пересоздано, обе добавленные колонки будут учтены во view_name.

Не один и не два раза в разных проектах встречалась проблема - в разных файлах создавались однотипные объекты с одинаковым именем. Причины разные, от copy-paste и забыли переименовать, до неправильного порядка при накате скриптов. Если использовать только create вместо create or replace, обновление развалится при перой же попытке накатить, это быстро локализует проблему.

Пересоздание таких сущностей занимает немного времени

но вы же, если правильно понял, дропаете их до применения миграций к таблицам, а создаете уже после. А миграции данных вполне себе могут занимать сколько угодно времени. И БД будет сидеть голенькая все это время. Для, например, добавления одной колонки в одну таблицу как-то круто сносить вообще всё.

Инкрементные миграции, которые выполняются на втором этапе, действительно могут выполняться долго. Удаление и создание хранимок и представлений, как правило, занимет мало времени, экономия не всегда целесообразна в ущерб простоте поддержки.

Для, например, добавления одной колонки в одну таблицу как-то круто сносить вообще всё.

В БД может быть от нескольких десятков view, которые зависят друг от друга, часть из них, могут иметь код вида

CREATE VIEW view_name AS SELECT table_name.*, ... FROM table_name ...

Да, выборка без фиксации колонок не относится к лучшим практикам, но такой код объективно встречается, не всегда есть время и ресурсы, чтобы отрефакторить и оттестировать все подобные места в связке БД и бэка. Если view не пересоздать, новая колонка не попадёт из table_name во view_name.

Пересоздавать проще, чем каждый раз вручную отслеживать что должно/может измениться при "добавлении одной колонки в одну таблицу".

И решение вы оцениваете как полностью ваш локальный велосипед (без оценки качества, только уникальность) или его можно сравнить со способом работы DbUp, SqlPackage или чего-то еще?

Вероятно мы говорим о разных вещах. Повторюсь, в статье описан подход по разделению сущностей БД, и, в зависимости от этого, разные алгоритмы организации хранения (инкременты или постоянный скрипт) и применения (строго один раз или многократно).
Подход может быть реализован разными инструментами и liquibase, и "своими велосипедами" (в опросе вариант "Разработали и применяем своё решение" достаточно популярен).

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

В текущем проекте используем liquibase, он обеспечивает очередность, проверяет контрольные суммы файлов, сколько раз скрипт должен быть выполнен, какие скрипты уже были накачены. Деплой - liquibase получает код необходимой версии и параметры коннекта к БД, обрабатывает changelog файлы.

Ветка или тег релиза (что принято в проекте) совпадают для кода миграций и соответствующего кода бэка.

А как добиться соответствия кода релизов БД, нескольких приложениях бэка и фронта - отдельная тема)

По таблицам больше похоже, что миграции (ALTER TABLE ADD COLUMN), по хп больше похоже что скрипт один и навсегда, т.е. смесь подходов. Как тогда рулите тем, что является дельтой, которую нужно применить к серверу?

Действительно, используется двойной подход, именно для этого и разделяем сущности по их отношению к данным - хранят (инкрементальные миграции) или только обрабатывают ("скрипт один и навсегда").
На сервере накатывается код соответствующий релизу. Он содержит и новые дельты и актуальные версии процедур/представлений.

Не рекомендуется использовать create or replace во всех случаях. Лучше явно выполнить удаление объекта, а потом создать заново (для функций и представлений это даже делается на разных этапах). Это уменьшит риск случайной замены объектов с потерей.

С удалением обычных view (на первом этапе) и созданием их заново (на третьем), как правило, меньше всего проблем. Самая часто встречающаяся - необходимость соблюдать порядок создания/удаления, который учитываем взаимозависимости.

С materialized view сложнее, т.к. они не только обрабатывают данные, но и хранят их. Как отметил в статье, для таких структур универсального подхода нет, из-за наличия данных их чаще приходится относить к инкрементальным изменениям (обрабатываются на втором этапе).

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

По вопросу N1 - явно указана зависимость от роли, зависимости от группы нет в описании и для демонстрации подхода нет необходимости её добавлять. По вопросу N2 - такое ограничение не указано и уточнение наоичия/отсутствия ограничения не поможет.

В реальных задачах перечень вопросов, которые должны быть проработаны до реализации, может быть очень широким и предложенные вами вопросы конечно должны входить в этот список.

Модельная задача описана полностью и рассмотрены варианты решения.

Какие дополнительные условия вы хотели бы предложить включить?

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

В указанной модели несколько документов могут ссылаться на одну запись во "второй проекции" таблице doc_number?

Корреляция может быть, а может и быть, поле типа serial определяет default, но не запрещает вставлять другие значения. При партиционировании по id может понадобиться прогнозировать соотношение дат и диапазонов id, устанавливать/корректировать диапазоны.

Фраза "в разных партициях записи могут содержать одинаковые значения doc_id" - просто шедевральна.

При партиционировании по дате - да, технически могут и СУБД это допустит. "Прилететь" такие данные могут, отказываться от такого контроля не хотелось бы.

В PG, к сожалению, в настоящее время нет кластеризованного индекса, который постоянно поддерживал бы порядок записей.

Каким образом партиционирование по id поможет улучшить выполнение запросов, которые зависят от даты документа (фильтруют по ней)?

Синхронизация на триггерах имеет ряд недостатков. Из-за отсутствия FK, вероятно, не получится возложить контроль синхронности данных на СУБД.

апдейт поля партицирования невозможен

Обновление полей по которым выполняется партиционирование работает, может быть не совсем ожидаемое поведение из-за реализации, если существует FK на PK партиционированной таблицы.

Вы правы, партиционирование инструмент, которым можно как исправить, так и завалить проект.

После партиционирования возможна ситуация, когда в разных партициях записи могут содержать одинаковые значения doc_id, поэтому используется пара doc_id+doc_date (это также отражение требования «контроль возложить на СУБД»).

1
23 ...

Information

Rating
297-th
Location
Россия
Registered
Activity