这些外键会做什么?

时间:2010-01-14 00:50:52

标签: mysql foreign-keys

我使用在线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个,我需要能够单独更新而不会弄乱另一个,所以我不应该使用外键吗?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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,则无法创建一个thread_id为20的mail_message,因为它没有任何意义(并且引用不起作用)。如果在该线程中有消息而没有级联删除(强制删除通过约束关联的所有内容)或首先删除消息,它还会阻止你删除说thread_id 20的mail_thread。

简而言之,这两个限制条件是:
mail_messages属于mail_threads,属于mail_folders
- 或 -
mail_folders有零到多个mail_threads,其中包含零到多个mail_messages

关于FK的利益/陷阱的问题:
What's wrong with foreign keys?

答案 2 :(得分:0)

外键只是保持对象的完整性。如果settings中没有具有相同用户ID的行,则此代码不允许您更改用户的ID。如果没有相应的用户,它将不允许您更改logins表中的用户ID。等

“弄乱”桌子是什么意思?您可以随时更新users表而无需更新settings表,只要每个用户始终具有相应的设置行即可。否则,查询将失败。

您应该保留代码,除非您有充分的理由将其删除。如果外键约束妨碍你,那只是通知你的代码做错了。