2008-08-20 2 views
94

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

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

+66

«Предположим, что программист на самом деле делает это правильно» - я даже не могу представить такой сценарий. – recursive 2009-04-19 15:05:38

+11

«Иностранный ключ» - это идея, а не технология. Это реляционное правило. Ваш вопрос действительно о том, следует ли пытаться обеспечить соблюдение правила в вашем коде или позволить базе данных помочь вам. Когда задействован параллелизм, лучше всего позволить механизму базы данных обеспечить соблюдение этого правила, поскольку он знает ВСЕ, что происходит в базе данных, в то время как ваш код не может быть осведомлен. – Triynko 2009-08-25 18:20:01

+0

@ Трийнко, понятие внешних ключей не является реляционным правилом. – 2010-02-08 12:21:33

ответ

95

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

55

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

41

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

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

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

8

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

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

1

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

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

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

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

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

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

12

Предположим, что программист фактически делает это в правильном порядке, уже

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

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

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

12

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

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

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

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

20

Да.

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

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

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

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

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

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

4

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

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

1

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

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

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

36

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

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

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

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

3

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

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

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

Вопрос:

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

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

1

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

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

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

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

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

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

8

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

0

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

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

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

5

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

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

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

8

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

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

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

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

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

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

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

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

4

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

5

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

ФКС позволяют DBA для защиты целостности данных от БОРМОТАТЬ пользователей, когда программист терпит неудачу сделать это, а иногда и для защиты от БОРМОТАТЬ программистов.

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

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

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

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

2

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

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

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

Альтернатива - это ошибка, при которой ошибка вступает в систему (и дается достаточно времени, она будет), когда внешний ключ не установлен, и ваши данные становятся непоследовательными. Затем вы получаете необычный отчет об ошибке, расследуете и «ОН». База данных завинчена. Теперь, сколько времени потребуется, чтобы исправить?

Смежные вопросы