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

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

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

23 ответов


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


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


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

Они не требуются, строго говоря, но преимущества огромны.

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


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

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

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

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


да.

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

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

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

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

Edit: я хотел бы добавить, что, IMO, использование внешних ключей в поддержку on DELETE или ON UPDATE CASCADE не обязательно хорошо. На практике я обнаружил, что каскад при удалении должен быть тщательно рассмотрен на основе отношения данных - например, у вас есть естественный родитель-ребенок, где это может быть нормально или связанная таблица-набор значений поиска. Использование каскадных обновлений означает, что вы разрешаете изменять первичный ключ одной таблицы. В этом случае у меня есть общее философское несогласие в том, что первичный ключ таблицы не должен меняться. Ключи должны быть по своей сути постоянный.


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

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

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

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


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

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


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


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

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

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

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

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

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

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

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


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


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

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

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

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


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

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

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


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

ФКС позволяют дБА защитить целостность данных от шарить потребителей когда программист не для этого, а иногда и для защиты от неловкости программистов.

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

программисты смертны и подвержены ошибкам. ФКС являются декларативный что делает их сложнее испортить.

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

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


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

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


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


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

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

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

вопрос:

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

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


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

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

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

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


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

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

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

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

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

  2. инструмент поддержки. Гораздо проще создавать модели данных, используя Visual Studio 2008 это можно использовать для LINQ to SQL если есть правильные отношения внешнего ключа.

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


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

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

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


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

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

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

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

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

удаление всех заказов и счетов-фактур удаленного клиента с помощью on DELETE CASCADE-идеальный пример красивой, но неправильной схемы базы данных.


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

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

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