Должны ли мы использовать ограничения внешнего ключа при сохранении моделей предметной области?

StackOverflow https://stackoverflow.com/questions/1076369

Вопрос

Некоторое время назад я обсуждал с моими коллегами вопрос о сохранении Доменные модели и следует ли нам применять ограничения внешнего ключа на уровне базы данных.

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

Вот мой вопрос (надеюсь, он не слишком общий):считается ли хорошей практикой обеспечение соблюдения ключевых ограничений в этих случаях?

Это было полезно?

Решение

Применяйте ограничения, но НЕ полагайтесь на них в своих бизнес-логика

  • Нет бизнес логика в базе данных:Я согласен с принципом.И если ваш не-SQL бизнес-код полагается ограничений базы данных, чтобы проверить целостность вашей базы данных, вам следует переосмыслить свою бизнес-логику.
  • Нет ничего плохого в наличии ограничений базы данных кроме того в вашу бизнес-логику.Тем более, что такие вещи, как ссылочная целостность с FOREIGN KEYs и другие ограничения UNIQUE, легко реализовать, и СУБД выполняет эту работу за вас очень эффективно и без особого обслуживания.
  • Вы не будете использовать индексы в базе данных тоже, потому что ее нет чисто связано с настойчивостью?
  • Поиск и исправление ошибок в программном обеспечении может занять некоторое время, но вы определенно не хотите тратить еще больше времени на очистку или (что еще хуже) потерю некоторых данных только потому, что вы избавили себя от необходимости писать однострочный скрипт для FK.Действительно:Вы получаете здесь что-то бесплатно и отказываетесь от этого?
  • [РЕДАКТИРОВАНИЕ-1]: Можете ли вы гарантировать, что данные в вашей базе данных будут управляться ТОЛЬКО через ваше приложение?Кажется, всегда есть исключения, в основном со стороны опытных пользователей, которые иногда (очень редко :-) делают ошибки и выполняют некоторые операторы SQL для очистки вашего кода, обновления статусов (до недопустимых значений из-за опечаток) и т. д.
  • [РЕДАКТИРОВАНИЕ-2]: Здание управляемый доменом Модель не является оправданием того, чтобы не нанимать хорошего администратора БД.Использование ORM — не повод не нанимать хорошего разработчика БД.

Но если вы и ваша команда умеете писать программное обеспечение без ошибок и обработать все возможные сценарии исключений в вашем коде (включая сбои оборудования/сети/фиктивного пользователя/ошибки программиста), а затем: «Эй, зачем беспокоиться о избыточный Ограничения ФК...." - -тизер-

Другие советы

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

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

Мне кажется, что игнорирование действительно полезных инструментов (целостность данных на уровне базы данных) ради чистой методологии разработки контрпродуктивно.Базы данных ДЕЙСТВИТЕЛЬНО хороши в подобных вещах... пусть они это делают.

В какой-то момент любая методология начинает давать сбой, и вам просто нужно быть практичным.

Раньше я так думал, но мое мнение изменилось с тех пор, как я начал писать много ресурсоориентированных систем.Как правило, для проверки части данных требуется гораздо больше, чем просто ограничения внешнего ключа — например, билет, имеющий статус «назначено», должен иметь допустимое значение «assigned_to» и так далее.Все эти правила должны быть помещены в какую-то процедуру проверки, и хотя теоретически это может и не произойти. повредить Чтобы иметь дополнительную проверку на уровне базы данных, если ваша проверка на уровне приложения работает, проверка ограничения внешнего ключа — это просто пустая трата циклов.Но гораздо хуже то, что теперь логика вашей модели данных повторяется в двух местах — коде проверки и ограничениях базы данных.

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

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

Да, ну, увы, в таких дебатах посредственное большинство всегда побеждает просто за счет численности.

Если вы все еще хотите вести эту битву, вы можете спросить своих оппонентов, как они собираются удержать кого-либо от использования «прямых редакторов баз данных» (аля db2-aid, spufi, ...) и как они намерены удержать кого-либо от повреждения базы данных. используя такие инструменты (которые по определению обходят запрограммированные бизнес-ограничения).

Если вы хотите следовать парадигме доменно-ориентированного проектирования, то ответом будет «да» для всего внутри агрегата и «нет» для любых межагрегатных связей.

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

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

Надеюсь, это поможет!А для получения дополнительной информации обязательно посетите Книга Эванса о проектировании, управляемом предметной областью. - и множество ссылок в сети.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top