Перенос Laravel с возможностью обнуления на основе другого столбца

#database #laravel #laravel-migrations

#База данных #ларавель #laravel-миграции

Вопрос:

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

Например:

 If    User.owns_cat === true  
Then  User.cat_name->nullable(false)
 

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

Комментарии:

1. Не должно иметь значения, какое содержимое находится в одной из строк для этого столбца, весь столбец будет nullable или нет nullable . Вам придется обрабатывать позже, либо с помощью триггера DB (или чего-то подобного), либо с помощью requried_with проверки Laravel.

2. Ах, триггеры. Вероятно, это то, что я ищу. Спасибо!

3. Нет проблем! Я думаю , это то, что вы ищете, но я не могу сказать, что мне когда-либо приходилось заставлять это условие на уровне БД. Если вам удастся найти решение, не стесняйтесь публиковать самостоятельный ответ или обновлять свой вопрос, если у вас возникнут какие-либо дополнительные проблемы. Приветствия!

4. @TimLewis Являются ли триггеры такими же, как события Eloquent?

5. @TimLewis Ах, хорошо … спасибо.

Ответ №1:

Что вам действительно нужно, так это поддержка условных функциональных зависимостей и правил ассоциации.

Правила ассоциации (AR)

c => f(A)

где c — логически определяемое значение, которое, если выполнено, то набор столбцов A заполнит что-то, где

A = (A1, A2, …, An)

Условные функциональные зависимости (CFD)

c => A -> B

где c — логически определяемое значение, которое, если выполнено, тогда набор столбцов A определяет значения набора столбцов B, где

A = (A1, A2, …, An)

и

B = (B1, B2, …, Bn)

Проблема

Системы СУБД, как правило, не поддерживают ARS или CFD из коробки, по крайней мере, так было в прошлый раз, когда я проверял. Итак, поскольку базовая система, вероятно, не поддерживает нужную вам функцию, миграции Laravel, вероятно, также не достигнут этого.

Решения

Проблема с определением схемы на основе кода приложения заключается в том, что эта задача не совсем правильно выполняется на уровне ORM стека технологий, поскольку:

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

Итак, что вы можете сделать:

  • вы можете реализовать функциональность на уровне приложения, которая проверяет некоторое условие, которое, если выполняется, приводит к соблюдению правила, то есть, если правило должно быть нарушено, то либо выдает ошибку, либо устанавливает значение по умолчанию, а если правила выполняются, то вызывает set
  • вы можете реализовать триггер в базе данных, который перед вставкой / обновлением будет проверять и применять необходимые вам правила
  • решение схемы
  • периодически выполняемое исправление данных

Триггер

Вы бы создали триггер, который проверял бы значение column2 и, если ваше условие выполнено, проверял, будет ли column1 иметь значение null. Если это так, то вы можете выбрать выдачу ошибки или установить значение по умолчанию.

Преимущество: согласованность ваших данных будет поддерживаться, даже если операции записи выполняются вне вашего приложения.

Недостаток: это будет довольно сложно поддерживать, если правила будут часто меняться, и это не будет иметь доступа к вашим ресурсам уровня приложения.

Является ли этот подход идеальным для вас, зависит от ваших потребностей.

Решение схемы

Итак, если c1 имеет некоторое значение, то c2 не обнуляется. Вы можете переместить c1 в другую таблицу и сделать c2 внешним ключом. Если ваше условие для c1 выполнено, убедитесь, что c2 является правильным внешним ключом к новой таблице, которая содержит c1.

Преимущество: вы используете только ресурсы, которые СУБД предоставляет вам из коробки

Недостаток: этот подход противоречит интуиции, если ваше условие для c2 является сложным

Применимость этого подхода зависит от сложности вашего состояния.

Периодически выполняемое исправление данных

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

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

Недостатки: вы не можете полагаться на то, что ваши правила применяются к каждой записи в каждый момент.

Это применимо, если вы не беспокоитесь о том, что ваше правило временно нарушается, если оно довольно быстро становится правильным.

Поддержка на уровне приложения

Вы можете реализовать класс, который имеет метод set . Этот метод set получит объект и функцию, которая возвращает логическое значение. Если функция возвращает true, то вызовите set . В противном случае либо создайте исключение, либо установите значение по умолчанию.

Комментарии:

1. Спасибо за подробное объяснение!