關系型數據庫中好友關系的設計


  接到需求,設計一群注冊用戶的好友關系,各自要能查詢到自己的好友列表。最早想過用圖數據庫來進行好友關系存儲,但身邊沒有成熟的案例,網上的資料也比較少。所以還是決定采用傳統關系型數據庫MySQL來進行設計。

  好友關系,如果簡單設計成一張表的話,隨着注冊用戶的增多,好友關系勢必會呈指數級增加,當系統中用戶為10個人時,那么完全添加好友的話,關系數據(假設A和B是好友只有一條數據)則為(9+8+...+1)即55條;當系統中注冊用戶的數量增長到1000個人時,關系數據最大值為(999+998+...+1)即499500。所以如何設計系統,讓用戶快速查詢到好友關系,是個難點。

  這里給出一種思路:根據注冊用戶的某一個字段(如用戶ID),將它的所有好友關系集中存放到一張表中,而不同的用戶,會根據這個ID的不同,將它們的好友關系分別散列在不同的數據表中。這樣達到了將數據表數據分散,減輕單表壓力的目的。但是,按照這個思路設計時,好友的關系必須是雙向的,否則A和B的關系,到底是以A的ID進行散列還是B的ID進行散列呢?這樣一來,好友的關系數增加了1倍,但是如果散列的足夠均衡,這個結果也是可以接受的。市面上很多好友關系在進行設計時,也是采用雙向的方式,即A加了B,B同意之后,即建立了雙向好友關系,當A刪除B的好友關系時,B查詢自己的好友列表時,會發現A還在,只有B再刪除A,雙向的好友關系才會消除。

  接下來的工作是如何將這個散列方案實施下來。這里有兩個問題,一個是在初期規划時,我們可能並不知道這個社交群體最終的規模,即無法在初期就創建固定數量的關系表,這個表一定是當容量達到一定規模時動態增長的;第二個是,在追求每張表的數據均衡時,我們還要考慮一種情況,即如果初期存入的一批用戶被散列到某張表中(即該批用戶指向的好友關系存在該表中),而恰好該批用戶的好友關系增長速度遠遠超過其他批次的用戶,造成該表數據急速增長的情況,該如何處理?在此背景下,我們來考慮這個被散列計算的字段該怎么設計。

  對於以上問題,一個簡單的思路如下:假設現在有t_a,t_b,t_c,t_d四張表,都用於存放關系,在它們遠沒有達到存儲規划上限時,我們可以就簡單根據現有的各自表的容量,來決定注冊用戶該字段計算出來該指向哪張表。比如a,b,c現在容量都達到了1000條,而d表的容量才100條,那么在注冊用戶時,我們就將用戶該字段設計成計算結果指向d表。我們還可以設計一個容量因子,在單表數量超過預設上限*該容量因子(如0.7)時,即停止將新用戶的字段值設計成計算結果指向該表。另外,如果我們設定一個好友關系上限,如最多500個好友,那么預設的表數據上限除以這個數量限制可以得到這張表最多存放多少個不同的用戶,這種做法可以保證這些關系表數量不會異常增長到超過我們預設的上限。

  但是,如果我們的系統允許用戶無節制的增加好友,那么當用戶量不斷增長時,上述方案就無法在系統規模不斷增長之后還能保證單表關系數量不會突破限制。此時,限制一個用戶所有的好友關系在某個單表的方案已經不現實,但我們還是應該盡量這么做,對於單個用戶在單表中設置一個關系數量上限,當他的好友關系超過這個數量時,把它存在另外一張表中。那么,如何知道這個用戶是否圖破了單表存儲的設定上限,擁有多張表存儲了好友關系,我們可以在注冊用戶的字段時加一個標記字段,那么查到該用戶即可知道這個信息,對於已經突破了單表設定上限的,我們可以再加一張表-突破關系存放表,某用戶突破一次,那么在該表中即存一條數據,其中一個字段的值與該用戶原先的散列計算值匹配起來可以確定這次突破后存放的新表名稱。這樣既可快速定位到這些新表的名稱,從而查詢出所有的好友關系,另外,好友關系表中對單表單用戶的好友關系數量做出了限制,所以當有N個表存放了該用戶的數據時,那么好友的數量即,(N-1)*固定容量+第N張表的好友數量,所以統計好友總數也不復雜,只需要知道第N張表的數量即可推算出總數。

  暫時想到這么多,歡迎評論留言補充思路或者其它拓展點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM