Как получить социальную карту друзей по одному запросу из базы данных sql социальной сети? - PullRequest
1 голос
/ 28 апреля 2011

У меня есть сайт социальной сети, построенный на основе Elgg (php + mysql). Моя цель - найти всех друзей данного пользователя, а также дружеские отношения между этими друзьями.

Вся необходимая информация находится в двух таблицах:

  • таблица «users», в которой пользователи идентифицируются по уникальному идентификатору guid
  • и таблица «отношений», где отношения друзей представлены триплетами (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))

Где ххх обозначает руководство пользователя, которое меня интересует. С этим связаны две основные проблемы: он не упорядочен по количеству связей и мучительно медленен из-за большого количества соединений. Также он получает только односторонние отношения (кто за кем следует среди моих друзей) - как бы это ни было решено профсоюзом, я думаю.

Есть идеи, как улучшить это?

1 Ответ

1 голос
/ 28 апреля 2011

Вы можете создать BFS для хранимой процедуры.инициализируйте таблицу с данным пользователем, и каждый шаг BFS будет вставлять в эту таблицу друзей пользователей в этой таблице.Расстояние (или прыжки) могут быть параметрами этой процедуры.


Редактировать : Как работает BFS ( wikipedia ).Как работают хранимые процедуры ( mysql ), циклы и рекурсия ( mysql ) и stackoverflow

...