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

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

  •  09-06-2019
  •  | 
  •  

Вопрос

Насколько я знаю, внешние ключи (FK) используются для того, чтобы помочь программисту правильно манипулировать данными.Предположим, программист на самом деле уже делает это правильным образом, тогда действительно ли нам нужна концепция внешних ключей?

Существуют ли какие-либо другие способы использования внешних ключей?Я что-то здесь упускаю?

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

Решение

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

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

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

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

Это не так требуемый, строго говоря, но преимущества огромны.

Я совершенно уверен, что Туманный жук не имеет ограничений по внешнему ключу в базе данных.Мне было бы интересно услышать, как Программное обеспечение Fog Creek команда структурирует свой код таким образом, чтобы гарантировать, что они никогда не приведут к несоответствию.

Схема базы данных без ограничений FK подобна вождению без ремня безопасности.

Однажды ты пожалеешь об этом.Не тратить так мало дополнительного времени на основы проектирования и целостность данных - верный способ избежать головной боли позже.

Приняли бы вы код в своем приложении, который был бы таким неаккуратным?Который напрямую обращался к объектам-членам и напрямую изменял структуры данных.

Как вы думаете, почему это было сделано так сложно и даже неприемлемо в рамках современных языков?

ДА.

  1. Они делают тебя честным
  2. Они обеспечивают честность новых разработчиков
  3. Вы можете сделать ON DELETE CASCADE
  4. Они помогают вам создавать красивые диаграммы, которые самостоятельно объясняют связи между таблицами

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

До ограничений внешнего ключа (также известных как декларативная ссылочная целостность или DRI) было потрачено много времени на реализацию этих отношений с использованием триггеров.Тот факт, что мы можем формализовать отношения с помощью декларативного ограничения, очень важен.

@John - Другие базы данных могут автоматически создавать индексы для внешних ключей, но SQL Server этого не делает.В SQL Server отношения с внешними ключами являются всего лишь ограничениями.Вы должны определить свой индекс для внешних ключей отдельно (что может быть полезно).

Редактировать:Я хотел бы добавить, что, IMO, использование внешних ключей для поддержки КАСКАДА УДАЛЕНИЯ или ОБНОВЛЕНИЯ не обязательно является хорошей вещью.На практике я обнаружил, что каскадное удаление должно быть тщательно рассмотрено на основе взаимосвязи данных - напримересть ли у вас естественный родитель-потомок, где это может быть нормально, или связанная таблица представляет собой набор значений подстановки.Использование каскадных обновлений подразумевает, что вы разрешаете изменять первичный ключ одной таблицы.В этом случае у меня есть общее философское несогласие с тем, что первичный ключ таблицы не должен меняться.Ключи должны быть по своей сути постоянными.

Предположим, программист на самом деле уже делает это правильным образом

Делать такое предположение, на мой взгляд, крайне плохая идея;в целом программное обеспечение феноменально глючит.

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

Хотя в идеальном мире естественные соединения использовали бы отношения (т. е.Ограничения FK), а не совпадающие имена столбцов.Это сделало бы FKs еще более полезным.

Без внешнего ключа, как вы определяете, что две записи в разных таблицах связаны?

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

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

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

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

Теоретически, нет.Однако никогда не существовало программного обеспечения без ошибок.

Ошибки в коде приложения обычно не так опасны - вы выявляете ошибку и исправляете ее, и после этого приложение снова работает без сбоев.Но если ошибка позволяет некорректным данным попадать в базу данных, то вы застряли с этим!Очень сложно восстановить поврежденные данные в базе данных.

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

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

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

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

FK очень важны и всегда должны существовать в вашей схеме, если только вы не с eBay.

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

Например, Ruby на рельсах не использует внешние ключи, но сам проверяет все взаимосвязи.Если вы обращаетесь к своей базе данных только из этого приложения Ruby on Rails, это нормально.

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

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

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

Возможно, сейчас все хорошо, но подумайте, что произойдет, когда ваш программист уйдет и его место займет кто-то другой.

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

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

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

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

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

Существуют ли какие-либо другие способы использования внешних ключей?Я что-то здесь упускаю?

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

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

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

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

Я думаю об этом с точки зрения затрат / выгод...В MySQL, добавление ограничения представляет собой единственную дополнительную строку DDL.Это всего лишь несколько ключевых слов и пара секунд на размышление.На мой взгляд, это единственная "цена"...

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

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

Этот вопрос:

Существуют ли какие-либо другие способы использования внешних ключей?Я что-то здесь упускаю?

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

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

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

Я думаю, что это стоит компромисса в скорости разработки.Конечно, без них вы можете кодировать быстрее, и, вероятно, именно поэтому некоторые люди ими не пользуются.Лично я убил несколько часов на NHibernate на и какое-то ограничение внешнего ключа, которое сердится, когда я выполняю какую-то операцию.ТЕМ не менее, я знаю, в чем проблема, так что это не такая уж большая проблема.Я использую обычные инструменты, и есть ресурсы, которые помогут мне обойти это, возможно, даже люди, которые помогут!

Альтернативой является возможность проникновения ошибки в систему (и при наличии достаточного времени это произойдет), когда внешний ключ не установлен и ваши данные становятся противоречивыми.Затем вы получаете необычное сообщение об ошибке, проводите расследование и "ОХ".База данных испорчена.Итак, сколько времени потребуется, чтобы это исправить?

Вы можете рассматривать внешние ключи как ограничение, которое,

  • Помогает поддерживать целостность данных
  • Показать, как данные связаны друг с другом (что может помочь в обеспечении соблюдения бизнес-логики и правил)
  • При правильном использовании это может помочь повысить эффективность извлечения данных из таблиц.

В настоящее время мы не используем внешние ключи.И по большей части мы не жалеем об этом.

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

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

  2. Инструментальная поддержка.Намного проще создавать модели данных, используя Visual Studio 2008 это может быть использовано для ССЫЛКА на SQL если существуют надлежащие отношения с внешними ключами.

Итак, я предполагаю, что моя точка зрения заключается в том, что мы обнаружили, что если мы выполняем много ручной SQL-работы (создаем запрос, выполняем запрос и прочее), внешние ключи не обязательно необходимы.Однако, как только вы начинаете пользоваться инструментами, они становятся намного более полезными.

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

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

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

Внешние ключи никогда не были явными (таблица ССЫЛОК НА ВНЕШНИЕ КЛЮЧИ (столбец)), объявленные в проектах (бизнес-приложениях и веб-сайтах социальных сетей), над которыми я работал.

Но всегда существовало своего рода соглашение об именовании столбцов, которые были внешними ключами.

Это как с нормализация базы данных -- вы должны знать, что вы делаете и каковы последствия этого (в основном производительность).

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

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

Удаление всех заказов и счетов-фактур удаленного клиента с помощью КАСКАДА УДАЛЕНИЯ - идеальный пример красивой, но неправильно разработанной схемы базы данных.

ДА.Функция ON DELETE [RESTRICT | CASCADE] удерживает разработчиков от скручивания данных, сохраняя их чистыми.Недавно я присоединился к команде разработчиков Rails, которые не фокусировались на ограничениях базы данных, таких как внешние ключи.

К счастью, я нашел эти: http://www.redhillonrails.org/foreign_key_associations.html -- Плагины RedHill на Ruby on Rails генерируют внешние ключи, используя соглашение о конфигурации Стиль.Миграция с product_id - идентификатор продукта создаст внешний ключ к ID в продукты таблица.

Ознакомьтесь с другими замечательными плагинами по адресу РедХилл, включая миграции, обернутые в транзакции.

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