如何通过社交网络sql数据库中的单个查询获取好友的社交地图?
我有一个建立在 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),这可以解释为
- Joe 和 Jack 是共同的朋友(互相关注)
- 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
- Joe and Jack are mutual friends (follow each other)
- 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以对存储过程执行 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