Оптимизация запроса для поиска общих друзей в Facebook

Предполагая, что таблица друга в Facebook выглядит следующим образом - userId | friendIdКак бы вы написать SQL-запрос, чтобы найти общих друзей между двумя друзьями? У меня есть приведенный ниже код, который работает для двух друзей A и B. Однако я чувствую, что он недостаточно оптимизирован, и я надеялся, что вместо этого смогу выполнить тот же запрос с объединениями. Две области, где я запутался:

  1. Идентификатор конкретного пользователя может находиться в любом из столбцов в зависимости от того, кто инициировал запрос на добавление в друзья. Если бы A послал запрос B, userId был бы A, а friendId был бы B. Следующий запрос, который я имею, обрабатывает этот сценарий, но как бы вы сделали то же самое с JOIN?
  2. Как FB рекомендует добавить кого-то в друзья? Как это будет выглядеть в запросе?

Есть много похожих вопросов о переполнении стека / Интернете, но ни один из них не кажется точным на 100%!

Я ищу запрос к серверу MS SQL, но любой язык SQL должен работать.

SELECT *
FROM (
SELECT CASE WHEN userId = 'A' THEN friendId ELSE userId END AS mutualFriends
FROM friendsTable 
WHERE userId = 'A' OR friendId = 'A'
UNION
SELECT CASE WHEN userId = 'B' THEN friendId ELSE userId END AS mutualFriends
FROM friendsTable 
WHERE userId = 'B' OR friendId = 'B'
) A
WHERE mututalFriends NOT IN ('A','B')

1 ответ

Вы указали запрос UNION, он возвращает союз друзей A и B.

Приведенный ниже запрос возвращает JOIN друзей A и B - список людей, которые дружат с A и B.

Скрипка: DB-Fiddle

SELECT a_mutualfriendid AS mutualfriendid FROM 

(SELECT distinct a_mutualfriendid
FROM (SELECT 
  case 
    when userid = 'A' then friendid 
    else userid 
  end as a_mutualfriendid
FROM friendsTable
WHERE userid in ('A') or friendid in ('A')
) a_friends
WHERE a_mutualfriendid NOT IN ('B')) a

INNER JOIN

(SELECT distinct b_mutualfriendid
FROM (SELECT 
  case 
    when userid = 'B' then friendid 
    else userid 
  end as b_mutualfriendid
FROM friendsTable
WHERE userid in ('B') or friendid in ('B')
) b_friends
WHERE b_mutualfriendid NOT IN ('A')) b

ON a_mutualfriendid = b_mutualfriendid

Что касается того, как Facebook хранит данные, это конфиденциальная информация, и сотрудники, вероятно, не смогут ответить.

Вот предположение: учитывая, что если X дружит с Y, любая из них может "игнорировать" другую, вероятно, в базе данных есть две записи: "X дружит с Y" и "Y дружит с X". Первоначальный запрос от X создает первую запись, а действие принятия от Y создает вторую запись. После этого каждая запись может содержать информацию о том, должны ли сообщения друзей отображаться в фиде других пользователей.

Другие вопросы по тегам