2009-06-17 12 views
3

PHP & CodeIgniterベースのWebサイトでは、ユーザーはさまざまなアクションの評判を得ることができますが、スタックオーバーフローとは異なります。評判が授与されるたびに、user_idという新しいエントリが作成され、アクションが報われ、そのポイントの価値(例えば評判10)が得られます。同時に、usersテーブルのフィールドreputation_totalが更新されます。異なる時間範囲にわたるポイント合計のパーセンタイルランクを計算するにはどうすればよいですか?

これはすべて参考フレームなしでは意味がないので、すべてのユーザーにユーザーのパーセンタイル順位を表示したいと考えています。完全な評判のために、それは十分に簡単だと思われる。 user_id1138であるとします。 usersテーブルのユーザー数をreputation_total未満の人数にカウントし、合計ユーザー数を数え、除算して評判が低いユーザーの割合を鉱山よりも見つけることができます。それはユーザー1138のパーセンタイルのランクですよね?簡単!

しかし、私はまた、評判テーブルを照会して、与えられた日付以降に獲得したすべてのポイントを合計することなど、過去7日間に獲得された、異なる期間にわたる評判合計を表示しています。私はまた、異なる時間帯のパーセンタイルランクを表示したいと思います。たとえば、私は全体で11パーセンタイルかもしれませんが、今月は50パーセンタイル、今日は97パーセンタイルです。

私は、すべてのユーザーの評判合計を特定の期間にわたって見つけ、そのグループ内のどこに該当するのかを確認する必要がありますか?それはひどく面倒ではないですか?これを行う最善の方法は何ですか?

多くのありがとうございます。

答えて

1
私はここに私の頭の上からいくつかのオプションを考えることができ

  1. あなたとして一般的にあなたが必要となるすべてはあなたのWHERE句に似た結果を制限し、クエリを追加することです時間範囲内で獲得した評判ポイントを合計し、それに基づいてパーセンタイルランクを計算します。

  2. reputation_totalの更新を日常的に追跡します。したがって、user_id、date、reputation_totalのテーブルがあります。

  3. ユーザテーブル(reputation_total、reputation_total_today、reputation_total_last30daysなど)に、新しい時間帯を追加します。また、これを別のテーブル(reputation_totals)に正規化して、追跡する各期間の新しい列を追加する必要がなくなります。

オプション#1が最も簡単ですが、あなたは評判のトランザクションテーブル内の行の多くを持っている場合、おそらく遅い取得するつもりだ - それはあなたがリアルタイムでこれらを計算する必要がある場合は特に、非常にうまくスケールしません時間。

オプション#2は、時間の経過とともにストレージがさらに必要になりますが(1人のユーザーあたり1行あたり1行)、トランザクションテーブルを直接クエリするよりもかなり高速です。

オプション#3の柔軟性は低くなりますが、最も速いオプションになりそうです。

両方のオプション2 & 3は、バッチプロセスで日常的に合計を計算する必要があるため、考慮する必要があります。

私はスピード/ストレージスペース/複雑さ/柔軟性の異なるトレードオフが関係しています。あなたがすることは、最終的に、あなたのアプリケーションの要件に頼ります。

1

なぜあまりにも複雑すぎるのかわかりません。

WHERE DatePosted between @StartOfRange and @EndOfRange 
+1

複雑ではありませんが、私はすべての単一のユーザーに対してこれを行う必要がありますか?そして、それは複雑ではないが、そうではないだろう...まあ...遅い? – Toph

+0

1人のユーザーごとに何を意味していますか?あなたの実際のクエリがどのように見えるかわからないように、あまりにも多くの見解を述べることはできません。 – TheTXI

関連する問題