1

我有一个建立在Elgg (php + mysql) 框架之上的社交网站。我的目标是获取给定用户的所有朋友,以及这些朋友之间的朋友关系。

我需要的所有信息都在两个表中:

  • “用户”表,其中用户由称为 guid 的唯一 ID 标识
  • 以及由 (guid_one, "friend", guid_two) 三元组表示朋友关系的 "relationships" 表

Elgg 中的好友关系既可以是单向的,也可以是双向的,更像是 Twitter 的“关注”关系。保证关系三元组的唯一性。

简短示例:考虑 (1, "Joe"), (2, "Jack") (3, "Jim") 用户和以下关系 (1, "friend", 2), (2, "friend", 1) , (1, "friend", 3), (2, "friend", 3),这可以解释为

  1. 乔和杰克是共同的朋友(互相关注)
  2. 乔和杰克都跟着吉姆

我想得到的是

  • 任何给定用户的朋友之间所有关系的列表
  • 按关系数量的降序排列(即,关注我大多数朋友的朋友首先列出关系)
  • 最好在单个查询中

最有效的方法是什么?

编辑到目前为止,我有这个:

SELECT
    u1.guid, u1.name, u2.guid, u2.name
FROM
    users u1
INNER JOIN relationships r1 ON 
  (u1.guid = r1.guid_one AND r1.relationship = "friend")
INNER JOIN users u2 ON (r1.guid_two = u2.guid)
INNER JOIN relationships r2 ON 
  ((r2.guid_one = xxx AND r2.guid_two = u1.guid) 
  OR (r2.guid_two = xxx AND r2.guid_one = u1.guid))
INNER JOIN relationships r3 ON 
  ((r3.guid_one = xxx AND r3.guid_two = u2.guid) 
  OR (r3.guid_two = xxx AND r3.guid_one = u2.guid))

其中 xxx 代表我感兴趣的用户 guid。这有两个主要问题:它不是按关系数量排序的,而且由于有很多连接,它的速度非常慢。它也只有一种方式的关系(谁在我的朋友中关注谁)——但是我认为这可以通过工会来解决。

有什么想法可以改进吗?

4

1 回答 1

1

您可以对存储过程执行 BFS。用给定的用户初始化表,BFS 的每一步都会将这个表中用户的朋友插入到这个表中。距离(或跳数)可以是此过程的参数。


编辑:BFS 如何工作(维基百科)。存储过程如何工作 ( mysql )、循环和递归 ( mysql ) 以及stackoverflow

于 2011-04-28T08:55:36.820 回答