2011-02-06 5 views
0

저는 사용자가 자신의 활동 (질문, 답변 등)을 기반으로 보너스를주는 기본 카르마/담당자 시스템을 보유하고 있습니다. 포인트에 따라 사용자 등급 (제목)을 갖고 싶습니다. 각기 다른 계급에는 서로 다른 한계와 권한이 있습니다. 아래의 사용자, 즉,동적 사용자 순위

내가 낮은 및 상한을 가질 필요가 있는지 확실하지 않습니다 테이블

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

을 위하지만, 간단하게하기 위해 나는 단지 최대 포인트 제한을 떠났다 150은 '초급'이고 300 이하이거나 '고급'입니다.

예를 들어, 157 점이있는 Bob은 사용자 이름으로 '고급'태그를 표시합니다.

사용자의 순위/제목을 어떻게 결정하고 표시 할 수 있습니까? 각 행을 반복하고 값을 비교합니까?

이렇게 계산 된 순위가있는 수천 명의 사용자에게이 문제를 적용하면 어떤 문제가 발생할 수 있습니까? 확실히 그것은 사용자의 순위가 요청 될 때마다 질의하고 반복하는 시스템에 과세 할 것인가?

답변

1

순위와 점수를 더 잘 캐시 할 수 있습니다. 특정 활동을 수행 할 때 사용자의 점수 만 변경되면 해당 활동에 트리거를 걸 수 있습니다. 점수가 변경되면 순위를 다시 계산하여 사용자 기록에 저장할 수 있습니다. 그렇게하면 순위를 알아내는 것이 쉽지 않으므로 점수가 변경 될 때 계산하면됩니다.

다음과 같이 일치하는 순위 ID를 얻을 수 있습니다. 사용자 schore와 가장 가까운 (또는 그 이하) 순위를 쿼리합니다. 이 순위 ID를 사용자 레코드에 저장하십시오. 매개 변수 나 다른 방법으로 쿼리에 값을 입력했는지 모르겠으므로 가상 변수 {USERSCORE}를 추가했습니다.

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

그건 내가 요구 한 것이 아닙니다. 이 방법으로 이미 사용자 점수를 관리합니다. 테이블에 따라 순위/제목을 결정해야합니다. –

+0

그러면, 질문의 두 번째 부분에 답하기 위해'score'를'rank'로 대체하십시오. 추가는 1 초 후에 올릴 것입니다. – GolezTrol

+0

점수를 기반으로 순위 ID를 계산하는 쿼리가 추가되었습니다. 이 실시간을 사용하거나 원하는대로 사용자 테이블에서 캐시 할 수 있습니다. 이 ID를 사용하여 사용자 페이지에 표시 할 올바른 순위 이름을 얻을 수 있습니다. 이 쿼리를 실시간으로 사용하면 (아마 수천 명의 사용자가없는 한 잘 수행 할 것입니다.)'r.id'를'r.rankname'으로 바로 바꾸는 것이 좋습니다. 두 번째 쿼리를 실행해야합니다. – 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에서 테이블의 최대 순위 만 반환하기 때문에 MAX를 사용한 이유가 확실하지 않습니다. 그렇지 않으면 훌륭합니다. –

+0

테이블에서 최대 순위를 얻는 것이 무슨 뜻인지 확신 할 수 없습니다. 모든 조인 된 행에서 가장 높은 순위를 부여합니다. 순위에서 조인 된 모든 행은 사용자 점수와 같거나 낮아야합니다. 따라서 사용자 점수에 가장 적합한 순위를 얻을 수 있습니다. 그것은 적합해야합니다. –

+0

방금 ​​시도했습니다. 두 항목 (Bob이 11 점, Jim이 299)이있는 사용자 테이블입니다. MAX를 사용하면 두 가지 모두에 대한 순위가 2로 표시됩니다 (OP의 순위 테이블에서 가져옴). MAX를 제거하면 1과 2가 적절하게 표시됩니다. –