Основы внешних ключей в MySQL?

91

Есть ли хорошее объяснение того, как использовать конструкцию внешнего ключа MySQL?

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

И вторая часть вопроса: можно ли что-нибудь улучшить с помощью встроенных внешних ключей MySQL?

Маха
источник

Ответы:

117

FOREIGN KEYS просто убедитесь, что ваши данные согласованы.

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

Если у вас такие отношения:

CREATE TABLE department (id INT NOT NULL)
CREATE TABLE employee (id INT NOT NULL, dept_id INT NOT NULL, FOREIGN KEY (dept_id) REFERENCES department(id))

, то вы не можете удалить a, departmentесли у него есть какие employee-то.

Если вы поставляете ON DELETE CASCADEк FOREIGN KEYопределению, ссылающаяся строка будет удалена автоматически вместе с ссылочными из них.

В качестве ограничения на FOREIGN KEYсамом деле немного замедляет запросы.

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

Quassnoi
источник
1
Замедление минимально, потому что вы обычно делаете FK для индексированных полей, что упрощает поиск соответствующих значений.
Себ
4
Вот почему я написал «немного» :) На самом деле, если вы удаляете много строк, базовый JOINможет быть гораздо менее эффективным, чем два DELETE с использованием ПОЛНОГО СКАНИРОВАНИЯ
ТАБЛИЦЫ
2
Извините за голосование "против". Это было случайно, но это не позволяет мне изменить свой голос.
Wondercricket
8
@Wondercricket: Я даже не знаю, что теперь делать, это серая зона в правилах сайта. Я думаю, ты купишь мне пива, когда будешь в Москве, а мы в расчете.
Quassnoi
1
@stack: любое обновление, которое вы делаете для каскадов ключей, на которые ссылаются, в ссылочную таблицу.
Quassnoi 05
32

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

Например, представьте, что вы программируете форум. У вас есть таблица «темы» с первичным ключом topics.topic_id, и у вас есть таблица «сообщений», в которой сообщения прикрепляются к темам со столбцом posts.topic_id, который является внешним ключом для таблицы тем.

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

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

Чад Берч
источник
11

1. ИНОСТРАННЫЕ КЛЮЧИ просто убедитесь, что ваши данные согласованы.

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

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

Запрос: ALTER TABLE child ADD FOREIGN KEY (parent_id) ССЫЛКИ на родительский (id) ON UPDATE CASCADE ON DELETE CASCADE;

  1. вы не можете удалить прямую родительскую таблицу, сначала удалите внешний ключ из дочерней таблицы, чем удалите родительскую таблицу.
Гаурав Кумар
источник
7
Наконец понял, что меня смущало в примерах внешнего ключа. Как отец четверых детей, я не привык, чтобы ребенок следил за родителем . Примерно через сорок лет это уже не будет казаться отсталым.
Боб Штайн,
1
Спасибо, что дали вашим таблицам в качестве примера такие имена, как «дочерний» и «родительский» ... это действительно очень полезно, и я бы хотел, чтобы официальная документация сделала это!
Майк грызун
7

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

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

Это действительно отличная функция, использующая ваш код.

Себ
источник