Я помню, как Джоэл Спольски упоминал в подкаст 014, что он почти никогда не использовал внешний ключ (если я правильно помню). Однако мне они кажутся очень важными, чтобы избежать дублирования и последующих проблем целостности данных в вашей базе данных.
Есть ли у людей веские причины, почему (чтобы избежать обсуждения принципов Stack Overflow)?
Редактировать:«У меня еще не было причин для создания внешнего ключа, так что это может быть моей первой причиной для его создания».
Не могли бы вы указать, где именно он это сказал, чтобы мы могли понять контекст? Стенограммы подкастов доступны здесь stackoverflow.fogbugz.com/default.asp?W4
У FogBugz есть внешние ключи (вроде), они просто не делают их формально связанными в базе данных. Если вы посмотрите на схему, вы увидите поля FK с именами, которые соответствуют полям PK в других таблицах. Все это просто поддерживается кодом. Меня чертовски беспокоит, но вроде работает нормально.
@romantika - также смотрите мои комментарии ниже относительно базы данных Clarify
Я не думаю, что Джоэл не использует FK, просто он не заставляет базу данных применять их. По логике, они все еще ФК!
@Daren: Смотри цитату выше, он в значительной степени говорит, что, по крайней мере, не делает !!
Он говорит, что не использует внешние ключи, но я согласен с Дареном в том, что он имеет в виду, что он не использует ОГРАНИЧЕНИЯ внешнего ключа. Столбец в одной таблице, значения которого должны быть взяты из первичного / уникального ключа другой таблицы, ЯВЛЯЕТСЯ внешними ключами, независимо от того, добавляете ли вы ограничение или нет.
... Как правило, глупо не добавлять ограничение: оно ОБЕСПЕЧИВАЕТ целостность в любое время, даже если есть ошибка в коде приложения или если вы работаете за кулисами, выполняя «исправление» данных.
+1 За комментарий Тони. Слишком много путаницы между этой функцией и логической концепцией внешних ключей.
Это дубликат: http://stackoverflow.com/questions/18717/are-foreign-keys-re ally-required-in-a- дизайн-базы данных # 1873 0
@TonyAndrews: Исходя из этого, вам также не нужно настраивать ПЕРВИЧНЫЙ КЛЮЧ, если код вашего приложения гарантирует, что все записи уникальны. Извините, но это чушь. Ограничения позволяют базе данных сохранять согласованность данных все само по себе, поэтому я не понимаю, почему вы не захотите использовать это.
@DanMan, не знаю, откуда у вас такое впечатление, я так думаю. На самом деле я сказал выше: «Как правило, глупо не добавлять ограничение: оно ОБЕСПЕЧИВАЕТ целостность во все времена».
Я имел в виду комментарий выше. Если вы не определять это как FKC, то это действительно не из точки зрения БД. (Ужасно много аббревиатур). Просто говорю.
У меня один вопрос: на кого возложена ужасная задача расшифровывать эти подкасты?
Многие люди создают внешние ключи, но просто не объявляют их. Интересно, имеет ли это в виду Джоэл Спольски.
Внешний ключ - это ограничение. Интерпретация некоторого столбца как ссылки на первичный ключ некоторой таблицы сама по себе не является внешним ключом, точно так же, как интерпретация числового столбца как счетчика не делает его последовательностью.
Ограничение внешнего ключа - это ограничение. Внешний ключ - это просто копия данных ключа в каком-то другом месте, используемая в качестве ссылки по ключу на исходный кортеж. Ссылка обычно относится к первичному ключу. У вас будут внешние ключи в вашей реляционной модели данных, даже если они не объявлены как таковые в окончательной реализации.
Дубликат Действительно ли внешние ключи необходимы при проектировании базы данных?

Нет никаких причин хороший, чтобы нет их использовал ... если только потерянные строки не имеют для вас большого значения, я думаю.
Почему бесхозные ссоры имеют большое значение?
А как насчет многопоточности? В определенных ситуациях они могут вызвать кошмар многопоточности. В сложном приложении с несколькими потоками, записывающими базу данных, которые могут сталкиваться с объектами, которым необходимо ссылаться друг на друга, лучше контролировать ссылочную целостность в бизнес-логике, особенно если впоследствии таблицы станут статическими.
Я согласен. Кроме того, я предпочитаю иметь строки ophan, которые я могу восстановить позже, чем безжалостно отбрасывать их.
Внешние ключи - это существенный для любой модели реляционной базы данных.
Модель, да. Реализация, не принципиальная, просто, вероятно, полезная.
Извините, но основная причина, по которой разработчики приложений не используют системы управления объектными базами данных (также известные как базы данных NoSQL!) Более широко, заключается в инвестициях в СУБД. В большинстве случаев база данных (а не система управления базами данных) представляет собой объектную модель среднего уровня, часто включающую распределенные кеши. Здесь в любом случае должны происходить каскадное удаление, владение и синхронизация изменений. РСУБД используется в первую очередь для сохранения этой объектной модели и обычно после кропотливого и практически бесполезного упражнения ORM. В большинстве случаев модели отношений не нужны!
нет, внешние ключи не обязательно указывать "реляционные"
На самом деле это мало что объясняет.
Мне всегда казалось ленивым не использовать их. Меня учили, что это нужно делать всегда. Но тогда я не стал слушать обсуждение Джоэла. У него могла быть веская причина, я не знаю.
Это было скорее неожиданное замечание, чем дискуссия, хотя, возможно, мне следовало бы выяснить, что он думает по этому поводу, независимо от того, что он думает! Однако мне было интересно узнать мнение сообщества по этой теме!
Они могут сделать удаление записей более обременительным - вы не можете удалить «основную» запись, если есть записи в других таблицах, где внешние ключи нарушили бы это ограничение. Вы можете использовать триггеры для каскадного удаления.
Если вы выбрали свой первичный ключ неразумно, то изменение этого значения станет еще более сложным. Например, если у меня есть PK моей таблицы «customers» в качестве имени человека, и я сделаю этот ключ FK в таблице «orders», если клиент хочет изменить свое имя, тогда это королевская боль .. ... но это просто дрянной дизайн базы данных.
Я считаю, что преимущества использования огненных клавиш перевешивают любые предполагаемые недостатки.
Я все равно редко удаляю вещи. Просто отметьте наличие бита «Видимый / активный».
+1 за «Я считаю, что преимущества использования внешних ключей перевешивают любые предполагаемые недостатки»
Вы никогда, никогда не изменять значение первичного ключа. Вы Удалить целую строку и воссоздать по-другому. Если вы думаете, что вам нужно изменять, ваша схема ошибочна.
Изменение имени клиента не будет проблемой, ЕСЛИ ваш внешний ключ установлен на CustomerId (PK). в таблице заказов. Единственный способ, которым это было бы неприятно, - это если бы FK был установлен на CustomerName, чего никогда не должно быть. ИМХО
Я слышал аргумент, что интерфейс должен иметь эти бизнес-правила. Внешние ключи «добавляют ненужные накладные расходы», когда вы не должны допускать никаких вставок, которые в первую очередь нарушают ваши ограничения. Я согласен с этим? Нет, но это то, что я всегда слышал.
Обновлено: Я предполагаю, что он имел в виду ограничения внешнего ключа, а не внешние ключи как концепцию.
Неа. Он не любит настоящие ключи!
Это меня поражает. Есть большая разница между тем, чтобы не любить ограничения внешнего ключа и не любить внешние ключи. Я не уверен, как у вас есть реляционная база данных без них.
Да, я был шокирован, когда услышал его. Однако он мог непреднамеренно иронизировать; возможно он разместит здесь и прояснит на каком-то этапе :-)
Я вижу несколько причин использовать внешние ключи (осиротевшие строки, как кто-то упомянул, раздражают), но я их тоже никогда не использую. При относительно разумной схеме БД я не думаю, что они на 100% нужны. Ограничения - это хорошо, но я думаю, что применение их с помощью программного обеспечения - лучший метод.
Алекс
Применение внешних ключей с помощью программного обеспечения непросто из-за проблем с множественным параллелизмом. Что делать, если пользователь A удаляет родительский элемент, в то время как пользователь B вставляет дочерние элементы?
Что, если я обновлю данные вручную? Что делать, если в коде есть ошибка? Вы высказали свое мнение, но даже не пытались его подтвердить. -1
Я согласен с предыдущими ответами в том, что они полезны для обеспечения согласованности данных. Однако несколько недель назад был интересный пост Джеффа Этвуда, в котором обсуждались плюсы и минусы нормализованных и согласованных данных.
Короче говоря, денормализованная база данных может работать быстрее при обработке огромных объемов данных; и вы можете не заботиться о точной согласованности в зависимости от приложения, но это заставляет вас быть гораздо более осторожными при работе с данными, поскольку БД не будет.
Джефф делает несколько хороших замечаний. Однако Дэн Чак в «Enterprise Rails» показывает способ создания кеш-таблиц, которые по сути являются ненормализованной копией данных. Запросы выполняются быстро, и если таблицу не нужно обновлять, она работает хорошо. Я считаю, что если ваши данные определяют поведение (например, состояние приложения) вашего приложения, вам нужно, чтобы данные были максимально нормализованы, потому что в противном случае несогласованные данные приводят к несогласованному поведению приложения.
Денормализованные данные склад могут использоваться, когда чтение большие объемы данных на согласованных, ожидаемых путях доступа. Во всех остальных случаях это опасное заблуждение.
Есть одна веская причина не использовать их: Если вы не понимаете их роль или как их использовать.
В неправильных ситуациях ограничения внешнего ключа могут привести к каскадной репликации аварий. Если кто-то удалит неправильную запись, отмена ее может стать гигантской задачей.
И наоборот, когда вам нужно что-то удалить, если плохо спроектировано, ограничения могут вызвать всевозможные блокировки, которые вам мешают.
Удаление строки в производственной среде без резервного копирования не является допустимым аргументом. Если вы их не понимаете, вам следует подумать о том, чтобы узнать об этом, а не пропускать.
@Guillaume Я думаю, что его ответ был немного саркастическим, не следует понимать буквально: если вы их не понимаете, не используйте их. Но, конечно, вы должен понимаете и используете их.
^ Это. Это полезные инструменты, но в руках новичка они опасны.
Проверка ограничений внешнего ключа требует некоторого времени ЦП, поэтому некоторые люди опускают внешние ключи, чтобы получить дополнительную производительность.
Сколько процессорного времени тратится на удаление повторяющихся и противоречивых данных?
Да, это правда. В системе, над которой я работаю, мы должны вставлять 10-40 гигабайт данных за раз в базу данных, и производительность FK с и без нее видна в общем затраченном времени.
База данных Clarify - это пример коммерческой базы данных, у которой нет первичных или внешних ключей.
http://www.geekinterview.com/question_details/18869
Забавно то, что техническая документация очень подробно объясняет, как связаны таблицы, какие столбцы использовать для их соединения и т. д.
Другими словами, они мог присоединились к таблицам с явными объявлениями (DRI), но они решил не.
Следовательно, база данных Clarify полна несоответствий и работает недостаточно эффективно.
Но я полагаю, это облегчило работу разработчиков, поскольку им не приходилось писать код для работы с ссылочной целостностью, такой как проверка связанных строк перед удалением, добавлением.
И это, я думаю, главное преимущество отсутствия ограничений внешнего ключа в реляционной базе данных. Это облегчает разработку, по крайней мере, с наплевательской точки зрения.
Код для обработки неудачной проверки ссылочной целостности намного меньше кода для обработки несогласованных данных.
@Jay согласен! Не думайте, что я защищаю этот подход.
@imphasing - именно такой образ мышления вызывает кошмары при обслуживании.
Почему, ну, почему вы игнорируете декларативную ссылочную целостность, где данные могут быть гарантированный, по крайней мере, согласованными, в пользу так называемого «программного обеспечения», которое в лучшем случае является слабой превентивной мерой.
Потому что разработчики никогда не решали проблему, требующую нетривиальной, нормализованной реляционной модели. Многие проблемы этого не делают, особенно те, которые изобилуют в программировании в Интернете / социальных сетях, которое сегодня является повальным увлечением. Если все, что выходит из задней части ORM-фреймворка, решает проблему в альфа-версии, вряд ли кто-то будет больше задумываться о моделировании данных. Многие такие проблемы так же легко решаются хранилищами K / V, базами данных документов или прямой сериализацией объектов.
Я уверен, что есть множество приложений, в которых это может сойти с рук, но это не лучшая идея. Вы не всегда можете рассчитывать на то, что ваше приложение правильно управляет вашей базой данных, и, откровенно говоря, управление базой данных не должно сильно беспокоить ваше приложение.
Если вы используете базу данных реляционный, то кажется, что вам нужно определить в ней некоторый отношения. К сожалению, такое отношение (вам не нужны внешние ключи), похоже, разделяют многие разработчики приложений, которые предпочли бы не беспокоиться о таких глупых вещах, как целостность данных (но это необходимо, потому что в их компаниях нет специальных разработчиков баз данных). Обычно в базах данных, собранных по этим типам, везет только с первичными ключами;)
Я действительно не встречаю людей, у которых нет FK в своей базе данных. В прошлый раз, когда я работал с кем-то, у кого его не было, он сказал: «Нет, мы применяем это в приложении». За исключением того, что я изучил все клиентские базы данных и обнаружил, что у большинства из них есть сироты ...
Обычно это так. Я думаю, вы могли бы обойтись без принудительного применения ТОЛЬКО в базе данных (если ваши пользователи не возражают против исключений во время выполнения), но иметь и то и другое - это действительно единственный способ.
Все дело в стенограммах / ответ Этвуда «Этвуд: ... на основе внешних ключей, которые вы установили в индексах, они выясняют это ... Спольски: [смеется] Предполагая, что вы это сделаете. Этвуд: Ну, при условии, что вы правильно настроили свою базу данных ... "
База данных называется реляционный не из-за отношения между таблицами (КАЖДЫЙ вид базы данных имеет какие-то связи между сущностями!), А потому, что сами таблицы связи в математических терминах. См. Википедия.
Я тоже слышал этот аргумент - от людей, которые забыли поставить индекс на свои внешние ключи, а затем жаловались, что некоторые операции выполняются медленно (потому что проверка ограничений может использовать любой индекс). Итак, подведем итоги: нет веских причин не использовать внешние ключи. Все современные базы данных поддерживают каскадное удаление, поэтому ...
Я считаю, что настоящая причина, по которой ограничения FK не используются некоторыми (большинством, с моей точки зрения), - это явная лень под предлогом того, что они могут защитить свою лень с помощью аргумента об экономии производительности. Я твердо верю, что подавляющее большинство расходов на глупость, которые несет наша компания, происходит из-за недостаточного соблюдения ограничений FK и волнового эффекта, который это имеет через компанию. Отсутствие уникальных ключей - это еще одна вещь, которая сводит меня с ума по сравнению с 2000+ строковыми хранимыми процедурами с 12 уровнями вложенных IF и случайным отступом, но я остановлюсь сейчас.
Я всегда ими пользуюсь, но потом делаю базы данных для финансовых систем. База данных - важная часть приложения. Если данные в финансовой базе данных не совсем точны, то на самом деле не имеет значения, сколько усилий вы вложили в свой код / дизайн интерфейса. Вы просто зря теряете время.
Также существует тот факт, что несколько систем обычно должны напрямую взаимодействовать с базой данных - от других систем, которые просто считывают данные (Crystal Reports), до систем, которые вставляют данные (не обязательно с использованием разработанного мной API; он может быть написан тупой менеджер, который только что открыл для себя VBScript и имеет пароль SA для SQL-бокса). Если база данных не настолько защищена от идиотов, насколько это возможно, ну - пока, база данных.
Если ваши данные важны, то да, используйте внешние ключи, создайте набор хранимых процедур для взаимодействия с данными и сделайте БД как можно сложнее. Если ваши данные не важны, зачем вы для начала создаете базу данных?
Хорошее понимание. Я бы сказал, что данные так важны для каждого приложения, которое действительно используется. Единственное, что отличается, - это последствия поврежденных данных. Они высоки для вашего типа приложений ...
Причины использования внешних ключей:
Причины не использовать внешние ключи:
Я думаю (я не уверен!), Что большинство установленных баз данных предоставляют способ указать внешний ключ, который не применяется принудительно, а представляет собой просто бит метаданных. Поскольку неисполнение требований устраняет все причины не использовать FK, вам, вероятно, следует пойти по этому пути, если применима какая-либо из причин, указанных во втором разделе.
Хороший список! DBM не проверяет согласованность R-части CRUD, поэтому я бы исключил эту часть. Кроме того, это, вероятно, промывка, потому что в вашем приложении вы делаете то же самое, что и СУБД: вы проверяете и убедитесь, что родительский идентификатор действителен до CRD, и это на самом деле медленнее, чем при использовании DBM!
Хороший момент, Мэтт, но что касается того, что делает БД в вашем приложении - вам, вероятно, не следует этого делать, если это делает БД. Либо вы доверяете БД и используете ее правильно, либо она быстро превращается в хранилище «ключ-значение». Если вам нужны хранилища ключей и значений, есть варианты получше :-).
Что, если кто-то удалит родительский элемент, пока вы вставляете дочерние элементы? Прямо сейчас, когда я отправляю «добавить комментарий» - если вы уже удалили свой ответ, этот комментарий теперь сирота. ФК помешали бы этому. Кроме того, я мог бы просто изменить parentID на все, что захочу. Кому-то нужно проверить. :)
Точнее, это должна быть работа БД, поскольку она единственная, которая может гарантировать транзакционность перед лицом нескольких одновременных клиентов.
О, я думал, вы утверждаете, что НИКОМУ НЕ нужно проверять, я неправильно прочитал ваш комментарий !! Ты прав :)
Остерегайтесь ситуаций "каскадного удаления" - он может работать медленно в больших базах данных.
Хорошо продуманный ответ! Мне было интересно - что может быть лучше хранилища ключей и значений для 500 миллионов записей, к которым могут получить доступ одновременные пользователи, чем база данных?
Дэвид Б. - ознакомьтесь с BerkeleyDB (все еще бесплатно, но теперь принадлежит Oracle)
+1 Отличный ответ - вторая причина не использовать ограничения FK может быть сочтена «затрудняет нарушение согласованности», что на самом деле звучит как хороший!
Еще одна причина в пользу внешних ключей заключается в том, что в большинстве реализаций СУБД объявление внешнего ключа неявно создает индекс для столбца (столбцов), который с наибольшей вероятностью получит выгоду от индекса.
База данных для OLTP-систем - это метод сохранения данных приложения. Единственная причина, по которой существуют базы данных, заключается в том, что данные приложения работают с энергозависимой памятью. Если ваш распределенный кеш, например, работал в быстрой энергонезависимой памяти, что становится экономической реальностью, или работал в оперативной памяти, поддерживаемой ИБП на HD, то база данных не нужна. Моделирование объектов и, следовательно, различие между агрегацией и композицией (и, следовательно, каскадное удаление) должно полностью зависеть от логики приложения и перемещаться в базу данных только по причинам производительности или оптимизации дизайна.
Проверка согласованности FK очень часто является очень быстрой операцией, так как это поиск по индексу. Это справедливо даже в тех случаях, когда у вас много «оттока», поскольку в таких ситуациях индексы, скорее всего, будут в памяти. Случаи, когда проверки FK могут иметь заметное влияние, - это вкладыши для больших партий; Фактически, основные базы данных также предлагают варианты пакетной проверки FK.
У вас есть огромный набор данных в таблице, и он находится в действующей системе, которая не может выйти из строя, а внесение изменений в схему заблокировало бы таблицу на слишком долгое время. Таким образом, вы копируете данные в новую таблицу, меняете там схему, а затем вместо этого выполняете атомарное переименование таблицы (original_table -> original_table_old, new_table -> original_table). FK значительно усложняют весь этот процесс (поскольку FK из подтаблиц перемещаются во время переименования, чтобы ссылаться на original_table_old), вам нужно удалить и воссоздать их, а это само по себе требует времени, в течение которого вы можете получить потерянные данные.
Или, по крайней мере, это оправдание, когда люди говорят мне, почему в их таблицах нет FK для непосредственно связанных подтаблиц, и почему у них есть задачи по очистке этих подтаблиц все время.
Спасибо @JeeBee за то, что подняли этот вопрос. Никто не занимался восстановлением резервных копий, перемещением баз данных, репликацией, модификациями схемы в действующей базе данных, массовой перезагрузкой некоторых таблиц и другими повседневными 5-миллионными вещами, которые FK превращают в дневное испытание или даже требуют написания кода. сценарий .. Буква F в FK становится другим словом .. Никто не безрассуден с данными .. степень свободы соответствует повышенному риску. Вот и все. Бремя согласованности перенесено на уровень приложения.
Я не люблю ФК. За поддержку и свободу, упомянутую в других комментариях, но по многим другим причинам. Моя причина номер один в том, что я использую его в восстановительных целях. Например, у меня есть несколько таблиц, которые имеют дело с клиентами (по типу идентификатора). Если я удалю запись из основной клиентской таблицы, она эффективно удалит весь доступ к этим записям клиентов (приложение не знает, что она существует), это позволяет мне очень ЛЕГКО восстановить ошибку, воссоздав одну запись (а не сотни). У меня есть фоновые процессы, которые со временем удалят данные (и сделают резервную копию). Я предпочитаю уровень API приложению
На мой взгляд, преимущества использования внешних ключей FAR перевешивают любые преимущества их неиспользования.
Мне намного проще настроить тест без внешних ключей.
Единственное, на что следует обратить внимание, это на больших системах, которые мы используем, мы НИКОГДА не настраиваем каскадное удаление. Наши удаления выполняются с помощью сценариев обслуживания, которые удаляют детей раньше родителей. На создание пакетных задач уходит немного больше времени, но оно того стоит для целостности базы данных. Я всегда использую FK для оптимизации и проверки целостности данных. Но проблемы с пакетным удалением / обслуживанием иногда возникают у нашего администратора баз данных, потому что это может причинить им неудобства.
@Sentinel Ваш образ мышления отлично работает, когда отношение между данными и приложением составляет 1: 1. Во многих организациях база данных является центральной, и приложения исходят из нее, как спицы в колесе. Со временем эти приложения часто пишутся на разных языках с использованием разных технологий. «Центральные» базы данных очень часто намного дольше тех приложений, которые к ним обращаются.
Я бы сказал, что в 99% случаев внешние ключи имеют смысл. Но у меня есть некоторые данные, которые меня особо не волнуют, но их много (крошечные фрагменты). Я хочу, чтобы CRUD был действительно быстрым с минимальной вероятностью отказа. Меня не волнуют потерянные записи, потому что данные имеют срок годности и в конечном итоге уничтожаются. Я не использую FK на этом столе. Нет никакой пользы.
Вот и мы десять лет спустя. Причина не использовать FK кажется выигрышной. В каждой компании, в которую я хожу, они запрещены.
Еще один недостаток FK, возможно, специфический для MySQL: он затрудняет выполнение изменений схемы онлайн, которые копируют данные в «теневую таблицу», а затем меняют новую таблицу на старую.
Один раз, когда FK может вызвать у вас проблему, это когда у вас есть исторические данные, которые ссылаются на ключ (в таблице поиска), даже если вам больше не нужен ключ.
Очевидно, решение состоит в том, чтобы лучше спроектировать вещи заранее, но я думаю о реальных ситуациях, когда вы не всегда можете полностью контролировать решение.
Например: возможно, у вас есть справочная таблица customer_type, в которой перечислены разные типы клиентов - допустим, вам нужно удалить определенный тип клиентов, но (из-за ограничений бизнеса) не можете обновить клиентское программное обеспечение, и никто не заметил этого. В ситуации при разработке программного обеспечения тот факт, что это внешний ключ в какой-либо другой таблице, может помешать вам удалить строку, даже если вы знаете исторические данные, которые ссылаются на нее, не имеет значения.
После того, как вы несколько раз обожглись этим, вы, вероятно, отказываетесь от обеспечения отношений между базами данных.
(Я не говорю, что это хорошо - просто указываю причину, по которой вы можете решить избегать ограничений FK и db в целом)
Если я понимаю, что вы пытаетесь сказать, я думаю, что моим ответом на это будет логическое удаление записи в таблице поиска или архивирование более не релевантных исторических данных, а также архивирование записи поиска.
«Они могут сделать удаление записей более обременительным - вы не можете удалить« основную »запись, если есть записи в других таблицах, где внешние ключи нарушили бы это ограничение».
Важно помнить, что стандарт SQL определяет действия, предпринимаемые при удалении или обновлении внешнего ключа. Я знаю следующие:
ON DELETE RESTRICT - предотвращает удаление любых строк в другой таблице, которые имеют ключи в этом столбце. Это то, что Кен Рэй описал выше.ON DELETE CASCADE - Если строка в другой таблице удалена, удалите все строки в этой таблице, которые ссылаются на нее.ON DELETE SET DEFAULT - Если строка в другой таблице удалена, установите для всех внешних ключей, ссылающихся на нее, значение по умолчанию для столбца.ON DELETE SET NULL - Если строка в другой таблице удалена, установите для всех внешних ключей, ссылающихся на нее в этой таблице, значение NULL.ON DELETE NO ACTION - этот внешний ключ только отмечает, что это внешний ключ; а именно для использования в картографах OR.Эти же действия применимы и к ON UPDATE.
По-видимому, значение по умолчанию зависит от того, какой сервер sql вы используете.
Для меня, если вы хотите следовать стандартам КИСЛОТА, критически важно иметь внешние ключи для обеспечения ссылочной целостности.
Я должен поддержать большинство комментариев здесь. Внешние ключи являются необходимыми элементами для обеспечения целостности ваших данных. Различные варианты ON DELETE и ON UPDATE позволят вам обойти некоторые из «падений», которые люди упоминают здесь относительно их использования.
Я обнаружил, что в 99% всех моих проектов у меня будут FK для обеспечения целостности данных, однако есть те редкие случаи, когда у меня есть клиенты, которые ДОЛЖНЫ хранить свои старые данные, независимо от того, насколько они плохи ... но потом я трачу много времени на написание кода, который в любом случае нужен только для получения достоверных данных, так что это становится бессмысленным.
Дополнительная причина использования внешних ключей: - Позволяет повторно использовать базу данных
Дополнительная причина НЕ использовать внешние ключи: - Вы пытаетесь привязать клиента к своему инструменту за счет сокращения повторного использования.
Как насчет ремонтопригодности и постоянства жизненных циклов приложений? Большинство данных имеют более длительный срок службы, чем приложения, которые их используют. Взаимосвязи и целостность данных слишком важны, чтобы оставлять надежду, что следующая команда разработчиков исправит это в коде приложения. Если вы не работали с БД с грязными данными, которые не соблюдают естественные отношения, вы это сделаете. Тогда станет ясно, насколько важна целостность данных.
Я повторю то, что сказал Дмитрий, но добавлю по пункту.
Я работал над системой пакетного биллинга, которая должна была вставлять большие наборы строк в более чем 30 таблиц. Нам не разрешили делать перекачку данных (Oracle), поэтому нам пришлось выполнять массовую вставку. У этих таблиц были внешние ключи, но мы уже убедились, что они не нарушают никаких отношений.
Перед вставкой мы отключаем ограничения внешнего ключа, чтобы Oracle не занимал вставки вечно. После успешной вставки мы снова включаем ограничения.
PS: В большой базе данных со многими внешними ключами и данными дочерних строк для одной записи иногда внешние ключи могут быть плохими, и вы можете запретить каскадное удаление. Для нас, работающих в биллинговой системе, если бы мы выполняли каскадное удаление, это заняло бы слишком много времени и обременило бы базу данных, поэтому мы просто помечаем запись как плохую с помощью поля в основной (родительской) таблице драйвера.
Я также считаю, что внешние ключи необходимы в большинстве баз данных. Единственный недостаток (помимо снижения производительности, связанного с принудительной согласованностью) заключается в том, что наличие внешнего ключа позволяет людям писать код, предполагающий наличие функционального внешнего ключа. Этого нельзя допускать.
Например, я видел, как люди пишут код, который вставляется в ссылочную таблицу, а затем пытается вставить в ссылочную таблицу, не проверяя, что первая вставка была успешной. Если внешний ключ будет удален позже, это приведет к несогласованности базы данных.
У вас также нет возможности предполагать определенное поведение при обновлении или удалении. Вам все равно нужно написать свой код, чтобы делать то, что вы хотите, независимо от наличия внешнего ключа. Если вы предполагаете, что удаления выполняются каскадом, а это не так, ваши удаления не удастся. Если вы предполагаете, что обновления ссылочных столбцов распространяются на ссылочные строки, а это не так, ваши обновления не будут выполнены. Для целей написания кода у вас также может не быть этих функций.
Если эти функции включены, ваш код все равно будет имитировать их, и вы немного потеряете производительность.
Итак, подведение итогов .... Внешние ключи необходимы, если вам нужна согласованная база данных. Никогда не следует предполагать, что внешние ключи присутствуют или работают в коде, который вы пишете.
Это вопрос воспитания. Если где-то в своей образовательной или профессиональной карьере вы тратили время на кормление и уход за базами данных (или тесно работали с талантливыми людьми, которые делали это), то фундаментальные принципы сущностей и отношений прочно укоренились в вашем мыслительном процессе. Среди этих рудиментов - как / когда / зачем указывать ключи в вашей базе данных (первичные, внешние и, возможно, альтернативные). Это вторая натура.
Если, однако, у вас не было такого полного или положительного опыта в прошлом с усилиями, связанными с РСУБД, то вы, вероятно, не сталкивались с такой информацией. Или, возможно, ваше прошлое включает в себя погружение в среду, которая громогласно противилась базам данных (например, «эти администраторы баз данных - идиоты - мы мало, мы выбрали несколько разработчиков кода java / C#, которые спасут положение»), и в этом случае вы можете быть решительно против к загадочным лепетам какого-то слабака, говорящего вам, что FK (и ограничения, которые они могут подразумевать) действительно важны, если вы просто прислушаетесь.
В детстве почти всех учили, что чистить зубы важно. Вы можете обойтись без этого? Конечно, но где-то в будущем у вас будет меньше зубов, чем если бы вы чистили зубы после каждого приема пищи. Если бы мамы и папы были достаточно ответственны, чтобы заниматься проектированием баз данных, а также гигиеной полости рта, мы бы не вели этого разговора. :-)
Я собираюсь использовать дистиллированный «внешние ключи - это как чистить зубы: давай, обходись без этого, но осторожно, когда улыбаешься».
Я лично считаю, что принципы РСУБД намного проще и более четко определены, чем принципы гигиены полости рта.
Через 10 лет я уверен, что поговорим об этом дизайне базы данных с моим сыном / дочерью, чтобы он / она не напортачили и не стали причиной следующего краха Уолл-стрит из-за проблемы с базой данных.
Повторяю ответ Дмитрия - очень хорошо сказано.
Для тех, кого беспокоят накладные расходы на производительность, часто вызываемые FK, есть способ (в Oracle) получить преимущество оптимизатора запросов от ограничения FK без накладных расходов на проверку ограничений во время вставки, удаления или обновления. То есть создать ограничение FK с атрибутами RELY DISABLE NOVALIDATE. Это означает, что оптимизатор запросов ПРЕДПОЛАГАЕТ, что ограничение было применено при построении запросов, но база данных фактически не применяет ограничение. Здесь вы должны быть очень осторожны, чтобы взять на себя ответственность при заполнении таблицы с ограничением FK, подобным этому, чтобы быть абсолютно уверенным, что в ваших столбцах FK нет данных, которые нарушают ограничение, как если бы вы это сделали, вы может получить ненадежные результаты из запросов, которые включают таблицу, для которой установлено это ограничение FK.
Я обычно использую эту стратегию для некоторых таблиц в моей схеме витрины данных, но не в моей интегрированной промежуточной схеме. Я убеждаюсь, что в таблицах, из которых я копирую данные, уже установлено такое же ограничение, или что подпрограмма ETL применяет это ограничение.
Как и многие другие вещи, это компромисс. Вопрос в том, где вы хотите выполнить работу по проверке целостности данных:
(1) использовать внешний ключ (единственная точка для настройки таблицы, функция уже реализована, протестирована, доказала свою работоспособность)
(2) оставьте это на усмотрение пользователей базы данных (возможно, несколько пользователей / приложений обновляют одни и те же таблицы, что означает больше потенциальных точек сбоя и повышенную сложность тестирования).
Для базы данных более эффективно выполнять (2), проще в обслуживании и с меньшим риском (1).
Аргумент эффективности переоценен. Правило №1 - целостность данных. Если производительность снижается из-за ограничений FK, измените его. Редко причина в этом.
Более важный вопрос: вы бы водили машину с завязанными глазами? Так будет, если вы создадите систему без ссылочных ограничений. Имейте в виду, что меняются бизнес-требования, изменяется дизайн приложения, соответствующие логические предположения в коде меняются, сама логика может быть подвергнута рефакторингу и т. д. В общем, ограничения в базах данных устанавливаются в соответствии с современными логическими предположениями, которые кажутся правильными для определенного набора логических утверждений и предположений.
На протяжении всего жизненного цикла приложения ссылочные проверки и проверки данных ограничивают сбор данных через приложение, особенно когда новые требования приводят к логическим изменениям приложения.
К теме этого списка - внешний ключ сам по себе не «улучшает производительность» и не «снижает производительность» значительно с точки зрения системы обработки транзакций в реальном времени. Однако существует совокупная стоимость проверки ограничений в «пакетной» системе с ВЫСОКИМ объемом. Итак, вот разница между процессом транзакции в реальном времени и пакетной транзакцией; пакетная обработка - когда совокупная стоимость последовательно обрабатываемого пакета, связанная с проверками ограничений, снижает производительность.
В хорошо спроектированной системе проверки согласованности данных должны выполняться «до» обработки пакета (тем не менее, здесь также связаны затраты); поэтому проверки ограничений внешнего ключа не требуются во время загрузки. Фактически, все ограничения, включая внешний ключ, должны быть временно отключены, пока пакет не будет обработан.
ЗАПРОС ПРОИЗВОДИТЕЛЬНОСТИ - если таблицы объединяются по внешним ключам, помните о том, что столбцы внешнего ключа НЕ ИНДЕКСИРУЮТСЯ (хотя соответствующий первичный ключ индексируется по определению). Если на то пошло, индексируя внешний ключ, индексируя любой ключ, и объединение таблиц по индексированным помогает повысить производительность, а не объединение по неиндексированному ключу с ограничением внешнего ключа на нем.
Смена темы, если база данных просто поддерживает отображение / рендеринг контента веб-сайта и т. д. И запись кликов, то база данных с полными ограничениями для всех таблиц для таких целей больше не нужна. Подумай об этом. Большинство веб-сайтов даже не используют для этого базу данных. Для аналогичных требований, когда данные просто записываются, а не ссылаются, скажем, на базу данных в памяти, которая не имеет ограничений. Это не означает, что нет модели данных, да логической модели, но нет физической модели данных.
Ну, я не знаю, почему вставка 3 двойных символов новой строки вместо пробелов и изменение двух слов считается «67% - это Джонатан Леффлер», но я не думаю, что проделал что-то подобное. Основной текст предоставил @jay (пользователь 183837).
Я просто предположил, что параграфы здесь не работают, как на большинстве других сайтов. Итак, я собрал все это как одно целое, выделив полужирным шрифтом изменение потока.
Один хороший принцип проектирования структуры данных - гарантировать, что каждый атрибут таблицы или объекта подчиняется хорошо понятному ограничению. Это важно, потому что, если вы или ваша программа можете рассчитывать на достоверные данные в базе данных, у вас меньше шансов получить программные дефекты, вызванные неверными данными. Кроме того, вы тратите меньше времени на написание кода для обработки условий ошибки и с большей вероятностью напишете код обработки ошибок заранее.
Во многих случаях эти ограничения могут быть определены во время компиляции, и в этом случае вы можете написать фильтр, чтобы гарантировать, что атрибут всегда находится в пределах диапазона, или попытка сохранить атрибут не удастся.
Однако во многих случаях эти ограничения могут измениться во время выполнения. Например, у вас может быть таблица «cars», в которой атрибут «цвет» изначально принимает значения, скажем, «красный», «зеленый» и «синий». Во время выполнения программы можно добавлять допустимые цвета в этот начальный список, и новые добавленные «автомобили» могут иметь любой цвет в актуальном списке цветов. Кроме того, вам обычно нужно, чтобы этот обновленный список цветов пережил перезапуск программы.
Чтобы ответить на ваш вопрос, оказывается, что если у вас есть требование к ограничению данных, которое может измениться во время выполнения, и эти изменения должны сохраняться после перезапуска программы, внешние ключи являются самым простым и кратким решением проблемы. Стоимость разработки - это добавление одной таблицы (например, «цвета», ограничение внешнего ключа для таблицы «автомобили» и индекс), а стоимость времени выполнения - это дополнительный поиск в таблице актуальных цветов. для проверки данных, и эти затраты времени выполнения обычно уменьшаются за счет индексации и кэширования.
Если вы не используете внешние ключи для этих требований, вы должны написать программное обеспечение для управления списком, поиска действительных записей, сохранения их на диск, эффективной структурирования данных, если список большой, убедитесь, что никакие обновления в списке не повредить файл списка, предоставить последовательный доступ к списку в случае, если есть несколько читателей и / или писателей, и так далее. т.е. вам необходимо реализовать множество функций СУБД.
В проекте, над которым я работал, часто использовались неявные, а не явные связи, так что можно было объединить несколько таблиц в одном столбце.
Возьмите следующую таблицу
Адрес
Возможные значения EntityType могут быть Employee, Company, Customer, а EntityId относится к первичному ключу любой интересующей вас таблицы.
Я не думаю, что это лучший способ делать что-то, но в этом проекте он сработал.
Обновлять: Сейчас я всегда использую внешние ключи. Мой ответ на возражение «они усложняют тестирование»: «напишите свои модульные тесты так, чтобы им вообще не нужна база данных. Любые тесты, использующие базу данных, должны использовать ее правильно, включая внешние ключи. Если настройка болезненна, найти менее болезненный способ настройки ».
Предположим, вы используете внешние ключи. Вы пишете автоматический тест, который говорит: «Когда я обновляю финансовый счет, он должен сохранять запись о транзакции». В этом тесте вас интересуют только две таблицы: accounts и transactions.
Однако accounts имеет внешний ключ для contracts, а contracts имеет fk для clients, clients имеет fk для cities, а cities имеет fk для states.
Теперь база данных не позволит вам запустить тест без настройки данных в четырех таблицах, не связанных с вашим тестом..
На это есть как минимум две возможные точки зрения:
Также возможно временно отключить проверку внешнего ключа во время выполнения тестов. MySQL, по крайней мере, поддерживает это.
Я обычно выбираю средний путь здесь: я использую FK, затем я пишу вспомогательные методы модульного тестирования, которые настраивают БД для поддержки различных сценариев тестирования, например вспомогательный метод для заполнения «городов» и «штатов» для любых тестов, требующих заполнения этих таблиц.
Возможно, вам следовало использовать таблицы ссылок между несвязанными сущностями. Или пойти дальше - отдельная DBS: рассмотрим ситуацию в сервис-ориентированной архитектуре или микросервисе, где каждый элемент (клиенты, учетные записи, транзакции) являются разными системами с разными базами данных. Никаких FK между ними, как и все. В этом случае следует использовать FK для предотвращения потери данных в подтаблицах для каждого типа данных.
Существуют также СУБД, которые позволяют накладывать ограничения на отложенный, чтобы они проверялись только при фиксации всей транзакции, поэтому порядок вставки, обновления, удаления не имеет значения.
Если вы тестируете обновление с бизнес-уровня, в вашей среде разработки должен присутствовать FK. При обновлении записи у вас должны быть значения столбцов, необходимые для успешного обновления. Иначе ИМХО ваш тест недействителен.
Ваша база данных даже не должна участвовать в ваших модульных тестах, вы должны имитировать их. В интеграционное тестирование они будут вовлечены, но любые проблемы из-за внешних ключей - это то, с чем ваши пользователи также столкнутся, если вы не исправите это.
Многие из людей, которые здесь отвечают, слишком зацикливаются на важности ссылочной целостности, реализованной с помощью ссылочных ограничений. Работа с большими базами данных со ссылочной целостностью просто неэффективна. Oracle особенно плохо справляется с каскадным удалением. Мое практическое правило заключается в том, что приложения никогда не должны обновлять базу данных напрямую, а должны выполняться через хранимую процедуру. Это сохраняет базу кода внутри базы данных и означает, что база данных сохраняет свою целостность.
Там, где к базе данных могут обращаться многие приложения, возникают проблемы из-за ограничений ссылочной целостности, но это зависит от контроля.
Есть и более широкая проблема: у разработчиков приложений могут быть очень разные требования, с которыми разработчики баз данных могут быть не так хорошо знакомы.
«приложения никогда не должны обновлять базу данных напрямую и должны выполняться через хранимую процедуру. Это сохраняет кодовую базу внутри базы данных и означает, что база данных сохраняет свою целостность». <- Здесь предполагается, что логика хранимых процедур не может нарушить целостность данных, что совершенно неверно.
В DB2, если используются MQT (материализованные таблицы запросов), для оптимизатора требуются ограничения внешнего ключа, чтобы выбрать правильный план для любого заданного запроса. Поскольку они содержат информацию о количестве элементов, оптимизатор интенсивно использует метаданные, чтобы использовать MQT или нет.
По моему опыту, всегда лучше избегать использования FK в критически важных приложениях базы данных. Я не могу не согласиться с ребятами, которые говорят, что FK - это хорошая практика, но это непрактично, когда база данных огромна и имеет огромные операции CRUD в секунду. Я могу поделиться, не называя ... один из крупнейших инвестиционных банков не имеет ни одного FK в базах данных. Эти ограничения обрабатываются программистами при создании приложений с использованием БД. Основная причина заключается в том, что когда когда-либо создается новый CRUD, он должен воздействовать на несколько таблиц и проверять каждую вставку / обновление, хотя это не будет большой проблемой для запросов, затрагивающих отдельные строки, но это создает огромную задержку, когда вы имеете дело с пакетная обработка, которую любой крупный банк должен выполнять как повседневные задачи.
Лучше избегать FK, но с риском должны справиться программисты.
Я не думаю, что практика развития в крупных банках устанавливает золотой стандарт.
Я знаю только базы данных Oracle, никаких других, и могу сказать, что внешние ключи необходимы для поддержания целостности данных. Перед вставкой данных необходимо создать правильную структуру данных. Когда это будет сделано - и, таким образом, будут созданы все первичные И внешние ключи - работа будет выполнена!
Значение: бесхозные строки? Нет. Никогда в жизни такого не видел. Если только плохой программист не забыл внешний ключ или не реализовал это на другом уровне. Оба - в контексте Oracle - огромные ошибки, которые приведут к дублированию данных, потерям данных и, следовательно, к повреждению данных. Я не могу представить базу данных без принудительного FK. Мне это кажется хаосом. Это немного похоже на систему разрешений Unix: представьте, что все являются root. Подумайте о хаосе.
Внешние ключи необходимы, как и первичные ключи. Это как сказать: что, если мы удалим первичные ключи? Что ж, случится полный хаос. Это то что. Вы не можете переносить ответственность за первичный или внешний ключ на уровень программирования, это должно быть на уровне данных.
Недостатки? Да, конечно ! Потому что при вставке будет происходить намного больше проверок. Но если целостность данных важнее производительности, это не проблема. Проблема с производительностью в Oracle больше связана с индексами, которые поставляются с PK и FK.
Quite часто получаем ошибки с Ограничения FK Невозможно добавить или обновить дочернюю строку: ограничение внешнего ключа не выполняется Предположим, есть две таблицы inventory_source и contract_lines, и мы ссылаемся на inventory_source_id в contract_lines из inventory_source, и предположим, что мы хотим удалить запись из inventory_source, и запись уже присутствует в contract_lines, или мы хотим удалить столбец PK из базовой таблицы, мы получаем ошибки для ограничений FK, мы можем избежать этого, следуя инструкциям ниже.
CREATE TABLE inventory_source (
inventory_source_id int(11) NOT NULL AUTO_INCREMENT,
display_name varchar(40) NOT NULL,
state_id int(11) NOT NULL,
PRIMARY KEY (inventory_source_id),
KEY state_id (state_id),
CONSTRAINT ba_inventory_source_state_fk FOREIGN KEY (state_id) REFERENCES ba_state (state_id)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
CREATE TABLE contract_lines(
contract_line_id int(11) NOT NULL AUTO_INCREMENT,
inventory_source_id int(11) NULL ,
PRIMARY KEY (contract_line_id),
UNIQUE KEY contract_line_id (contract_line_id),
KEY AI_contract_line_id (contract_line_id),
KEY contract_lines_inventory_source_fk (inventory_source_id),
CONSTRAINT contract_lines_inventory_source_fk FOREIGN KEY (inventory_source_id) REFERENCES ba_inventory_source (inventory_source_id)
) ENGINE=InnoDB AUTO_INCREMENT=135 DEFAULT CHARSET=utf8 ;
Мы можем преодолеть это, используя следующие шаги: -
Если вы абсолютно уверены, что одна базовая система базы данных не изменится в будущем, я бы использовал внешние ключи для обеспечения целостности данных.
Но вот еще одна очень хорошая реальная причина вообще не использовать внешние ключи:
Вы разрабатываете продукт, который должен поддерживать разные системы баз данных.
Если вы работаете с Entity Framework, которая может подключаться ко многим различным системам баз данных, вам также может потребоваться поддержка бессерверных баз данных с открытым исходным кодом. Не все эти базы данных могут поддерживать ваши правила внешнего ключа (обновление, удаление строк ...).
Это может привести к разным проблемам:
1.) Вы можете столкнуться с ошибками при создании или обновлении структуры базы данных. Возможно, будут только тихие ошибки, потому что ваши внешние ключи просто игнорируются системой баз данных.
2.) Если вы полагаетесь на внешние ключи, вы, вероятно, будете меньше проверять целостность данных или вообще не проводить их в своей бизнес-логике. Теперь, если новая система базы данных не поддерживает эти правила внешнего ключа или просто ведет себя иначе, вам придется переписать свою бизнес-логику.
Вы можете спросить: Кому нужны разные системы баз данных? Что ж, не каждый может себе позволить или хочет иметь полноценный SQL-сервер на своей машине. Это программное обеспечение, которое необходимо поддерживать. Другие уже вложили время и деньги в какую-то другую систему БД. Бессерверная база данных отлично подходит для небольших клиентов на одном компьютере.
Никто не знает, как ведут себя все эти системы БД, но ваша бизнес-логика с проверками целостности всегда остается неизменной.
«Перед добавлением записи убедитесь, что соответствующая запись существует в другой таблице» - это бизнес-логика.
Вот несколько причин, по которым вы не хотите, чтобы это было в базе данных:
Если бизнес-правила меняются, вам необходимо изменить базу данных. Во многих случаях базе данных потребуется воссоздавать индекс, а для больших таблиц это происходит медленно. (Правила изменения включают: разрешить гостям публиковать сообщения или разрешить пользователям удалять свою учетную запись, несмотря на то, что они оставляли комментарии и т. д.).
Изменить базу данных не так просто, как развернуть исправление программного обеспечения путем отправки изменений в производственный репозиторий. Мы хотим максимально избежать изменения структуры базы данных. Чем больше бизнес-логики в базе данных, тем больше у вас шансов изменить базу данных (и запустить повторную индексацию).
TDD. В модульных тестах вы можете заменить базу данных на mocks и протестировать функциональность. Если у вас есть бизнес-логика в вашей базе данных, вы не проводите полные тесты, и вам нужно будет либо протестировать с базой данных, либо реплицировать бизнес-логику в коде для целей тестирования, дублируя логику и увеличивая вероятность того, что логика не работает так же.
Повторное использование вашей логики с разными источниками данных. Если в базе данных нет логики, мое приложение может создавать объекты из записей из базы данных, создавать их из веб-службы, файла json или любого другого источника. Мне просто нужно поменять местами реализацию преобразователя данных и использовать всю свою бизнес-логику с любым источником. Если в базе данных есть логика, это невозможно, и вам придется реализовать логику на уровне отображения данных или в бизнес-логике. В любом случае вам нужны эти проверки в вашем коде. Если в базе данных нет логики, я могу развернуть приложение в разных местах, используя разные реализации баз данных или плоских файлов.
Ух ты ...
Ответы везде. На самом деле это самая сложная тема, с которой я когда-либо сталкивался.
Я использую FK, когда они нужны, но в производственной среде я их редко использую.
Вот почему я редко использую Fks:
1. Большую часть времени я имею дело с огромными данными на небольшом сервере, чтобы повысить производительность, мне нужно удалить FK. Потому что, когда у вас есть FK и вы выполняете Create, Update или Delete RDBMS, сначала проверьте, нет ли нарушения ограничений и если у вас огромная БД, которая может быть чем-то фатальным
2. Иногда мне нужно импортировать данные из других мест, и поскольку я не слишком уверен в том, насколько они хорошо структурированы, я просто отбрасываю FK.
3. В случае, если вы имеете дело с несколькими БД, и наличие ссылочного ключа в другой БД не будет работать (на данный момент), пока вы не удалите FK (перекрестные отношения между базами данных)
4. Они также имели место, когда вы пишете приложение, которое будет размещаться в любой СУБД, или вы хотите, чтобы ваша БД экспортировалась и импортировалась в любую систему СУБД, в этом случае каждая конкретная система СУБД имеет свой собственный способ работы с FK, и вы будете наверное придется отказаться от использования FKs.
5. Если вы используете платформу РСУБД (ORM), вы знаете, что некоторые из них предлагают собственное отображение в зависимости от решения и технических особенностей своего предложения, и вам не нужно создавать таблицы и их FK.
6. Перед последним пунктом будет информация о работе с БД, которая имеет FK, и знания для написания приложения, которое выполняет всю работу без необходимости использования FK.
7. Наконец, когда я начал говорить, все зависит от вашего сценария, если знание не является препятствием. Вам всегда захочется использовать лучшее из лучшего, что вы можете получить!
Спасибо всем!
Мне особенно интересно увидеть реальную реализацию базы данных без внешних ключей.