簡體   English   中英

社交網絡應用程序中友誼的最佳數據庫體系結構

[英]Best database architecture for friendships in a social networking application

我正在Rails的社交網站上工作,目前我可以想到幾種方式可以實現友誼(就像Facebook一樣)。 但是由於很多應用程序的功能將取決於應用程序的這一部分,我有點擔心提交到一個,然后意識到我可以做得更好,然后進行遷移並改變整個事情一個接一個。

如果你們可以建議哪種方式最好,那就太好了。 此外,如果我的架構都不夠好,請隨意建議一個新架構

建築1

友誼的單個表有3列 -

  • user_id(發送請求的用戶的ID)
  • friend_id(收到請求的用戶的ID)
  • pending(保持狀態的布爾值。如果請求被接受,則返回false,否則返回true)

獲得用戶的所有朋友

  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

我能想到的優點 -

  • 與其他體系結構相比,它需要數據庫中最少數量的表和記錄。 我不確定這是否真的有優勢,因為我聽說表中的記錄數不會影響性能。 如果我錯了,請糾正我。
  • 只需要幾個驗證。 首先,user_id在friend_id的范圍內是唯一的。 其次,user_id不等於friend_id。
  • 干密碼。 接受朋友請求只需要查找記錄並只更新一個字段(布爾值 - 待定)。 非友好需要只找到記錄並刪除它

我能想到的缺點 -

  • User.friends和User.friend_requests不是急於加載的,因為它們實際上不是ActiveRecord關聯。 從長遠來看,這可能是一個主要的減速點,尤其是搜索功能,我想要通過一些共同的朋友對結果進行排名。

建築2

兩張桌子。 一個用於友誼,一個用於朋友請求 - 友誼將像 -

  • user_id(友誼中的一個用戶的ID)
  • friend_id(友誼中其他用戶的ID)

朋友請求表也會像 -

  • user_id(友誼中的一個用戶的ID)
  • friend_id(友誼中其他用戶的ID)

獲得用戶的所有朋友 -

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

我能想到的優點是 -

  • User.friends和User.friend_requests是可加載的。 這可以提高很多地方的性能,我在一個查詢中急切地加載一堆用戶的朋友,而不是一遍又一遍地打擊數據庫並做User.friends

我能想到的缺點是 -

  • 友誼的重復條目。 為了使User.friends關聯工作,我將不得不為一個friendhsip創建2個條目。

| id  | user_id | friend_id |  
-----------------------------
|  1  |   15    |    30     |
-----------------------------
|  2  |   30    |    15     |
-----------------------------
  • 這將需要復雜的驗證,例如:如果第1行是有效的,則驗證第2行的存在(在上面的示例中)。 還有很多其他人
  • 建立友誼將是復雜的。 它需要
    • 從好友請求表中刪除條目
    • 在friends表中創建2行
    • 我知道這聽起來不是一個真正的缺點,但對我來說,創建/刪除3個相互依賴的條目似乎有很多錯誤

我想最后這個問題歸結為 -

數據庫(體系結構1)中具有較少數量(一半)的條目與更多條目(體系結構2)相比具有顯着優勢嗎?

單個友誼有兩個條目有多糟糕? (建築2)

我會推薦第二個模型,為friend_requestfriendship分開表。 雖然這些表目前可能保存完全相同的數據,但隨着時間的推移,我預計它們會分歧。

以下是可能發生的一些方法: -

  • 你想讓他們和朋友的請求一起發送信息(“嘿,記得我從學校開始”)
  • 您決定要保留有關好友請求的統計信息,例如請求何時發出
  • 您決定要在數據庫中保留拒絕的好友請求(拒絕進一步請求一旦被拒絕)

因為它們是不同的東西,所以應該創建不同的表而不是重載單個表。 創建表格並不困難。

你應該在表中放兩行,代表關系的兩個方向嗎? 這是規范化績效的問題。

規范化答案僅包括一行。 這個型號:

  • 更容易獲得更新/插入/刪除,因為只需要擔心一行
  • 由於您需要從兩個方向進行查詢,因此查詢更加困難且速度更慢

反規范化答案(因為存儲了重復數據)是包括兩行:此模型:

  • 更新/插入/刪除更難,因為有兩行保持同步
  • 查詢速度更快,因為您可以從一個方向查詢

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM