我使用在线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)
外键将保证您不会引用不存在的记录。外键创建的约束通常被认为是在数据库中实施数据完整性的基础。
事实上,我认为您的第一个外键可能需要调整如下:
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
表,只要每个用户始终具有相应的设置行即可。否则,查询将失败。
您应该保留代码,除非您有充分的理由将其删除。如果外键约束妨碍你,那只是通知你的代码做错了。