2011-02-06 10 views
0

私は基本的なカルマ/リプレースシステムを持っており、ユーザーはそのアクティビティ(質問、回答など)に基づいてユーザーを賞賛します。彼らのポイントに基づいてユーザーのランク(タイトル)を持っていたい。ランクが異なると、制限と権限が異なります。ダイナミックなユーザーランク

ランクテーブル

id rankname points questions_per_day 
1 beginner 150  10 
2 advanced 300  30 

私は下限と上限を持っている必要がある場合はわからないんだけど、簡単のために、私はつまり、ユーザー以下、最大のポイントの上限にのみ残っています150は初心者で、300歳以下の人は「上級者」です。

たとえば、157ポイントのBobには、彼のユーザー名で表示される「advanced」タグがあります。

ユーザーのランク/タイトルを決定して表示するにはどうすればよいですか?各行をループして値を比較しますか?

これを、このように計算されたランクを持つ何千人ものユーザーに拡大するとどのような問題が発生する可能性がありますか?確かに、ユーザーのランクが要求されるたびにクエリとループを実行するシステムに課税されますか?

答えて

1

ランクとスコアをよくキャッシュできます。特定のアクティビティを実行したときにユーザーのスコアだけが変化した場合、そのアクティビティにトリガをかけることができます。スコアが変わると、ランクを再計算してユーザーレコードに保存することができます。そうすれば、ランクを取得するのは簡単です。スコアが変わったときに計算するだけです。

このような一致するランクIDを取得できます。ユーザーのSchoreに最も近い(ただし、それ以下の)ランクを照会します。このランクIDをユーザーのレコードに格納します。 疑似変数{USERSCORE}を追加しました。パラメータやその他の方法でクエリに値を入力するかどうかわかりません。

select r.id 
from ranks r 
where r.points <= {USERSCORE} 
order by r.points desc 
limit 1 
+0

これは私が尋ねたものではありません。私はすでにこの方法でユーザースコアを管理しています。私はテーブルに基づいて彼らのランク/タイトルを決定する必要があります。 –

+0

さて、あなたの質問の第2部分に答えるために、私の答えに 'score'を' rank'で置き換えてください。 1秒で追加をポストします。 – GolezTrol

+0

スコアに基づいてランクIDを計算するためのクエリを追加しました。このリアルタイムを使用するか、好きなようにユーザーテーブルでキャッシュすることができます。このIDを使用して、ユーザーページに表示する正しいランク名を取得することができます。このクエリをリアルタイムで使用すると(何千ものユーザがいない限り大丈夫でしょう)、すぐに 'r.id'を' r.rankname'に置き換える方がよいでしょう。 2番目のクエリを実行する必要があります。 – GolezTrol

1

スキーマを知らなくても少し難しいです。試してみてください:

SELECT user.id, MIN(ranks.id) AS rankid FROM user JOIN ranks ON (user.score <= ranks.points) GROUP BY user.id; 

ここで、あなたはランクidを知っています。

これは(GROUP BYとMAXはパイプラインブレーカなので非常に重い操作ですが)、GolezTrolのアドバイスは良いです。この情報をキャッシュして、ユーザーのスコアが変更された場合にのみ更新する必要があります。トリガーはこれでいいですね。

+0

なぜMAXを使用したのかわからないのは、テーブルの最大ランクしか返さないからです。 –

+0

私はあなたがテーブルの最大ランクで何を意味するのかよくわかりません。結合されたすべての行から最も高いランクを与えます。ランクから結合されたすべての行は、ユーザースコア以下でなければなりません。だから、それはあなたにユーザーのスコア以下に適合する最高ランクを与えるでしょう。それは収まるはずです。 –

+0

私はこれを試しました。 2つの項目(Bobが11ポイント、Jimが299)のusersテーブル。 MAXでは、両方のランクIDが2であることが示されます(OPのランク表から取得されます)。 MAXを取り外すと、1と2が必要に応じて表示されます。 –

関連する問題