Действительно ли необходимы foreign keys в дизайне базы данных?

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

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

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

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

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

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

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

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

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

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

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

Да.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Вопрос:

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

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

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

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

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

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

Вы можете просматривать foreign keys как ограничение, которое,

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • Как передать List из java в Oracle Procedure?
  • Разделение разделенной запятой строки в PL / SQL хранимой процедуре
  • Каков минимальный клиентский след, необходимый для подключения C # к базе данных Oracle?
  • Какова минимальная настройка, требуемая для развертывания приложения .NET с клиентом Oracle 11?
  • Oracle Искать все таблицы для всех столбцов для строки
  • BEGIN - END блокирует атомные транзакции в PL / SQL
  • Нужно сбросить значение последовательности в Oracle
  • Oracle: как вставить INSERT, если строка не существует
  • Поставщик несовместим с версией клиента Oracle
  • Oracle вставить, если не существует оператора
  • Что такое двойная таблица в Oracle?
  • Давайте будем гением компьютера.