代码之家  ›  专栏  ›  技术社区  ›  Prakash Atreya

mysql多重外键与内部联接

  •  0
  • Prakash Atreya  · 技术社区  · 11 年前

    对同一个父表使用两个外键来避免内部联接有什么意义吗?

    表:user_profile

    id1, userid, username, firstname
    

    表:user_hobby1

    id2, userid(fk), hobby, movies
    

    表:user_hobby2

    id3, userid(fk), firstname(fk), hobby, movies
    

    我想从上表中选择所有的名字和爱好。我不确定user_hobby1或user_hobby 2是否是性能最佳的设计?一个添加额外的外键,另一个需要联接。

    查询1:

    Select firstname, hobby 
    from user_hobby2;
    

    查询2:

    Select p.firstname, h.hobby
    from 
     user_profile p
     inner join user_hobby1 h on u.userid=h.userid;
    
    2 回复  |  直到 11 年前
        1
  •  0
  •   spencer7593    11 年前

    将属性值从用户表复制到爱好表不是“外键”,这是冗余。

    我们的性能目标通常无法通过避免JOIN操作来实现,JOIN操作是关系数据库操作的正常部分。

    我会选择标准化设计作为第一步。每个属性都应该依赖于关键点、整个关键点,而不是关键点。“firstname”属性取决于用户的id,而不是爱好。

    有时,我们确实通过在数据库中引入冗余来获得性能优势。我们必须以一种可控的方式做到这一点,并确保不会出现更新异常。(考虑一下,如果“firstname”属性的值被更新,我们希望应用什么更改……我们是否对用户表、user_hobby表或两者都进行了更改。

    很可能,“名字”是 在用户表中是唯一的,因此我们绝对不希望外键引用该列;我们希望引用用户表的外键引用表的PRIMARY KEY。

    如果user_hobby只与一个用户相关,那么在user_hoby和user之间定义两个外键是没有意义的。我们只需要一把外键。。。我们只需将用户表中的id存储在userhobby表中。

        2
  •  0
  •   ffflabs    11 年前

    如果user_hobby2中有两个FK,则只能确保user_profile中存在userid和username,但无法确保哪个userid与给定的用户名一起使用。

    如果您使(userid,username)成为一个复合FK,那么您将保证每个元组的一致性,但复合FK通常更复杂。根据更新和删除级联的行为,我看到mysql同时触发它们并拒绝从父级删除。

    此外保持复合FK有什么意义?它只会在您更新或删除user_profile时帮助您,但不会在您为用户插入新用户或新爱好时帮助您复制数据。

    你试图避免的加入非常便宜。就用第一种方法。它更易于维护,并将帮助您保持数据的一致性和规范化。

    推荐文章