为用户友谊设计数据库

gmu*_*ent 4 sql database

我想将友谊存储在数据库中.我的想法是,当user1成为user2的朋友时,我存储了这种友谊,这样我就可以获得所有用户的朋友,如果我需要的话.起初我以为我只是将他们的id存储在一个带有一个插入的表中,但是当我查询db时我想到了一些复杂性.

如果我有2个用户ID为10和20的用户,我应该在他们成为朋友时对数据库进行两次插入

ID USER1 USER2
1  10    20
2  20    10
Run Code Online (Sandbox Code Playgroud)

或者有没有办法查询数据库只有一个特定的用户朋友,如果我只做了一个这样的插入

ID USER1 USER2
1  10    20
Run Code Online (Sandbox Code Playgroud)

我知道第一种方式肯定可以给我我想要的东西,但我想知道这是不是很好的做法,如果有更好的选择.如果可以查询第二种方式来获得结果,我会像所有用户10的朋友一样寻找.

Bra*_*tie 5

友谊是一种双向联系(无论出于何种意图和目的).与另一个链接(如单向消息)不同,友谊应该只有一个条目.但是,你所看到的是正确的; 您需要查询两列以获取用户的朋友,但这很简单:

-- The uses of `1` below is where you'd insert the ID of
-- the person you're looking up friends on
SELECT      u.id, u.name
FROM        friendship f
  LEFT JOIN user u
  ON        (u.id = f.user1 OR u.id = f.user2)
    AND     u.id <> 1
WHERE       (f.user1 = 1 OR f.user2 = 1)
Run Code Online (Sandbox Code Playgroud)

这里的例子


Ilm*_*nen 5

布拉德克里斯蒂建议在两个方向查询桌子是好的.但是,鉴于MySQL不是很擅长优化OR查询,使用UNION ALL可能更有效:

( SELECT u.id, u.name
  FROM friendship f, user u
  WHERE f.user1 = 1 AND f.user2 = u.id )
UNION ALL
( SELECT u.id, u.name
  FROM friendship f, user u
  WHERE f.user2 = 1 AND f.user1 = u.id )
Run Code Online (Sandbox Code Playgroud)

这是基于Brad的例子的SQLFiddle.我修改了friendship表以添加双向索引以进行有效访问,并删除无意义的id.当然,有了这么小的例子,你无法真正测试真实世界的性能,但比较两个版本之间的执行计划可能是有益的.