需要外国的关键,在这种情况下(少/mysql)
-
05-07-2019 - |
题
我最近迁移我的整个DB从些至少.我相当新的,所有这使我有一个问题有关使用外地关键。
可以说我有两个表格:用户、用户信息。
用户
id (pr_key)
name
消息
id (pr_key)
user_id
message
Id领域都是自动增加。
所以现在我的查询我加入这些表2。它是仍然有必要把一个外国的关键就在这里,我实际上看不到一点。它具有性能的好处。
如果我选择把一个外国的关键在这里,我认为我必须做的pr_key的消息,这两个id,并user_id.
将添加的其他prim_key不仅仅是采取更多的空间,并导致慢性能。
现在如果表有两个pr_keys,我只能查询关于他们中的一个,我将仍然具有同样性能的好处。或者我需要明确地使用两个键。
我知道在这个例子中,我将寻找在user_id所以这也许是明智的指数,这无论如何。但是,如果该领域的一个领域里有没有搜索。它仍然是良好的地方的一个主要关键,在这一领域,只为国外嘿的关系。
谢谢你!
解决方案
它已 数据的完整性 好处。
它会停止的应用程序代码进入user_id的1234中的消息表当,没有用户提id=1234在用户表。它会停止的应用程序删除的用户时,用户有任何消息的消息表。
名称的PK没有匹配的名称FK在引用儿童表。
"如果我选择把一个外国的关键在这里,我认为我必须做的pr_key的消息,这两个id,并user_id."
没有.你不改变关键的消息表,你只是建立一个外国的关键(FK)的约束User_Id列的消息表,引用(指向)的id列在用户表。没有额外的PK是必需的信息,并且由于PK已经是唯一的(你不能有两个消息具有相同messageId)使PK在两个id和user_id不添加任何更多的独特性。)
底线在这里,你可以有一个根本性的误解,关于什么的一个主要关键和外关键实际的。
- 一PK是一个制约因素的独特性的一个排,这需要索引。
- 一FK是一个制约因素的价值一栏(它的任务规定,值的存在作为一PK值在某些其他引用的表格)它不会 不 需要指数。
@诺亚,看看这个 其他这样的问题
其他提示
无论是否在消息(user_id)上建立正式的FOREIGN KEY规则,简单的事实是这是一个外键关系。
首先,请记住,表上正确的主键应足以唯一标识表中的每条记录。考虑到每条消息都已经包含 id
字段,您不需要也不需要将 user_id
包装到messages表的主键中。
其次,正如Charles已经声明在消息(user_id)上声明一个FOREIGN KEY,REFERENCES用户(id)将允许您确保数据的完整性。使用外键约束,您可以指定删除在users表中具有相应记录的users表中的记录时要执行的操作。您的选择是ON DELETE CASCADE(删除此用户记录的所有子记录),ON DELETE RESTRICT(不允许删除用户在消息表中有记录),ON DELETE NO ACTION(忽略删除操作) ,ON DELETE SET NULL(保留子记录但将user_id字段设置为NULL)。
根据具体情况,每个选项都是合适的,但最重要的是你可以防止从子表到父表的意外空指针。
第三,建立FOREIGN KEY关系将提供性能提升,因为这将在与users表上的PRIMARY KEY对应的消息(user_id)上生成INDEX。在执行连接这些字段的任何查询时,您将看到与未建立FOREIGN KEY相比,必须查询以返回子记录的记录数量大幅减少。
@Charles Bretana - 您链接的问题特定于Microsoft SQL Server。这里的问题是关于MySQL / InnoDB。
我建议您查看 InnoDB外键约束。
InnoDB需要外国索引 键和引用键,以便 外键检查可以快速而不是 需要进行表扫描。在里面 引用表,必须有一个 索引所在的外键列 被列为第一列 同样的顺序。创建了这样的索引 在引用表上自动 如果它不存在。 (这是在 与一些旧版本形成鲜明对比 必须创建哪些索引 明确地或创造外国的 关键约束会失败。) index_name,如果给定,则用作 如前所述。