Дизайн базы данных: лучшая структура таблицы для захвата отношений между пользователем и другом? - PullRequest
31 голосов
/ 18 декабря 2008

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

User
=====
Id
Name
etc...

UserFriend
===========
UserId
FriendId
IsMutual
IsBlocked

Ответы [ 13 ]

0 голосов
/ 26 июня 2018

Насколько я понимаю, дружба - это результат отношений между двумя пользователями (Пользователь1 и Пользователь2), а также потому, что пользователь1 может иметь 0 или более пользователей в качестве друзей и наоборот пользователя2, поэтому таблица соединений Посередине «друг» представляет эти отношения следующим образом:

User1 id (int) имя пользователя (строка)

User2 id (int) имя пользователя (строка)

Друг ---- id (int) user1_Id (int) user2_Id (int) active (bool)

И user1_Id, и user2_Id являются FK в таблице Frind

Надеюсь, я прав.

0 голосов
/ 10 августа 2017

Ну, я опаздываю на вечеринку, но вот моя ставка.

Первые столы:

User
-id

Type
-id

Relationship
-user_id_1
-user_id_2
-type_id

Теперь я хочу, чтобы моя таблица типов была простой. Таким образом, типы, которые я добавляю, представляют только отношения одного пользователя с другим. Они никогда не представляют двунаправленные отношения. Например:

friend
ignored

Это облегчает добавление новых типов. Мне не нужно думать или создавать все возможные комбинации всех моих типов. Я просто добавляю новый тип.

Чтобы установить дружбу, вам нужно 2 записи в таблицу отношений. Если оба пользователя согласны с тем, что они друзья, они друзья. Если только один говорит, что он дружит с другим, а другой заблокировал его, они не друзья.

Делать запросы очень просто. Вот как вы получаете всех друзей в MySQL:

SELECT u.* FROM user u
LEFT JOIN relationship r1 ON u.id = r1.user_id_2
LEFT JOIN relationship r2 ON u.id = r2.user_id_1
WHERE r1.user_id_1 = <my_user_id> # my relationship with them
AND r1.type_id = <friend_type_id> # i say i'm a friend
AND r2.user_id_2 = <my_user_id> # their relationship with me
AND r2.type_id = <friend_type_id> # they say they're friends

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

Если бы вместо этого у вас был один тип, который представлял двунаправленные отношения, вы были бы вынуждены сделать своего рода оценку в своем коде того, каким именно должно быть новое состояние отношений, как только друг принял запрос друга. Если вы этого не сделаете, вы можете в итоге разблокировать пользователя и подружить его с пользователем, которого он заблокировал.

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

0 голосов
/ 07 февраля 2014

Я думаю, вам следует создать две таблицы:

1. пользователь
u_id int
u_username строка
balahhh ............

2. дружба
fs_id int
related_id int
related_id int

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...