社交网络应用程序中友谊的最佳数据库架构

Best database architecture for friendships in a social networking application

我在 Rails 的一个社交网站上工作,目前我能想到几种实现友谊的方法(就像 Facebook)。但是由于应用程序的很多功能都将依赖于应用程序的这一部分,所以我有点担心提交一个,然后意识到我可以做得更好,然后进行迁移并更改整个一件一件的事情。

如果你们能建议最好的方法,那就太好了。此外,如果我的 none 个架构足够好,请随意推荐一个新架构

架构 1

一个 table 的友谊有 3 列 -

获取用户的所有好友

  def friends
    user_ids = Friendship.where(
      '(user_id = :id OR friend_id = :id) AND pending = false',
       id: self.id
    ).pluck(:user_id, :friend_id)
     .flatten
     .uniq
     .reject { |id| id == self.id }

    users = User.where(id: user_ids)
  end

获取用户收到的所有好友请求 -

def friend_requests
  friend_ids = Friendship.where('friend_id = ? AND pending = true', self.id).all
  users = User.where(id: friend_ids)
end

我能想到的优点-

缺点我能想到的-

架构 2

两个 table。一种用于友谊,一种用于朋友请求 - 友谊会像 -

好友请求 table 也会像 -

获取用户的所有好友 -

has_many :friendships,
  class_name: "Friendship",
  foreign_key: :user_id,
  primary_key: :id

has_many :friends,
  through: :friendships,
  source: :friend

获取用户的所有好友请求 -

has_many :friend_requests,
  class_name: "FriendRequest",
  foreign_key: :friend_id,
  primary_key: :id

我能想到的优点是 -

我能想到的缺点是 -


| id  | user_id | friend_id |  
-----------------------------
|  1  |   15    |    30     |
-----------------------------
|  2  |   30    |    15     |
-----------------------------

我猜最后问题归结为 -

数据库中条目数较少(一半)(架构 1)是否比条目较多(架构 2)具有显着优势?

一个友谊有 2 个条目有多糟糕? (架构二)

我推荐第二种模式,friend_requestfriendship 分开 table。虽然这些 table 目前可能持有完全相同的数据,但随着时间的推移,我预计它们会有所不同。

以下是发生这种情况的一些可能方式:-

  • 您想允许他们在发送好友请求的同时发送消息 ("Hey, remember me from school")
  • 您决定要保留有关好友请求的统计信息,例如发出请求的时间
  • 您决定要在数据库中保留被拒绝的好友请求(一旦被拒绝就不允许进一步的请求)

因为它们是不同的东西,所以您应该创建不同的 table 而不是重载单个 table。创建 table.

并不难

是否应该在 table 中放置两行,代表关系的两个方向?这是规范化 vs 性能 的问题。

规范化答案是只包含一行。这个型号:

  • 更容易获得 update/insert/delete 因为只需要担心一行
  • 查询起来更困难也更慢,因为您需要从两个方向查询

去规范化答案(因为存储了重复的数据)是包括两行:这个模型:

  • 更难 update/insert/delete 因为有两行要保持同步
  • 查询速度更快,因为您可以只从一个方向查询