嗯,我来晚了,但这是我的出价。
首先是桌子:
User
-id
Type
-id
Relationship
-user_id_1
-user_id_2
-type_id
现在,我想保持我的类型表简单。因此,我添加的类型仅代表单个用户与另一个用户的关系,不代表双向关系。例如:
friend
ignored
这使添加新的类型很容易。我不需要考虑或创建所有类型的所有可能组合。我只需添加新类型即可。
建立友谊,需要在关系表中输入两个条目。如果两个用户都同意他们是朋友,他们就是朋友。如果只有一个人说他与另一个人是朋友,而另一个人将他拦截,他们就不是朋友。
进行查询非常简单。这里是如何在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
我也认为这种方法更“交易安全”。想象一下,你向某人发送好友请求,然后随后屏蔽了那个人。如果那个人后来接受了好友请求,这并不重要。它不会改变关系的状态,因为它们是完全独立的。
如果您有一个表示双向关系的单一类型,那么您将被迫在代码中进行某种评估,以确定朋友接受朋友请求后关系的新状态应该是什么。如果您不这样做,则可能会解除阻止用户并使该人成为已阻止用户的朋友。
我更喜欢在数据库层面上处理这个问题。如果你有一群程序员在应用程序上工作,不久之后就会有人在某个地方忘记了这个问题,导致产生难以找到的错误。