最近,我将整个DB从myisam迁移到innodb。我对所有这些都很陌生,所以我有一个关于外键使用的问题。
假设我有两个表:用户,消息。
用户
id (pr_key)
name
消息
id (pr_key)
user_id
message
id字段都是自动递增的。
因此,在我的查询中,我已经加入了这两个表。你还需要在这里放一个外键吗?其实我看不出有什么意义。有性能上的好处吗。
如果我选择在这里放置一个外键,我假设我必须使消息的pr_key既包括id,也包括user_id。
添加其他prim_key不仅占用更多的空间,而且会导致性能下降。 现在,如果表中有两个pr_keys,并且我只查询其中一个,那么我仍然有相同的性能优势。还是我需要显式地使用这两个键。
我知道在这个例子中,我将在user_id上搜索,所以无论如何对它进行索引可能是明智的。但是,如果字段是一个没有搜索的字段,该怎么办。在这个领域上放置多个主键还是好的,只是为了国外的关系。
谢谢!
发布于 2009-11-27 16:30:45
它具有数据完整性、优点。
当用户表中没有id = 1234的用户时,它将阻止应用程序代码在消息表中输入user_id为1234。当用户在消息表中有任何消息时,它将阻止应用程序删除用户。
PK的名称不必与引用子表中的FK名称相匹配。
“如果我选择在这里放置一个外键,我假设我必须使消息的pr_key既包括id,也包括user_id。”
,NO,.不更改messages表中的键,只需在messages表中的User_Id列上建立一个Foreign (FK)约束,该约束引用(指向)用户表上的id列。消息中不需要额外的PK,而且由于PK已经是唯一的(不能有两条具有相同messageId的消息),使得id和user_id上的PK不能添加更多的唯一性。
这里的底线是,对于主键和外键实际上是什么,您可能有一个基本的误解。
@Noah,看看这个其他问题
发布于 2009-11-27 16:39:36
无论您是否对消息建立正式的外键规则(User_id),简单的事实是,这是一种外键关系。
首先,请记住,表上的适当主键应该足以唯一地标识表中的每个记录。考虑到每个消息在id字段中都已经有了,您不需要也不特别希望将user_id封装到messages表的主键中。
其次,正如Charles已经指出的,声明引用用户(Id)的消息外键(User_id)将允许您确保数据的完整性。使用外键约束,您可以指定删除“用户”表中有相应记录的“用户”表中的记录时应执行的操作。您的选择包括DELETE级联(删除此用户记录的所有子记录)、delete限制(不允许删除包含消息表中记录的用户)、DELETE NO操作(忽略删除操作)、DELETE SET NULL (保留子记录但将user_id字段设置为NULL)。
根据具体情况,这些选项都是适当的,但这里最重要的是可以防止从子表到父表的意外空指针。
第三,建立外键关系将提供性能提升,因为这将生成与用户表上的主键对应的消息索引(User_id)。在对这些字段执行任何连接的查询时,您将看到,与未建立外键相比,必须查询才能返回子记录的记录数量大大减少。
@Charles Bretana -链接到的问题特定于。这里的问题是关于MySQL / InnoDB。
我建议您查看InnoDB外键约束的文档。
InnoDB需要对外键和引用键进行索引,这样外键检查就可以快速而不需要表扫描。在“引用”表中,必须有一个索引,其中将外键列按相同顺序列为第一列。如果引用表不存在,则自动在该表上创建这样的索引。(这与一些旧版本形成了对比,在这些版本中,必须显式创建索引,否则创建外键约束就会失败。)如果给出了index_name,则按前面描述的方式使用。
https://stackoverflow.com/questions/1809629
复制相似问题