Зачем мне использовать внешний ключ, если я могу использовать ГДЕ? - PullRequest
35 голосов
/ 15 декабря 2009

Вопрос новичка о внешнем ключе в MySQL.

В w3school сказано:

ИНОСТРАННЫЙ КЛЮЧ в одной таблице указывает на ПЕРВИЧНЫЙ КЛЮЧ в другой таблице.

А также есть ГДЕ,

WHERE id = page_id

Так что, если я могу использовать WHERE для связывания таблиц, какова основная цель иметь внешний ключ?

Ответы [ 10 ]

38 голосов
/ 15 декабря 2009

Это не строго необходимо для запроса, это правда. Он существует по нескольким причинам:

  1. В качестве ограничения на таблицу, чтобы не вставлять что-то, что ни на что не указывает;
  2. как подсказка для оптимизатора; и
  3. По историческим причинам, где это было более необходимо.

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

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

7 голосов
/ 15 декабря 2009

Иностранный используется для ссылочной целостности.

См. Введение в внешние ключи и ссылочную целостность в MySQL

5 голосов
/ 15 декабря 2009

Так что, если я могу использовать WHERE для связывания таблиц, какова основная цель иметь внешний ключ?

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

Скажем, если у вас есть таблица, которая описывает диапазоны цен и скидок, вы используете это сложное условие для объединения таблиц:

SELECT  *
FROM    Goods
JOIN    PriceRange
ON      PriceRange.Price =
        (
        SELECT  MAX(Price)
        FROM    PriceRange
        WHERE   PriceRange.Price <= Goods.Price
        )

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

Смотрите эту запись в моем блоге для более подробной информации:

Связывание с pk-to-pk все же важно. FOREIGN KEY может заверить вас, что права, которые вы связываете, описываются вашей реляционной моделью.

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

SQL Server может даже учитывать этот факт и оптимизировать определенные типы запросов.

Скажите, этот запрос:

SELECT  f.*
FROM    t_foreign f
WHERE   f.pid IN
        (
        SELECT  id
        FROM    t_primary p
        )

даже не будет смотреть на t_primary, если соотношение FOREIGN KEY определено между t_foreign и t_primary.

См. Эту статью для более подробной информации:

2 голосов
/ 15 декабря 2009

Поддержание ссылочной целостности и индексация.

1 голос
/ 15 декабря 2009

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

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

1 голос
/ 15 декабря 2009

оператор RESTRICT (WHERE) не имеет никакого отношения к ссылочным ограничениям!

цитата из C.J. Date's Словарь реляционных баз данных

внешний ключ Пусть R1 и R2 будут relvars, не обязательно различающимися, и пусть K будет ключом для R1 . Пусть FK будет подмножеством заголовка R2 таким, что существует возможно пустая последовательность переименований атрибутов, которая отображает K в K ' (скажем), где K ' и FK содержат точно такие же атрибуты. Тогда FK - это внешний ключ

ссылочная целостность В общем, правило, что ссылочный кортеж не может существовать, если соответствующий ссылочный кортеж не существует. Точнее, пусть FK будет некоторым внешним ключом в некоторой ссылке relvar R2 ; пусть K будет соответствующим ключом в соответствующем ссылочном relvar R1 , и пусть K ' будет получено из K , как описано в внешний ключ . Тогда правило ссылочной целостности требует, чтобы никогда не было времени, в которое существует значение FK в R2 , которое для некоторых не является значением K ' ( обязательно уникальный) кортеж в R1 в данный момент. R1 и R2 здесь указаны relvar и ссылочный relvar, соответственно, и ограничение между ними является ссылочным ограничением.

Примеры : в relvar SP {S#} и {P#} - внешние ключи, соответствующие ключам {S#} и {P#} в relvars S и P соответственно. Обратите внимание, что ключ в указанном relvar, который соответствует данному внешнему ключу, не обязательно должен быть первичным ключом.

1 голос
/ 15 декабря 2009

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

Отношения первичный ключ / внешний ключ поддерживают ссылочную целостность и при правильном индексировании повышают производительность запросов. (См. Объяснение Пита Оанлона выше и Типы JOIN )

0 голосов
/ 26 января 2018

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

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

0 голосов
/ 15 декабря 2009

Прежде всего. Хороший вопрос !!

MySql - это СУБД - реляционная СУБД, поэтому все объекты (таблицы) связаны столбцом.

СОТРУДНИК - EMPID EMPNAME DEPTID

ОТДЕЛ - DEPTID DEPTNAME

DEPTID - это внешний ключ в таблице EMPLOYEE и первичный ключ в таблице DEPARTMENT.

Это отношение - воображаемое отношение объектов, просто соображение или вид проектирования для структурирования данных, чтобы их можно было легко извлечь в будущем. НЕ ФИЗИЧЕСКОЕ ОТНОШЕНИЕ (потому что это язык программирования)

Чтобы получить эти данные, нам нужно немного синтаксиса, описанного Создателем SQL.

ВЫБРАТЬ * от СОТРУДНИКА

ВЫБРАТЬ * ИЗ ОТДЕЛА

ВЫБРАТЬ * ИЗ СОТРУДНИКА ГДЕ ГЛУБИНА = 5

Здесь мы реализовали две мнимые таблицы для нашего удобства, но для требуемого результата мы использовали этот синтаксис WHERE DEPTID = 5.

0 голосов
/ 15 декабря 2009

Внешний ключ используется для поддержания ссылочной целостности, в то время как предложение WHERE используется для объединения таблиц в операции SQL, такой как выбор. Предложение where может работать с несколькими таблицами, но оно просто там как фильтр.

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

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

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