2011-04-28 143 views
1

我有一个建立在Elgg(php + mysql)框架之上的社交网站。我的目标是获得给定用户的所有朋友,以及这些朋友之间的朋友关系。如何通过社交网络sql数据库中的单个查询获取朋友的社交地图?

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

  • ,用户都能通过一个称为GUID唯一ID标识的“用户”表
  • 和“关系”表,其中的朋友关系,分别由(guid_one,“friend”,guid_two)三联

Elgg中的朋友关系既可以是单向的,也可以是双向的,它更像Twitter的“跟随”关系。关系三元组的唯一性是有保证的。考虑(1,“乔”),(2,“杰克”)(3,“吉姆”)用户和以下关系(1,“朋友”,2),(2,“朋友”,1),(1, “朋友”,3),(2, “朋友”,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我感兴趣的还有与此两个主要的问题:它不是由关系的数量排序,由于很多连接,它的速度很慢。同样,它也只有一种方式的关系(谁跟随我的朋友之间的关系) - 但是我认为这可以通过工会解决。

任何想法,以改善呢?

回答

1

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


编辑: BFS工作原理(wikipedia)。 如何存储过程的工作(mysql),循环和递归(mysql)和stackoverflow

+0

可以链接我在更多的细节解释的任何资源如何实现这一点?谢谢! – 2011-04-28 09:00:59

+0

@Andras:请参阅编辑答案 – Dan 2011-04-28 14:13:16

+0

+1以显示BFS,但不使用存储过程的单个查询将是首选解决方案。 – 2011-04-29 15:51:24