#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 выбора