2012-11-21 51 views
1

我目前正在MongoDB中的一個項目中從數據庫中隨機抽取新產品。但我的問題不是MongoDB的具體問題,我認爲這是一個通用的數據庫問題。如何保留每個用戶使用的數據列表

該場景:

比方說,我們有一個產品集合(或表)。我們也有一個用戶集合(或表)。每次用戶登錄時,都會顯示10個產品。這些產品從收集/表中隨機選擇。足夠簡單,但問題在於,每次用戶登錄時,都必須提供10種他們從未見過的產品。我能想到的解決這個問題的兩個明顯的方法是:

  1. 每個用戶開始的所有產品自己的私人列表。每次他們獲得這些產品中的一種時,產品都會從其私人列表中刪除。結果是,下次從先前修剪的列表中選擇產品時,它只包含新項目。

  2. 每個用戶都有一個以前看過的產品的私人列表。當用戶登錄時,他們從主列表中選擇10個隨機產品,將每個產品的ID與以前查看的產品列表進行比較,如果該項目出現在先前查看的列表中,應用程序會拋出該項目,選擇一個新項目,並迭代,直到有10個新項目,然後將它添加到以前查看的列表下次。

#1的問題似乎是一個巨大的浪費。你基本上會複製n個用戶的列表數據。同時刪除/添加新項目到系統將是一場噩夢,因爲它必須迭代所有用戶。 #2似乎更可取,但它也有問題。爲了保證10個新產品,您最終可能會向數據庫進行額外的多餘呼叫。隨着用戶越來越多地選擇產品,新產品的選擇越來越少,因此不得不從數據庫中拿走新產品的機會大大增加。

是否有替代解決方案?我首要關心的是性能。我會放棄磁盤空間以優化性能。

+0

選項1看起來很糟糕(特別是如果您打算定期從通用列表中添加和刪除產品),我會選擇選項2.對於選項2,您可以簡單地詢問* *不是*的產品用戶的列表並從該組中隨機選擇。 – NullUserException

+0

是的,我完全同意Null。我只列出了我能想到的唯一選項。我真的不喜歡這兩種解決方案...... –

+0

我唯一的選擇2是,隨着時間的推移,你將擁有一個用戶,他們將擁有以前看過的產品的巨大列表,這可能是一個問題。 – NullUserException

回答

0

這2種方式是完全浪費主存儲器和輔助存儲器。 你想展示2個從未見過的產品,但這是一個真正的必須? 如果你有很多產品,10個隨機產品有很高的獨特性。

3。你可以列出10級隨機的產品,即使不那麼容易,因爲在MySQL,比1和2

0

如果你不介意的id的順序是怎樣隨機你能做到這一點還不太複雜:

創建一個只包含產品ID和隨機整數代理鍵列的隨機表。在第一次登錄時,在列表中隨機選擇一個客戶,然後循環訪問由該關鍵字定購的列表。如果你到達最後,從頭開始重新開始。

客戶記錄將包含他們看到的最後一個產品(來自隨機列表的代理,而不是實際ID)的單個值。然後,您將在登錄後拉動下一個十次,併爲客戶做一次更新。當然,這不會是隨機的。但是這種桌上種子策略是很多更簡單的僞隨機數發生器的工作原理。

我看到的唯一問題是,如果您的產品列表增長得比您的用戶登錄速度更快,那麼他們永遠無法看到列表中出現在他們開始之前的部分。即使如此,有大量產品和非常活躍的用戶,這應該比存儲他們看到的任何東西都要好得多。因此,如果產品以一套僞隨機序列出現並不重要,這可能非常適合您。

編輯:

如果存儲他們開始以及第一條記錄,你仍然可以產生的看到所有事情的清單。這將是價值和最後觀看之間的一切。

0

如何做到這一點:創建一個集合prodUser你將只有產品的id和customersID的列表(誰看過這些產品)。

{ 
    prodID : 1, 
    userID : [] 
} 

當你一個客戶登錄發現尚未分配給該用戶

db.prodUser.find({ 
    userID : { 
    $nin : [yourUser] 
    } 
}) 

(出於某種原因,$不是沒有:-(工作10 PRODID。我沒有時間)在向他展示他的產品之後 - 你可以更新他的prodUser集合,爲了減輕mongos無法找到隨機元素 - 你可以隨機插入元素並找到前10個元素。

一切都應該很快。

相關問題