2011-01-05 9 views
4

レコードがたくさんあるテーブルがあり、ランダムにユーザーに提示したいとします。私はまた、ユーザーが前後に改ページできるようにしたいので、少なくともしばらくは何らかの命令を守らなければなりません。データベースレコードのテーブルを "シャッフル"する最も良い方法は何ですか?

アプリケーションは基本的にAJAXのみであり、既に訪問したページにキャッシュを使用していますので、いつでもランダムな結果を返しても、ユーザーが戻ろうとすると、ローカルページからロードされるため、キャッシュ。

ランダムな結果のみを返すと、重複がある可能性があるという問題があります。各ページには6つの結果が含まれているので、これを防ぐために、以前に読み込まれたすべてのIDを置く場所のようなものをWHERE id NOT IN (1,2,3,4 ...)とする必要があります。

このソリューションの大きな欠点は、すべてのユーザーが異なるデータを要求するため、サーバー側で何もキャッシュできないことです。

代替ソリューションは、レコードを注文するための別の列を作成すること、およびシャッフルかもしれないそれはここにすべての挿入時間単位。ここで問題となるのは、テーブル内のすべてのレコードに対してシーケンスの乱数を設定する必要があることです。これは、レコードと同じくらい多くのクエリが必要になります。

私はRailsとMySQLを使用していますが、これは関連性があります。

+1

ユーザーとしてのランダムデータによるページングは​​、私にはあまり意味がありません。あなたが「6つのランダムな投稿」のような名前を付けた場合、可能な複製と一緒に暮らしていたのですが、ほとんどの場合、あなたは何も求めていないようです。 – jdl

+0

回答にはどうしたらいいですか?私は、ソリューションのいずれかがあなたに適しているかどうかを知ることに興味があります。 – noodl

答えて

7

この試し:のrand()関数はシード値(123)を有すること

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 | 
+------+ 

注意。また、最後の3つのクエリを繰り返すと、毎回同じ結果が得られることに注意してください。

+0

ORDER BY RAND()は、テーブル全体をコピーし、各行にRAND()値を追加し、最後にソートを行うためにmySQLを必要とするため、最悪です。 6行テーブルでは問題はありませんが、さらに多くの行では非常に非効率です。 mySQLサーバーが遅くなり過負荷になることが予想されます。 – Sebastian

2

私は、次の(シーケンシャルと仮定すると、数値の主キー)を行うだろう:

  1. は、乱数を生成し、ユーザーのセッションに格納し
  2. ときのためのデータを介してユーザページ、クエリ合計行
  3. 各要求で同じ 'ランダム'の順序を生成するために、セッションに格納されている番号を使用してください。
  4. idsを介してページし、データベースからこれらのIDに一致するレコードのみを取得します。
1

ではなく、特定のユーザーよりも、あなたはこのような何かを行うことができ、「みんなのための」ランダムな結果がされている場合:(これはPostgresのためのもので、他の人と動作するはずです)

update mytable set sortorder = random() * 100000000; 

select * from mytable order by sortorder, primarykeyid; 

ランダム複製可能性があるため 、 primarykeyidによるセカンダリソートは、ソートに安定性を与えます。

この操作は、キャッシュを更新する頻度で行うことができます。たとえば、毎分のような絶対的な有効期限をページに与えます。そして毎分、ソート順を更新し、ページを正常に配信します。

リフレッシュウィンドウでリクエストを受け取った場合、異なるページで同じ結果が得られる可能性があります。あなたはまた、彼らが以前に持っていたページを得ることができないかもしれない "後ろに"ヒットしたときの問題を抱えています(リフレッシュしてから)。

ランダムデータの提示の背後にある動機は、これがどれだけうまくいくかということになります。また、データ量などによっても変わります。

これは、キャッシュを使用してこれをオフにする方法です。ステートレスです(セッション情報は必要ありません)。

関連する問題