Задать вопрос
inik23
@inik23
типа разработчик

Как вытянуть с базы (mySql) всех друзей пользователя, друзей друзей и так до конца?

Доброго. Подскажите как можно вытянуть с базы всех друзей друзей.
Пример у меня есть три друга и них по три друга и так далее надо вытянуть всех.
Можно ограничить до 5ти кругов.

Возможно ли это сделать одним запросом,? если да то как? Да и вообще как это можно сделать?
Спасибо.
  • Вопрос задан
  • 180 просмотров
Подписаться 2 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 3
usdglander
@usdglander Куратор тега PHP
Yipee-ki-yay
Скажу основное из статьи, которую порекомендовал 27cm:
Вынужден огорчить пользователей mySQL – в этой СУБД придется рекурсию организовывать внешними по отношению к СУБД средствами, например на php (код приводить не буду, его публиковали не раз, например здесь, достаточно поискать по запросу “mySQL tree” и т.п.).
Ответ написан
Комментировать
@ollisso
Самый простой способ:

В момент изменения списка друзей - пересчитываем вручную друзей до 5ого уровня и сохраняем в таблице вида:
user_id,friend_id, level

Так как редактирование списка друзей - событие реже чем выборка" - то это имеет смысл чтобы выборка была быстрая.

Правда на больших объёмах - (Сотни людей) - могут быть проблемы :)

2ой способ, в момент выборки, так как у нас ограничен уровень вложения: (но сражу скажу что этот способ намного хуже)

друзья первого уровня:
select friend_id from users_friends where user_id  =1;


Друзья второго уровня:
select lvl2.friend_id 
from users_friends as lvl1
right join users_friends  as lvl2 on lvl2.friend_id=lvl1.user_id
where lvl1.user_id  =1;


Дальше уровни по аналогии

а чтобы это всё вместе возвращало:

select friend_id from users_friends where user_id  =1 UNION
select lvl2.friend_id  from users_friends as lvl1 right join users_friends  as lvl2 on lvl2.friend_id=lvl1.user_id where lvl1.user_id  =1;


Правда на больших объёмах производительнсть будет хромать.

использую такую таблицу:
users_friends: -друзья юзеров
user_id, friend_id (причём для каждой "дружбы" - две записи)

способ 3:
делать подобную выборку как в п1 и хранить в кеше локальном (требуется 5 запросов

Способ 4:
написать процедуру которая делает то же самое что в п1-п2
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы