Как моделировать дружеские отношения

#mysql #database-design #relationships #table-structure

#mysql #база данных-дизайн #отношения #структура таблицы

Вопрос:

Я пытался выяснить, как это сделать, и даже при просмотре других примеров я не могу разобраться в этом, поэтому, возможно, я смогу получить персональную помощь.

У меня есть две таблицы, users_status и friendships .

В users_status таблице у меня есть поле userid и несколько других. В friendships таблице у меня есть поля request_to , request_from , и friendship_status .

По сути, я хочу получить все сообщения о состоянии текущего пользователя И тех, кто является друзьями текущего пользователя (которые я могу указать в своем PHP, используя переменную $ userid).

Вот пример структуры friendships таблицы. Когда отправляется запрос на добавление в друзья, идентификаторы пользователя отправителя и получателя помещаются в таблицу с friendship_status равным 0. Когда запрос принимается, для friendship_status устанавливается значение 1, и эти двое теперь друзья.

 friendship_id   request_from    request_to  friendship_status
1               111248          111249      1
2               111209          111249      1
3               111209          111248      0
11              111209          111259      1
5               111252          111209      1
12              111261          111209      1
  

Я понимаю, что это может быть даже не лучшая структура для определения дружеских отношений, тем более, что сайт основан на отношениях, и часто используется необходимость проверки дружеских связей.

Возможно, было бы лучше иметь две отдельные таблицы для friend_requests и friendships ? Если да, то как мне структурировать / управлять friendships таблицей?

Ответ №1:

Вы можете использовать объединение таблиц (например http://dev.mysql.com/doc/refman/5.0/en/join.html ), чтобы найти все запросы.

На самом деле вы можете использовать подзапрос здесь:

 SELECT * FROM users_status WHERE userid = "$userid" 
    OR userid in (SELECT request_to   FROM friendships where request_from = "$userid" AND friendship_status = 1)
    OR userid in (SELECT request_from FROM friendships where request_to   = "$userid" AND friendship_status = 1)
  

$userid замените своим идентификатором пользователя

Комментарии:

1. Я понимаю, что JOIN — это вариант, и я попробовал его, но я не знаю, как заставить его работать с моей конкретной ситуацией. Вот почему я опубликовал вопрос. Мне нужна более персонализированная помощь с этим.

2. @vertigoelectric на самом деле вам не нужно соединение — достаточно подзапроса. Я обновил свой ответ

3. Если пользователь запрашивает у текущего пользователя его дружеские отношения, и текущий пользователь принимает, тогда этот запрос не будет работать правильно, потому что этот пользователь не будет возвращен как друг. Я прав?

4. @MostyMostacho да, вам также нужно будет проверить другой случай, который является аналогичным подзапросом. обновление ответа

5. @Foo Bah, я тоже пробовал подзапрос. Я попробовал ваш пример, но, похоже, он не проверяет должным образом, находится ли идентификатор пользователя в request_to ИЛИ request_from . Я тестировал его как пользователя, который отправил запрос пользователю, который его принял. Пользователь может видеть сообщения о статусе от себя и друга, но пользователь не может видеть сообщения о статусе от пользователя, который отправил ему запрос на добавление в друзья, хотя они оба друзья. Я поменял request_to местами и request_from в вашем примере, и тогда пользователь больше не мог видеть сообщения пользователя, ожидаемое изменение (но пользователь все еще мог видеть оба, что было странно).

Ответ №2:

Самая простая схема, о которой я могу думать, это:

 PENDING_FRIENDSHIPS(request_from, request_to)
FRIENDSHIPS(request_from, request_to)
  

Я также удалил идентификатор, потому что оба поля в обеих таблицах будут составными первичными ключами (request_from, request_to).

Чтобы получить всех друзей от текущего пользователя, просто запустите:

 select * from friendships
where $currentUser = request_from OR $currentUser = request_to
  

Это вернет оба столбца, и вам придется удалить в PHP текущего пользователя.

Другой способ получить всех друзей из этой схемы — запустить ОБЪЕДИНЕНИЕ:

 select request_from from friendships
where request_to = $currentUser
UNION
select request_to from friendships
where request_from = $currentUser
  

Недостатком этого решения является то, что вы используете 2 выбора