Нужны ли внешние ключи в дизайне базы данных? - PullRequest
103 голосов
/ 21 августа 2008

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

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

Ответы [ 23 ]

99 голосов
/ 21 августа 2008

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

57 голосов
/ 21 августа 2008

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

43 голосов
/ 21 августа 2008

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

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

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

39 голосов
/ 21 августа 2008

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

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

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

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

21 голосов
/ 21 августа 2008

Да.

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

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

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

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

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

12 голосов
/ 21 августа 2008

Предположим, программист действительно делает это правильно

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

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

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

9 голосов
/ 21 августа 2008

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

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

8 голосов
/ 17 сентября 2008

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

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

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

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

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

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

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

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

8 голосов
/ 22 августа 2008

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

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