2010-01-14 1 views
1

Я использовал онлайн-конструктор SQL для разработки некоторых таблиц MySQL, над которыми я работаю. Внешние ключи меня всегда путают.Что будут делать эти внешние ключи?

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

ALTER TABLE `users` ADD FOREIGN KEY (user_id) REFERENCES `settings` (`user_id`); 
ALTER TABLE `logins` ADD FOREIGN KEY (user_id) REFERENCES `users` (`user_id`); 
ALTER TABLE `mail_threads` ADD FOREIGN KEY (folder_id) REFERENCES `mail_folders` (`folder_id`); 
ALTER TABLE `mail_message` ADD FOREIGN KEY (thread_id) REFERENCES `mail_threads` (`thread_id`); 

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

+0

Внешние ключи не являются обязательными. Они являются частью ваших доменных отношений. –

+1

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

ответ

1

Внешние ключи - это способ для базы данных назначить ассоциацию «родительской» таблице.

Я начну с нижней части вашего списка и начну свой путь вверх.

Дно FK утверждает, что колонна mail_message.thread_id является ссылкой на mail_threads.thread_id Следующий FK утверждает, что столбец mail_threads.folder_id является ссылкой на mail_folders.folder_id

Что это означает, что mail_thread «относится к» mail_folder, и mail_message "принадлежит" mail_thread. Поэтому, если у вас нет mail_thread с thread_id из 20, вы не можете создать mail_message с thread_id из 20, потому что это не имеет никакого смысла (и ссылка не будет работать). Это также мешает вам удалить mail_thread, например thread_id 20, если есть сообщения внутри этого потока без каскадирования удаления (форсирование удаления всего, связанного с ограничениями), или удаление сообщений в первую очередь.

В двух словах, эти два ограничения говорят:
mail_messages принадлежит mail_threads, которые принадлежат к mail_folders
-или-
mail_folders имеет нулевой многие mail_threads, которые имеют ноль многого mail_messages

SO вопрос с преимущества/ловушки FKs:
What's wrong with foreign keys?

0

Внешние ключи просто сохраняют целостность объекта на месте. Этот код не позволит вам изменить идентификатор пользователя, если в settings нет строки с тем же идентификатором пользователя. Это не позволит вам изменить идентификатор пользователя в таблице logins, если нет соответствующего пользователя. И т. Д.

Что вы подразумеваете под «возиться с» таблицами? Вы можете в любое время обновить таблицу users без обновления таблицы settings, если каждый пользователь всегда имеет соответствующую строку настроек. В противном случае запрос завершится с ошибкой.

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

1

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

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

ALTER TABLE `settings` ADD FOREIGN KEY (user_id) REFERENCES `users` (`user_id`); 

Это будет гарантировать, что любой user_id в таблице settings будет действительным user_id уже присутствует в users таблице. Кроме того, он не позволит вам удалить строку в таблице users, если в таблице settings еще есть строка, которая ссылается на пользователя, который будет удален. Таким образом, он также будет следить за тем, чтобы не было сиротских рядов.

Ваш оригинальный внешний ключ потребовал бы, чтобы строка параметров была вставлена ​​перед строкой пользователей, что, я считаю, не является вашим намерением. Этот внешний ключ проверяет user_id в таблице settings, прежде чем разрешить новому пользователю в таблице users.

Что касается следующего внешнего ключа:

ALTER TABLE `logins` ADD FOREIGN KEY (user_id) REFERENCES `users` (`user_id`); 

Это также будет гарантировать, что любой user_id в таблице logins будет действительным user_id уже присутствует в users таблице. База данных не позволит вам иметь запись с user_id = 100 в таблице logins, если у пользователя нет user_id = 100 в таблице users.

Вы можете применить ту же логику к mail_threads ограничению, которое требует folder_id уже присутствует в ИНТЕ mail_folders таблицы, и то же самое для mail_message ограничения, которое требует действительного thread_id.

+0

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

+0

Не нужно ли вставлять строку 'settings' перед строкой' users'? Этот внешний ключ проверяет 'user_id' в таблице' settings', прежде чем разрешить новому пользователю в таблице 'users'. –

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

  • Нет связанных вопросов^_^