我用了一个在线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个,我需要能够没有他们与其他搞乱单独更新,所以我不应该对他们使用一种外国键?
外键是数据库关联分配给一个“父”表的方式。
我会从你的列表的底部开始,然后我的方式。
底部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 20的thread_id,则不能创建与20的一个的thread_id mail_message,因为它将没有任何意义(与基准将不起作用)。 它还可以防止您删除发言权的mail_thread THREAD_ID 20如果有线程中的消息没有任何级联删除(强制通过约束相关的一切删除),或者先删除消息。
概括地说,这两个制约因素说:
mail_messages属于属于mail_folders mail_threads
-要么-
mail_folders具有零到有0到多个mail_messages许多mail_threads
与FKS的好处/陷阱SO问题:
这有什么错外键?
外键会保证你不会对一个不存在的记录的引用。 由外键创建的约束往往被认为根本执行数据库中的数据完整性。
事实上,我认为你的第一个外键可能需要按以下方式进行调整:
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
已经存在的int mail_folders
表,同为mail_message
约束,需要一个有效thread_id
。
外键简单地保持对象完整性到位。 此代码不会让你更改用户的ID,如果在没有行settings
使用相同的用户ID。 它不会让你更改用户ID的logins
表,如果没有相应的用户。 等等。
你是什么意思表“搞乱”是什么意思? 你可以自由地更新users
在任何时间表而不更新settings
表,只要每个用户总是有一个相应的设置行。 否则,查询将失败。
你应该离开的代码,除非你有一个很好的理由将其删除。 如果外键约束不断得到你的去路,这仅仅是你的代码做一些错误的通知。