如何通过社交网络sql数据库中的单个查询获取好友的社交地图?

发布于 2024-11-03 12:16:20 字数 1345 浏览 4 评论 0原文

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

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

  • “users”表,其中用户由称为 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。这有两个主要问题:它不是按关系数量排序的,而且由于许多加入。而且它只有一种方式的关系(谁在我的朋友中关注谁)——但是我认为这可以通过工会来解决。

有什么想法可以改进吗?

I have a social networking site built on top of the Elgg (php + mysql) framework. My objective is to get all friends of a given user, and also the friend relationships among those friends.

All the information I need is in two tables:

  • the "users" table where users are identified by a unique id called guid
  • and the "relationships" table where friend relationships are represented by (guid_one, "friend", guid_two) triplets

Friend relationships in Elgg can both be one way or bidirectional, it is more like Twitter's "follow" relationship. Uniqueness of the relationship triplets is guaranteed.

Short example:
Considering (1, "Joe"), (2, "Jack") (3, "Jim") users and the following relationships (1, "friend", 2), (2, "friend", 1), (1, "friend", 3), (2, "friend", 3), this could be interpreted as

  1. Joe and Jack are mutual friends (follow each other)
  2. Jim is followed by both Joe and Jack

What I'd like to get is

  • a list of all relationship among the friends for any given user
  • in the descending order of the number of relationships (i.e. list relationships first for those friends who follow most of my friends)
  • preferably in a single query

What would be the most efficient way to do this?

EDIT So far I have this:

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))

Where xxx stands for the user's guid I'm interested in. There are two main problems with this: it's not ordered by the number of relationships and it's painfully slow because of the many joins. Also it gets only one way relationships (who is following whom among my friends) - however that could by solved by a union, I think.

Any ideas to improve on this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

黯淡〆 2024-11-10 12:16:20

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


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

You can do a BFS on a stored procedure.
initialize the table with the user given, and each step of the BFS will insert into this table the friends of the users in this table.
distance (or hops) can be a parameters to this procedure.


Edit:
How BFS works (wikipedia).
How stored procedures work (mysql), loops and recursion (mysql), and stackoverflow

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文