2012-05-28 58 views
2

我有一個應用程序(對於給定的twitter用戶),獲取您關注的twitter用戶列表,但不會跟着你回來。它這樣做:什麼是這個數據集的最佳數據庫?

  • 比較兩個列表,其中一個來自時間x和時間y,也看看是否有更多的人跟着你回來或更少。
  • 看看twitter用戶x需要多長時間才能關注你。
  • 看看有多少銳推/評論所花費的用戶X跟着你回來

我想出了一個簡單的方法只是一個有一個過許多屬於關係瓦特/用戶,人們不繼你回來了,如:

User table 
-id 

TwitterUser table 
-user_id 
-timestamp 
-isFollowing 

所以W/SQL是我的模式可以得到所有的非追蹤回用戶給定用戶,他們可以通過時間戳進行比較,以符合上述要求。

但是,我希望有一個更好的DB後端來表示這個數據集比sql數據庫。我一直在嘗試w/redis,但不知道如何把它關掉。

我在想也許一個文件存儲 - b/c所有我想要做的是採取兩個數據集的差異。或者更確切地說:我想區分兩個twitter用戶ID列表。

任何想法?

回答

5

比較兩個數組的Bruteforce方法將具有O(N * M)的時間複雜度,其中N和M是數組的大小。因此,我們應該使用一些智能數據結構來存儲它們,以便高效地完成此操作。

我已經想出以下方法:

  1. 嘰嘰喳喳IDS'的列表是一組,因爲ID是唯一的。 Redis支持 集,並允許執行不同的集合操作。假設您有兩套 的鑰匙ids_at_time_xids_at_time_y。 元素加入他們使用SADD 像這樣:

    SADD ids_at_time_x "15424" 
    

    當你準備執行DIFF執行

    SDIFF ids_at_time_x ids_at_time_y 
    

    這將從ids_at_time_x返回ID列表是不 存在ids_at_time_y。如果你想要做反向操作, 即檢索不存在於ids_at_time_x ID列表, 只是交換參數:

    SDIFF ids_at_time_y ids_at_time_x 
    

    大約那麼sdiff的最好的事情是,它非常有效地運行 - 時間複雜度爲O(N)其中N是 這2組元素的總數。即使您執行2個差異操作,時間複雜度仍然是線性的。

  2. 將它們存儲爲排序列表。 Redis支持排序集。當添加 ID,你必須包含元素的得分(Redis的會基於分數排序)相等於ID在你的 情況:

    ZADD ids_at_time_x 15424 "15424" 
    

    當列表是準備好了,我們找回他們與它們進行比較在 的代碼中。這裏是僞代碼:

    n = size of A 
    m = size of B 
    i = 0 
    j = 0 
    setA = [] // List of elements that present only in A 
    setB = [] // List of elements that present only in B 
    intersection = [] // List of elements that present in A and B 
    
    while i < n or j < m { 
        if j == m { 
        setA.add(A[i]) 
        i = i + 1 
        } else if i == n { 
        setB.add(B[j]) 
        j = j + 1 
        } else if A[i] < B[j] { 
        setA.add(A[i]) 
        i = i + 1 
        } else if B[j] < A[i] { 
        setB.add(B[j]) 
        j = j + 1 
        } else { 
        intersection.add(A[i]) 
        i = i + 1 
        j = j + 1 
        } 
    } 
    

    說明:我們使用A和B排序的事實。我們有兩個索引,都從零開始。如果A [0]小於B [0],我們知道 A [0]僅存在於A中,因此我們將它添加到列表setA和 中,增加索引號爲 。一個一個。如果B [0]小於A [0],我們將B [0] 添加到列表setB,並將B的索引增加1。如果A [0] == B [0]我們 將A [0]添加到交點列表並增加兩個索引。 這個代碼也可以以線性時間O(N),其中N是既 元素和B的總數

    注意,這種方法將可以返回排序列表的任何數據庫的工作,這意味着你可以存儲它在傳統的SQL數據庫中並使用ORDER BY twitter_id檢索列表)。

看看Redis支持的所有Data types及其命令的完整列表,它們都很好地記錄在案。 Redis也有許多語言的官方客戶端,所以這應該不成問題。 您仍然可以將重要數據存儲在SQL數據庫中,並讓Redis處理ID列表。

+0

非常有趣的回覆 - 謝謝。我還沒有考慮過增長率分析,但這是一個非常重要的考慮因素。我正在考慮你的第一個設計,但是如果我想將一組ID與一個用戶相關聯,那麼我應該只將用戶ID添加到密鑰中?例如:SADD user_a_ids_at_time_x「15424」還是那個糟糕的redis設計? – eggie5

+1

@ eggie5在密鑰中包含用戶標識是完全有效的。通常情況下,程序員使用':'作爲分隔符,所以持有一個集合的鍵可能遵循像'user:$ USERID:ids:$ UNIXTIMESTAMP'這樣的模式,例如:'user:153343:ids:1337939983'。使用類似於此的模式,您將能夠動態構建密鑰。 [Redis的官方微博克隆](http://redis.io/topics/twitter-clone)對初學者來說是一個不錯的閱讀 – galymzhan

+0

好的,我會看看twitter克隆示例和關鍵方案。 – eggie5

0

neo4j(http://neo4j.org)是一個數據庫引擎,用於將數據存儲爲圖形。我沒有任何實際使用neo4j的經驗,但它似乎是一個很好的選擇。

+0

你爲什麼認爲這將是一個很好的圖形表示? – eggie5

+0

一組Twitter用戶以及他們之間的關係固有地形成了一個有向圖,其中每個用戶都是一個節點,每個關係都是從一個節點到另一個節點的邊。 –

+0

好的,但是你認爲一張圖表仍然適用,因爲我只是在時間x,y,z ......拍攝了一個用戶a的沒有跟隨的朋友的快照? – eggie5

相關問題