朋友表为社交网站

时间:2012-08-13 17:46:25

标签: mysql social-networking

我一直在社交网站上工作。这里用户请求另一个用户成为他的朋友(朋友请求)。我想到了一个看起来像

的“朋友”表
Table Name: Friends
Coloumns :
    User1   - Int - FK
    User2   - Int - FK
    Request - Enum('0','1')
    Time    - DateTime

PK - (User1, User2)

在请求字段中,当User1向User2发出请求时存储“0”,并且当User2批准该请求时存储“1”。

当我想要检索用户的所有朋友时,问题就出现了。我每次都要检查Request字段是'0'还是'1'。还有另一种方法吗?如果我有另一个表存储朋友请求的所有细节,那会更好吗?

2 个答案:

答案 0 :(得分:1)

我会将您的数据分成requestsfriendships。批准request后,将其转换为friendship。它们实际上是两个不同的对象,应该这样对待。

Requests ::
  requesting_user_id : int()
  requested_user_id  : int()
  date_requested     : datetime()
  status_id          : int()

Statuses ::
  (Active, Declined, Accepted, Ignored)

Friendships ::
  friendship_id      : int()
  user_id            : int()
  friend_id          : int()

如果请求被拒绝,或者有一个列(以防止人们反复请求相同用户的友谊),可能会删除该请求。您必须将请求转换为两个友谊(每个方向一个)才能轻松编制索引

SELECT friend_id FROM friendships WHERE user_id = ? 

答案 1 :(得分:1)

在评论中,您基本上声明已建立的友谊(与请求相对)在您的设置中始终是对称的。在这种情况下,您基本上有两个选项:您可以将它存储在两行中,也可以通过匹配任一列来选择它。前者将产生更简单的查询,但后者将确保对称性是数据库结构中固有的,并且将避免存储重复数据。所以我会选择后者,即某种形式的WHERE (User1 = XX or User2 = XX )。查询可能需要两倍的时间,因为只有一列的查询会在相同数量的行上执行,但由于行数只是其他存储方案的一半,因此净效应在性能方面应该可以忽略不计。

对于请求或已建立的友谊,您是否需要单独的表取决于这两者在相关数据和应用程序中的控制流方面的相似程度。因此,例如,如果您想向用户显示单个列表,该列表既显示了已建立的友谊,也显示了未决请求,可能使用不同颜色或其他任何颜色,但在同一列表中,则在数据库中拥有单个表将更多不合适。另一方面,如果你主要是分别处理请求和友谊,那么拥有两个表会更自然。如果在某个时候,你决定一个freindship需要像share_calendar这样的属性而一个请求需要confirmation_key等属性,那么你最好使用不同的表。

如果您决定将其作为单个表格,我会建议枚举的更多描述性值,例如调用列status以及值requestedestablished。举个例子,我乍一看将request = 1的值解释为“这只是一个请求,而不是一个既定的自由”,与你所关联的含义完全相反。当不同的人需要维护代码时,这种模糊性可能导致错误。几年之后,你就会成为一个与你现在不同的人,即使你自己也可能会错误地解释你的旧代码。所以在那里描述一下。

还有一点需要注意:您可能始终使用视图来调整数据库对查询的显示方式。例如,您可以创建视图

CREATE VIEW SymmetricEstablishedFriends AS
SELECT User1 AS Me, User2 AS Friend, Time
FROM Friends
WHERE Status = 'established'
UNION
SELECT User2 AS Me, User1 AS Friend, Time
FROM Friends
WHERE Status = 'established'

这会将数据限制为已建立的友谊,并会为您提供对称化的功能。在查询中使用此类视图,可以避免在每个查询中处理表结构的所有详细信息。如果你改变这些细节,那么改变的地方就会减少。