2012-09-12 2 views
1

내 사이트 중 하나에서 사용자는 서로 투표 할 수 있습니다. 나는 각각의 행이 주어진 투표에 해당하는 Votes 테이블을 가지고있다.사용자 투표 열을 실시간으로 또는 하루에 한 번 업데이트해야합니까?

전체 투표 점수를 표시하기를 원합니다.이 점수는 단순히 Votes 표에받은 투표 수의 합계입니다. 실시간으로 계산해야합니까, 아니면 하루에 한 번 계산해야합니까? 이 유형의 시나리오에 대한 "우수 사례"는 무엇입니까 (수십만 표를 얻고 성장한다고 가정)?

실시간으로는 충분하지만 하루에 한 번 간단하지는 않습니다. 나는 크론 작업을 할 필요가 있다고 가정하고 있지만, 정확히 이것을 어떻게 할 것인가? 나는 각 사용자를 반복해야하고 그들이 Votes 테이블에서받은 투표 수의 합계를 수행해야한다고 알고 있지만 첫 번째 투표에서 시작하여 매일 매일 전체 금액을 계산하여 저장해야합니다. 나는 단지 새로운 투표 (지난 업데이트 이후)를 기존 합계에 추가하고 그 대신에 저축합니까?

후자의 경우 정확히 어떻게하면 모든 사항을 추적하여 투표를 놓치거나 두 번 추가하지 않을 수 있습니까?

답변

1

이 문제를 처리하는 표준 방법은 denormalization입니다. 이는 기본적으로 쿼리로 결정될 수있는 데이터를 저장하는 것을 의미합니다. 유일하게 실제로 scalable 솔루션 일뿐만 아니라 매우 간단하고 뛰어난 성능을 제공합니다. 이를 구현하는 방법은 다음과 같습니다.

테이블에 total_votes 열을 추가하고 투표 데이터가 변경 될 때 발생하는 트리거에 의해 올바르게 유지하십시오. 이 같은

뭔가 :

delimiter // 

create trigger vote_trigger 
after insert on votes 
for each row 
begin 
    update users set 
    total_votes = total_votes + 1 
    where users.user_id = new.user_id; 
end; // 

delimiter ; 

은 행 삭제 및 행 업데이트에 대한 다른 유사한 트리거를 만듭니다.


처음이 실행과 같은 모든 값을 채울 쿼리, 뭔가를 실행 한 번만 적 시스템은 라인에서 벗어나거나 읽기 전용 모드에있는 동안 :

update users set 
total_votes = (select count(*) from votes where user_id = users.user_id); 

하지만이 실행 쿼리를 사용하는 경우 트리거는 total_votes 값을 올바르게 유지합니다 (예 : votes 테이블과 동기화 됨).

+0

흥미 롭습니다. 그러나 내가 방아쇠를 제대로 이해한다면, 한 번 새로운 투표가있을 때마다 모든 사람의 총 투표 수를 다시 계산합니까? 그렇다면 매우 비효율적이지 않습니까? 아니면 잘못 이해하고 있습니까 (예 :'new.user_id'가 무엇인지 모르겠습니다)? – ProgrammerGirl

+0

정규화 된 성능 최적화 인 비정규화할 때마다 중복 값이 ​​동기화되도록 도구를 작성하십시오. 이렇게하지 않으면 캐시 된 값과 실제 값 사이에 표류하는 경우가 있습니다. – tadman

+0

@ tadman : 내가 무슨 뜻인지 이해가 안가요, 예제를 제공해 주시겠습니까? 감사. 보헤미안 : 위 질문에 대한 답변을 얻었습니까? 감사. – ProgrammerGirl

관련 문제