2011-01-05 137 views
4

說我有一個表了一系列的記錄,我想隨機存在給用戶。我還希望用戶能夠來回分頁,所以我必須堅持某種順序,至少在一段時間內。什麼是「洗牌」數據庫記錄表的最佳方式?

該應用程序基本上只有AJAX,並且它對已經訪問過的頁面使用緩存,所以即使我總是提供隨機結果,當用戶嘗試返回時,他也會得到前一頁,因爲它會從本地加載緩存。

的問題是,如果我只返回隨機的結果,可能有一些重複。每個頁面都包含6個結果,所以要避免這種情況,我不得不這樣做WHERE id NOT IN (1,2,3,4 ...),我會把所有的以前加載的ID。

該溶液的巨大缺點是,它不可能緩存在服務器端任何東西,因爲每個用戶將請求不同的數據。

替代的解決方案可能是訂購的記錄中創建另一列,並洗牌它的每插入時間單位在這裏。這裏的問題是,我需要爲表中的每條記錄設置一個序列中的隨機數,這會佔用與記錄一樣多的查詢。

我使用Rails和MySQL的,如果這是任何意義的。

+1

作爲用戶的隨機數據分頁對我來說並沒有多大意義。如果你稱之爲「6個隨機帖子!」並只是與可能的重複生活在一起,似乎它將主要是你所要求的零工作。 – jdl 2011-01-05 23:46:44

+0

那麼如何回答答案?我很想知道是否有任何解決方案建議適用於您。 – noodl 2011-01-11 11:44:45

回答

7

嘗試這種情況:

mysql> create table t (i int); 
mysql> insert into t values (1),(2),(3),(4),(5),(6); 
mysql> select * from t order by rand(123) limit 2 offset 0; 
+------+ 
| i | 
+------+ 
| 6 | 
| 4 | 
+------+ 
mysql> select * from t order by rand(123) limit 2 offset 2; 
+------+ 
| i | 
+------+ 
| 2 | 
| 3 | 
+------+ 
mysql> select * from t order by rand(123) limit 2 offset 4; 
+------+ 
| i | 
+------+ 
| 5 | 
| 1 | 
+------+ 

注意,rand()函數具有種子值(123)。另請注意,如果您重複最後三個查詢,則每次都會得到相同的結果。

+0

ORDER BY RAND()是最糟糕的,因爲它需要mySQL複製整個表格,爲每行添加一個RAND()值並最終進行排序。 6行表格沒有問題,但行數更多時效率非常低。預計你的mySQL服務器變得越來越慢並且超載。 – Sebastian 2015-02-11 09:25:00

2

我會做以下(假設順序,數字主鍵):

  1. 生成一個隨機數,並將其存儲在用戶的會話
  2. 當通過數據的用戶的頁面,請查詢總行數
  3. 使用存儲在會話中的號碼作爲種子,以在每個請求上生成相同的「隨機」ids順序
  4. Page通過ids並僅檢索與數據庫中的這些id匹配的記錄。
1

如果隨機結果是「大家」,而不是任何特定的用戶,那麼你可以做這樣的事情:(這是Postgres的,應與他人合作)

update mytable set sortorder = random() * 100000000; 

select * from mytable order by sortorder, primarykeyid; 

由於隨機可重複,通過primarykeyid進行二次排序使得排序具有一定的穩定性。

如要刷新緩存然後你可以做到這一點經常。例如,給你一個頁面,比如說每分鐘一次絕對過期。然後每分鐘重新排列排序順序並正常提供頁面。

如果您在整個刷新窗口中收到請求,那麼,是的,您有機會讓不同的頁面獲得相同的結果。您也將有他們擊中時的問題,「後退」,他們很可能無法獲得頁面之前,他們有(因爲它刷新)。

種類歸結爲隨機數據呈現背後的動機是什麼,它會如何工作。它也取決於數據量等。

但是,如果這對你很重要,這是一種緩存友好的方法。它也是無狀態的(不需要會話信息)。

相關問題