【问题标题】:How to get the social map of friends by a single query from a social networking sql database?如何通过单个查询从社交网络 sql 数据库中获取朋友的社交地图?
【发布时间】:2011-08-14 11:59:07
【问题描述】:

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

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

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

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

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

  1. Joe 和 Jack 是共同的朋友(互相关注)
  2. Jim 后面跟着 Joe 和 Jack

我想得到的是

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

最有效的方法是什么?

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

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。这有两个主要问题:它不是按关系数量排序的,而且由于有很多连接,它的速度非常慢。它也只有一种方式的关系(我的朋友中谁在关注谁)——但是我认为这可以通过工会来解决。

有什么改进的想法吗?

【问题讨论】:

    标签: mysql sql social-networking entity-relationship elgg


    【解决方案1】:

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


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

    【讨论】:

    • 您能否将我链接到更详细地解释如何实现此功能的任何资源?谢谢!
    • +1 用于向我展示 BFS,但是不使用存储过程的单个查询将是首选解决方案。
    • 如果您的“社交半径”固定为 2,那么您可以将其设为对存储过程的一次调用。我仍然建议使用存储过程,因为您还需要在迭代期间锁定表以避免返回不正确的数据。无论哪种方式,您都不能一次完成,并且存储过程是首选,因为它们将算法与您在业务逻辑中使用的语言分离,例如Java、Ruby 等
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    相关资源
    最近更新 更多