2011-04-28 89 views
1

我有一個建立在Elgg(php + mysql)框架之上的社交網站。我的目標是獲得給定用戶的所有朋友,以及這些朋友之間的朋友關係。如何通過社交網絡sql數據庫中的單個查詢獲取朋友的社交地圖?

所有我需要的信息是在兩個表:

  • ,用戶都能通過一個稱爲GUID唯一ID標識的「用戶」表
  • 和「關係」表,其中的朋友關係,分別由(guid_one,「friend」,guid_two)三聯

Elgg中的朋友關係既可以是單向的,也可以是雙向的,它更像Twitter的「跟隨」關係。關係三元組的唯一性是有保證的。考慮(1,「喬」),(2,「傑克」)(3,「吉姆」)用戶和以下關係(1,「朋友」,2),(2,「朋友」,1),(1, 「朋友」,3),(2, 「朋友」,3),這可以解釋爲

  1. 喬和傑克共同的朋友(跟隨對方)
  2. 吉姆後接喬和傑克

我希望得到什麼是

  • 按照關係數量的降序(即,對於任何給定用戶的朋友之間的所有關係的列表)
  • 。列表關係首先對於那些誰遵循我的大多數朋友的朋友)
  • 最好在一個單一的查詢

什麼是最有效的方式做到這一點?

編輯到目前爲止,我有這樣的:

SELECT 
    u1.guid, u1.name, u2.guid, u2.name 
FROM 
    users u1 
INNER JOIN relationships r1 ON 
    (u1.guid = r1.guid_one AND r1.relationship = "friend") 
INNER JOIN users u2 ON (r1.guid_two = u2.guid) 
INNER JOIN relationships r2 ON 
    ((r2.guid_one = xxx AND r2.guid_two = u1.guid) 
    OR (r2.guid_two = xxx AND r2.guid_one = u1.guid)) 
INNER JOIN relationships r3 ON 
    ((r3.guid_one = xxx AND r3.guid_two = u2.guid) 
    OR (r3.guid_two = xxx AND r3.guid_one = u2.guid)) 

其中xxx代表用戶的GUID我感興趣的還有與此兩個主要的問題:它不是由關係的數量排序,由於很多連接,它的速度很慢。同樣,它也只有一種方式的關係(誰跟隨我的朋友之間的關係) - 但是我認爲這可以通過工會解決。

任何想法,以改善呢?

回答

1

您可以對存儲過程執行BFS。 用給出的用戶初始化表,並且BFS的每一步都會將此表中用戶的朋友插入此表中。距離(或跳數)可以是此過程的參數。


編輯: BFS工作原理(wikipedia)。 如何存儲過程的工作(mysql),循環和遞歸(mysql)和stackoverflow

+0

可以鏈接我在更多的細節解釋的任何資源如何實現這一點?謝謝! – 2011-04-28 09:00:59

+0

@Andras:請參閱編輯答案 – Dan 2011-04-28 14:13:16

+0

+1以顯示BFS,但不使用存儲過程的單個查詢將是首選解決方案。 – 2011-04-29 15:51:24