[PHP]랭킹을 매겨야 하는 DB를 어떻게 구성하는게 좋을까?
개발을 하다 보니 참가자들의 랭킹을 매겨야하는 작업이 있다.
이런 경우 어떤식으로 짜는게 가장 효율적이며 정확할까 고민을 하다보니 3가지 방법이 생각났다.(더 좋은 방법이 있으면 공유해주세요!)
1.db 트랜잭션 걸기
첫 번째 방법은 먼저 db테이블에 들어간 데이터 수를 select count 해와서 그숫자에 +1을 한 값을 db의 순위 필드에 insert하는 방법이다.
단 주의할점은 select 후 insert하기 때문에 그 중간에 다른 데이터가 들어오거나 변경되는 경우 정확하지 않을 수도 있어서 트랜잭션을 걸어줘야 한다. (하지만 트랜잭션은 db에 lock을 걸기 때문에 함부로 사용해서는 안된다. 그리고 select -> insert라는 2 step을 거치기 때문에 비효율적일 수 있다.) (참고 : http://blog.saltfactory.net/database/introduce-mysql-lock.html)
2. auto_increment 필드로 순위 매기기
두 번째 방법은 db 테이블에 index 필드를 만들고 auto_increment를 설정해 놓은 경우 이 index필드를 랭킹으로 사용할 때 쓰는 방법이다.
이 방법은 select-> insert를 하지않고 바로 insert를 할 수 있기 때문에 부하가 적다.
단 주의할점은 auto_increment가 설정된 필드를 랭킹으로 쓰면 데이터가 삭제된 경우에 대한 처리가 불가능하다 그리고 만약 db insert시 duplication,db error 가 나는 경우 insert는 되지 않지만 auto_increment는 증가한다는 치명적인 문제점이 있다. 그래서 사용하면 안되는 방법이다.
3. auto_increment필드 + 로직상 순위 매기기
세 번째 방법은 2번째 방법을 보완한 방법으로 auto_increment 필드를 만들고 그 index 값을 순위로 바로 사용하는게 아니라 order by index를 해서 그 순서로 로직상에서 순위를 매기는 방법이다.
이 방법이 가장 효율적이며 정확한 방법인 것 같다.