Comments 28
… все колонки nullable()
Дичь какая-то. У Вас как-будто не база данных, а склад всего на свете какой-то, то не знаете, это не можете. Пишите просто в файл тогда, а бизнес-логика в приложении разберётся уж…
2. не надо БДшный код пихать в миграции
Лучше структурированных БД, пока ничего не придумали, поэтому лучше выжимать их них максимум.
Типы данных надо объявлять такими, какими они будут, это позволит:
— отправить мета инфу на фронт и обработать максимально эффективно 95% ошибок
— на уровне БД перехватить ошибки и проксировать их пользователю. Тут опять же максимальная производительность и минимальный код
Всё не то.
А если вам надо тип переменной изменить?
Например поле name сделали сначала 15 символов, потом поняли что надо 30, а потом поняли что надо 255. Рандомные миграции приведут к рандомной длине поля.
И очень интересно будет будущим разрабам смотреть в базе миллион колонок, которые давно уже не используются
Размер колонок меняется миграцией в любую сторону. Разве это проблема?
Но на самом дела колонки всегда надо создавать максимальной длины. Современным СУБД не важно колонка 10 символов или 100, если в неё пишется только 5, то места на диске будет занято только на 5 символов.
При желании тип колонки можно поменять в миграции. Если колонку добавили недавно, то это не проблема. Если колонку добавили давно, то просто добавляем новую колонку и работаем только с ней, старую колонку не пишем и не читаем.
Работать с таблицами через select *, это всегда был дурной тон. Всегда надо указывать колонки которые вас действительно интересуют.
И на самом деле в таблице должны быть колонки для индексов и одна колонка data в которую пишется json с бизнес данными. Но это высший пилотаж. Для тех кто понимает что такое база данных.
Если в таблице стало 200+ колонок и используется только 10. То почему не начать работать с новой таблицей?
Первый релиз делаем миграцию с новой таблицей и пишем посев данных с переносом данных из одной таблицы в другую, следующий релиз меняем в моделе имя таблицы и теперь мы работаем с новой таблицей в которой только нужные нам 10 колонок.
за полгода было написано 1000+ миграций
Уверен очень скоро захотите эти миграции схлопнуть и тогда вас ждут сюрпризы. Миграции не должны зависить от кода, схлопывать такие миграции та еще боль. Ну да и вы сами говорите, что хотите добится от миграций идемпотентности, а код этому не способствует.
'Есть у нас ветка драфт, что бы пушить в драфт не надо делать МР, эта ветка нужна для того что бы программист мог по быстрому показать свои наработки бизнес аналитику, что бы фронт-энд мог интегрироваться с изменениями на бэк-энде. Драфт регулярно ресетиться.'
Мне кажется, тут корень проблемы в Вас.
Тратите ресурсы на гипотетическую возможность в любой момент слить любые ветки, это действительно нужно?
Есть разница между пет проектами, ин-хаус для фирмы на пару тысяч сотрудников и для приложения которое работает с десятками тысяч пользователей с функционалом объёма примерно обычной CRM системы, в которой лидов 100500 вариантов и каждый вариант обрабатывается уникальным образом.
Т.е., грубо говоря, когда заказчик спросит, почему БД разрослась до большого объёма и почему там есть колонки\таблицы, которые не используются, но замедляют работу и едят память, что Вы ответите?
И ровно попричине что ваша система серьезная и там много клиентов и всего такого — стоит озаботится тем что бы в базу ни в каком разе не могли попасть невалидные данные. И о чудо для этого в бд есть constraint на все случаи жизни. А в миграциях есть эксепшн который будет орать если его пытаются накатить не на то состоянии базы, которое использовал программист при создании
Проблема не в том что таблицу правит два разных человека которые между собой не договариваются, проблема в том что для одной фичи нужны одни колонки, для другой другие, и какие то колонки могут после проверки гипотезы на драфте умереть на всегда.
А приложение не должно падать от таких вещей. Если приложению важно что бы какие то данные соответствовали каким то требованиям, то эти требования надо проверять на уровне приложения, а не БД, потому что БД одна, а версий приложения с десяток.
Перекраивать БД под каждую конкретную версию кода не реально (ветки фич иногда приходиться сливать в одну ветку и тестировать их совместную работу)
Мне кажется у вас не было опыта подобной разработки, поэтому вам сложно уловить на слух, это та вещи которую надо увидеть.
В приложении надо валидировать данные. Но и на уровне бд имхо должен быть бастион — который не даст внести невалидные данные.
У меня встречное впечатление. Что то в том как вы работаете и как у вас организованно — что то пошло не так, если вы выпиливаете constraint из бд и один из основных принципов работы миграций потому что иначе никак, иначе неудобно
Схожая проблема и с отказом от constraint в бд. Там выше уже предлагали тупо писать в файл.
Вы в курсе что такое миграции и как они работают? Если миграция создает колонку в таблице, то она упадет только если такая колонка уже создана. Ни один механизм миграцийни когда не проверяет что схема бд находиться в каком то преопределенном состоянии.
Миграции это способ версионировать схему базы данных. Каждая миграция это аналог камита. Каждая миграция это изменение состояния между до миграции и после миграции. Но в отличии от версионирования у миграцийнет дерева. Нет механизма для записи осередности применения измененийк схеме базы данных.
Ровно так же причин не хватает выпиливать constraint из дб. Ну говорю ж к чему эти полумеры strict=off и льем туда вообще что захотим
З.Ы. К этому заявлению «у каждой таблицы есть команда владелец» — у меня честно говоря миллион вопросов возникает — сформулировать без мата могу только один — какого черта у вас там вообще происходит?
З.З.Ы. Ваши слабые попытки намекнуть мне что я «ростом не вышел» — начинают чуток утомлять честно говоря. Вы уж либо их прекращайте, уверяю вас, я работал не только с пет проектами, знаю что такое миграции и даже сталкивался с последствиями решения — а давайте выпилим какие то проверки на уровне бд и через 3 месяца проверим чо там у нас получилось. Либо уж тогда делайте их более сильными — «дурак не фига не понимаешь» и закрываем общение.
Continuos delivery, миграции, репозитории нужны для переносимости кода, для отчуждаемости кода от разработчика.
Миграция которая создаёт колонку, почему она не должна упасть если в таблице присутствуют какие то другие колонки? Кажется я повторяюсь.
Ваше возмущение по поводу владельцев кода, это что то с чем то. Вас не возмущает что работу между сотрудниками делят по отделам? что каждая команда отвечает за свой функционал или фичу? нет? странно.
Сервис ориентированная архитектура не слышали? Каждый микро-сервис со своим стеком технологий? нет?
Владелец продукта?
У кода не может быть владельца? у Фичи?
Миграция которая создает колонку в таблицу должна упасть если колонка в этой таблице уже есть. Потому что эту миграцию писали для версии бд которая уже не имеет отношение к тому что сейчас находится на сервере. В вашем случае она накатится и сообщит программисту что все ок, хотя ни хрена не ок. Программист думал об одном состоянии структуры бд — а по факту там другое. Это конфликт — который должен быть обработан человеком. Иначе консистентность нарушена. Главный смысл миграции потерян. Но для вас это норм. В таком случае миграции не нужны
Что такое микро-сервисная архитектура я знаю. и даже работал. я вас попросил — завязывать. я вполне могу себе представить когда точкой обмена может быть бд, очередь, апи и даже файловая система. Но из ваших слов у меня начинает создаваться впечатление что у вас огромная бд с монолитом в ларке, вы в бд выделили таблицы раздали их по командам, прицепили модульную структуру к ларке и назвали это микросервисами. В таком случае могу вас разочаровать — называть это микросервисной архитектурой скорее всего не стоит.
Так как я подустал читать аргументацию «да вы не знаете что это такое» — подытожу. Все что вы сделали в этой статье — дык это уменьшили контроль за состоянием данных в бд и за версионностью в бд — просто потому что вам неудобно, да и фикстуры медленно накатываются. У меня был опыт разбора проектов с таким подходом — уверяю вас ничего хорошего там не происходит. Судя по обсуждению — вам это только предстоит. Предсказываю: будет как с бэкапами — ситуации когда они нужны возникают очень редко, но та ситуация когда они нужны а их нет — запомнится раз и на всю жизнь, и в вашем случае вы в дальнейшем будете вешать ограничения на все движется, а на все что не движется — двигать и вешать, и в откатах миграций будете использовать drop а не dropIfExists — мало ли.
Мои отчаянные попытки обьяснить какая боль вас ждет за следующим поворотом не возымели никакого результата, а аргументировать в рамках «да кто вы такой» — мне мало интересно. Желаю удачи
в таблице migrations (не в вашем случае, а в обычном) хранится список миграций, которые уже применены к БД, а так же очередность их применения. Чем вам не состояние БД?
— это быстрее и производительнее
— на уровне БД гарантирует консистентность данных
Например, решили сделать поле position обязательным, на основе того, что оно обязательное написали какие-то сервисы.
Пишем миграцицию:
ALTER mytable MODIFY position VARCHAR(191) NOT NULL
Миграция может отвалиться, тогда мы поймём что у нас есть данные, которые не соответствуют нашим представлениям.
Ну и тут 2 варианта:
— написать UPDATE и по определённым правилам обновить данные
— написать
ALTER mytable
ADD CONSTRAINT position_not_null_check
CHECK (position NOT NULL AND created_at > '2020-02-19')
В любом случае выполнив SHOW CREATE TABLE, я увижу каким критериям соответствуют данные и смогу правильно написать код их обработки.
Дописав же код проверки в приложении, на данные нет абсолютно никаких гарантий.
На уровне БД если эти проверки делать, то потребуется для каждой версии кода, делать свою версию бд, свои инстанс.
Не айс.
А в чем проблема работать в одной БД, но добавлять таблицам префиксы для каждой версии кода?
Кроме того, у нас сейчас работа ведётся одновременно в 30-ти ветках, то есть одной таблицы будет 30-ть копий, влитые ветки в мастер ни кто не удаляет, то есть у нас на текущий момент могло бы быть 1800 версий одной и той же таблицы.
Сложно администрировать такое хозяйство.
при сбое механизма префиксов, могу быть проблемы с чтением не из той таблицы
Префикс таблиц задается в конфигурации приложения. Как часто у вас проиходят сбои конфигов подключения к БД?
Сложно администрировать такое хозяйство.
Установите регламент префиксов. Например, instanse_{ISSUE_ID}_
. Написать скрипт, который дропнет таблицы по префиксу, посмотреть в сторону вебхуков, которые могут дергать этот скрипт при удалении ветки.
По-моему, это куда меньшая боль, недели всё описанное выше.
в этом проекте накатить схему с нуля с посевом занимает от часа.
Но ведь с представленным вами механизмом все миграции накатываются каждый раз заново (у вас же таблица миграций остается пустая)?
Есть у нас ветка драфт, что бы пушить в драфт не надо делать МР, эта ветка нужна для того что бы программист мог по быстрому показать свои наработки бизнес аналитику, что бы фронт-энд мог интегрироваться с изменениями на бэк-энде
Другая проблема в том что миграции локально применяются по мере разработки кода, а накатываются на БД, по мере тестирования кода. Фича которую ты разработал может на пару недель застрять в тестировании, а фича которую ты делал на этой неделе уже будет раскатана сегодня, и когда завтра из тестирования выйдет первая фича и будет накатываться на прод, могут возникнуть проблемы
Ок, предлагаю вам решение этих проблем при которых не придется применять ваши правила, останутся стантартные, всем понятные, миграции от ларавел и вышеобозначенных проблем не будет — git-flow + capistrano/deployer/ansible в общем все чтоб автоматизировать деплой
В git-flow создаете новую фичу, в ней работает бекендщик, есть миграции, так же делает свои правки фронтендщик
Если нужно продемонстрировать — деплоером раскатываете на драфте изменения из нужной ветки
нужно откатить — откатываете и свежие миграции вместе с переключением на старый релиз.
Если несколько модулей будут создавать одинаковые колонки/таблицы — миграции и должны падать т.к. это конфликт
Если нужно проверить что приложение все еще корректно работает с новыми колонками — пишите тесты, как на фронтенд так и на бекенд
Итого получается что когда все правки сделаны и проверены фича финишируется, в дев ветку попадают ее миграции и далее уже тесты покажут а все ли хорошо, после чего это уже попадет в релиз. На выходе в миграциях будет корректная история изменений версий, не придется вставлять костыли, патчить таблицу с примененными миграциями, оставлять кучу неиспользуемых колонок
git-flow из примера не обязательно должна быть одноименная утилита, а похожая модель ветвления
Добрый день,
У меня два вопроса:
- Зачем так странно доставать билдер когда есть фасад Schema?
- Что такое DataModel? Если это ваша реальная модель (Eloquent), то вполне логичный вопрос: зачем вы модели используете в миграциях. Модель вещь переменная, сначала вы добавили таблицу, а через три месяца удалили. В миграциях кож последовательный, таблица должна быть добавлена и потом быть удалена. И на момент когда вы с нуля катите миграции DataModel уже не будет. Или вы предлагаете рефачить 100500 миграция каждый раз когда удаляете таблицу и Model из проекта?
Code style для миграций Laravel