Ето как да извършите търсенето, като използвате търсене в широчина, най-кратък път, като използвате JOIN. В този алгоритъм няма магия, тъй като използваме MySQL, за да намерим отговора си, и не включваме никакъв луксозен алгоритъм за търсене, който използва какъвто и да е вид евристика или оптимизация.
Моята таблица с „приятели“ има еднопосочни връзки, така че имаме дубликати в смисъл, че и „1 към 2“ и „2 към 1“ се съхраняват. Освен това изключвам is_active, тъй като реализацията ще бъде очевидна:
Ето данните:
member_id friend_id
1 2
1 3
1 4
2 1
2 3
2 5
2 6
3 2
3 1
4 1
5 2
6 2
6 7
7 6
7 8
8 7
Имаме избран член 1 и питаме дали 1 приятел със 7, приятел на приятел и т.н.? Брой 0 означава не, а брой 1 означава да.
SELECT COUNT(*)
FROM friends f1
WHERE f1.member_id = 1
AND f1.friend_id = 7
Ако не, тогава те приятели на приятел ли са?
SELECT COUNT(*)
FROM friends f1
JOIN friends f2
ON f2.member_id = f1.friend_id
WHERE f1.member_id = 1
AND f2.friend_id = 7
Ако не, тогава приятел на приятел на приятел?
SELECT COUNT(*)
FROM friends f1
JOIN friends f2
ON f2.member_id = f1.friend_id
JOIN friends f3
ON f3.member_id = f2.friend_id
WHERE f1.member_id = 1
AND f3.friend_id = 7
И така нататък...
Третата заявка ще намери пътя „1 до 2“, „2 до 6“ и „6 до 7“, връщайки броя на 1.
Всяка заявка става по-скъпа (поради по-големия брой присъединявания), така че може да искате да ограничите търсенето в даден момент. Едно страхотно нещо е, че това търсене работи от двата края към средата, което е една проста оптимизация, предложена за търсения по най-краткия път.
Ето как да намерите тези препоръки за общи приятели за член 1:
SELECT f2.friend_id
FROM friends f1
JOIN friends f2
ON f2.member_id = f1.friend_id
LEFT JOIN friends f3
ON f3.member_id = f1.member_id
AND f3.friend_id = f2.friend_id
WHERE f1.member_id = 1
AND f2.friend_id <> f1.member_id // Not ourself
AND f3.friend_id IS NULL // Not already a friend