4

我想将友谊存储在数据库中。我的想法是,当 user1 与 user2 成为朋友时,我会存储该友谊,以便在需要时可以获取任一用户的所有朋友。起初我以为我只需将他们的 id 存储在一个插入的表中,但后来我在查询数据库时想到了一些复杂性。

如果我有 2 个用户 ID 分别为 10 和 20 的用户,当他们成为朋友时,我是否应该在数据库中插入两次

ID USER1 USER2
1  10    20
2  20    10

或者如果我只像这样插入一个,是否有办法查询数据库以仅获取特定用户的朋友

ID USER1 USER2
1  10    20

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

4

2 回答 2

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)

这里的例子

于 2012-12-28T01:57:44.960 回答
5

Brad Christie 关于双向查询表的建议很好。但是,鉴于 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 )

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

于 2012-12-28T02:15:11.047 回答