월별 랭킹 시스템 구현하기 > 그누보드5 팁자료실

그누보드5 팁자료실

월별 랭킹 시스템 구현하기 정보

월별 랭킹 시스템 구현하기

본문

음악 사이트 하나를 만들고 사용 후기에 올렸는데, 랭킹을 구현한 방법을 물어보신 분이 있어서 간단히 구현 방식만 정리해 드리려고 합니다.

 

http://midiex.net/chart.php

 

우선 이 페이지이구요, 이런 랭킹을 구성하는 데에 필요한 메카니즘에 대해서 간단히 설명 드리겠습니다.

(참고로 사이트가 12월 말에 오픈해서 2017년 12월, 2018년 1월 랭킹만 보여집니다.)

 

우선 제가 사용하는 방식은 제가 크게 고민하지 않고 머리속으로만 생각해낸 방식이라 실제로 음악 사이트들에서 이런식으로 계산을 하고 있는지는 모르겠습니다. 아마 아닐것 같습니다ㅎㅎ 이보다는 좀 더 고도화된 방식일테구요, 제 방식은 그냥 흉내만 낼 수 있는 단순한 방식이니 참고만 해주세요.

 

난이도는 초중급입니다. 그누보드 파일만 고치는게 아니라 신규 테이블이 나오고, 신규 화면이 나와야 합니다.

 

우선 테이블이 하나 새로 있어야 합니다. ranking이라고 정의하겠습니다.

 

CREATE TABLE `ranking` (
  `year` smallint(4) NOT NULL,
  `month` tinyint(4) NOT NULL,
  `bo_table` varchar(100) NOT NULL,
  `wr_id` int(11) NOT NULL,
  `hit` int(11) NOT NULL DEFAULT '0',
  `listen` int(11) NOT NULL DEFAULT '0',
  `download` int(11) NOT NULL DEFAULT '0',
  `good` int(11) NOT NULL DEFAULT '0'

 

ALTER TABLE `ranking`
  ADD PRIMARY KEY (`year`,`month`,`bo_table`,`wr_id`);
COMMIT;

 

전 몇몇 부가 필드들이 있는데, 필수적인 필드들만 표시하였습니다.

간단히 설명 드리면, 특정 게시판의 특정 글이, 조회/재생/다운로드/추천등의 액션이 발생하면 한달에 한번 테이블에 쌓이는 것입니다. 만약 그 달에 그런 액션이 한번 더 발생 하였다면 그때는 update가 되겠죠.

 

예를 들어 음악 게시판의 3번곡이 재생되면

 

2018년 1월 음악게시판 3번곡 재생 1번

 

이렇게 쌓일 것이구요, 6번곡이 재생되면

 

2018년 1월 음악게시판 3번곡 재생 1번

2018년 1월 음악게시판 6번곡 재생 1번

 

그러다 3번곡이 한 번 더 재생되고, 다운로드 되면

 

2018년 1월 음악게시판 3번곡 재생 2번, 다운로드 1번

2018년 1월 음악게시판 6번곡 재생 1번

 

이런식으로 쌓여 가는 것입니다. 만약 월을 넘겨 2월달이 되어서 3번곡 재생 액션이 발생하면

 

2018년 1월 음악게시판 3번곡 재생 2번, 다운로드 1번

2018년 1월 음악게시판 6번곡 재생 1번

2018년 2월 음악게시판 3번곡 재생 1번

 

이렇게 데이터들이 죽~~~ 쌓이겠죠. 이해 되시죠?

저 액션을 하는 함수는 구현이 매우 간단합니다.

 

function rankUpdate($bo_table, $wr_id, $factor) {
    $year = date("Y");
    $month = date("m");
    $sql = "INSERT INTO rank (year, month, bo_table, wr_id, ".$factor.") VALUES ('$year', '$month', '$bo_table', '$wr_id', 1) 
            ON DUPLICATE KEY UPDATE ".$factor." = ".$factor."+1";

    sql_query($sql);
}

 

끝입니다. 이 소스를 common.lib의 마지막에 추가 해 주시면 됩니다. 다운로드, 추천, 조회 등의 이런저런 액션에서 불러와져야 하므로 common.lib에 있는게 좋습니다.

 

그리고 수정할 파일은

download.php

board.php

good.php

입니다..

 

우선 download.php입니다. 제가 원본수정을 워낙 많이 하는 편이라 라인수는 모르겠구요,

 

// 다운로드 카운트 증가
    $sql = " update {$g5['board_file_table']} set bf_download = bf_download + 1 where bo_table = '$bo_table' and wr_id = '$wr_id' and bf_no = '$no' ";
    sql_query($sql);

 

이런 부분이 있습니다. 이 바로 아래에 넣어줍니다. 다운로드 카운트가 증가할때 랭킹값도 증가합니다.

rankUpdate($bo_table, $wr_id, 'download');

 

이젠 board.php입니다.

 

// 한번 읽은글은 브라우저를 닫기전까지는 카운트를 증가시키지 않음
    $ss_name = 'ss_view_'.$bo_table.'_'.$wr_id;
    if (!get_session($ss_name))
    {
        sql_query(" update {$write_table} set wr_hit = wr_hit + 1 where wr_id = '{$wr_id}' ");

 

위 소스 바로 아래에 비슷하게 넣어줍니다. 조회수가 올라갈 때 랭킹값도 올라갑니다.


rankUpdate($bo_table, $wr_id, 'hit');

 

이젠 good.php입니다.

 

// 추천(찬성), 비추천(반대) 카운트 증가
            sql_query(" update {$g5['write_prefix']}{$bo_table} set wr_{$good} = wr_{$good} + 1 where wr_id = '{$wr_id}' ");
            // 내역 생성
            sql_query(" insert {$g5['board_good_table']} set bo_table = '{$bo_table}', wr_id = '{$wr_id}', mb_id = '{$member['mb_id']}', bg_flag = '{$good}', bg_datetime = '".G5_TIME_YMDHIS."' ");

 

부분이 있습니다. 이 바로 아래에 넣어줍니다. 추천 카운트가 올라가면 랭킹 수치도 하나 올라가는 것입니다.

 

rankUpdate($bo_table, $wr_id, 'good');

 

이렇게만 해주면 데이터는 알아서 잘 쌓일겁니다.

단! 그냥 조건 없이 저렇게 하시면 데이터가 엄청 많이 쌓입니다. 활동량이 많은 커뮤니티에선 어마어마하게 쌓일겁니다. 그래서 그런 경우라면 랭킹을 매기고 싶은 게시판에 한해서 쌓이도록 하는 소스를 추가해주시는게 좋습니다. 아니면 뭐.. 저대로 하셔서 모든 게시물에 대한 랭킹을 쌓을 수도 있구요.

 

하나 빠진게 있다면, listen이란 요소에 대한 것인데, 이건 제가 별도로 플레이어를 만들어서 사용하고 있으므로, 이 플레이어 내부에 rankUpdate소스가 들어갑니다. 범용적인 부분이 아니라 여기 올려드려봐야 소용이 없구요, 적용법은 일맥상통하니 여러분이 원하는 액션, 원하는 타이밍에 적용해 주시면 얼마든지 다르게 활용 가능할겁니다.

 

자 이렇게만 했으면, 어떤식으로든 활용 가능한 데이터가 죽죽 잘 쌓일겁니다. 랭킹 페이지를 만들어야 하는데요, 여기까지 잘 따라오신분이면 랭킹 페이지를 어떻게 만들지는 자체적으로 구상 가능하신 분일거라 생각합니다. 음악 사이트인지, 그냥 일반 커뮤니티 사이트인지, 무슨 게임 랭킹 사이트인지에 따라서 완전 다른 디자인으로 다르게 구성될테니깐요.

 

우선 기본적으로 목록을 불러오는 쿼리는 이러합니다. 저는 게시판별 랭킹을 보여주기 때문에 소스가 아래와 같습니다. 

http://midiex.net/chart.php

에 보시면 앨범, 곡 2가지 랭킹이 제공되는데, 앨범이나 곡이나 둘다 각각의 게시판 하나씩으로 구성되어 있습니다.

 

<?php

$year = date("Y");
$month = date("m");

 

$sql = " SELECT *
               FROM ranking, g5_write_게시판ID 게시판ID
              WHERE ranking.wr_id = 게시판ID.wr_id AND rank.bo_table = '게시판ID'
                AND 게시판ID.wr_is_comment = '0'
                AND ranking.year = '$year' AND ranking.month = '$month'
           ORDER BY ranking.hit + ranking.listen*2 + ranking.download*4 + ranking.good*10 DESC
              LIMIT 0, 100";

$query = sql_query($sql);

 

$list = array();
while($row = sql_fetch_array($query)) {
    $row = get_list($row, $board, G5_URL);

    $row['name'] = get_sideview($row['mb_id'], $row['wr_name']);

    array_push($list, $row);

}

?>

 

뭐 이런식으로 $list를 구성하시구요, 목록을 출력 하실 곳에서

 

<?php  for ($i=0; $i<count($list); $i++) { ?>

   // 목록 출력용 html

<?php } ?>

 

이렇게 해 주시면 될겁니다.

구현 메카니즘에 대한 팁이므로.. 다른 팁들에 비해 깔끔하고 명확하지 않게 설명될것 같은데요,

혹시 추가 질문 있으시면 댓글로 달아주시기 바랍니다. 소스를 짜드릴순 없지만 도와드릴 수 있는 선까지 도와드리도록 하겠습니다.

추천
5

댓글 12개

와우 아주 잘돼요 근데 한가지더질문이요


이부분어떻게 처리하면돼요 ? 이부분 소스도 부탁드릴께요
=================php
$year = date("Y");
$month = date("m");
$due = $year.$month;

$for = "score";

if(isset($_REQUEST['due'])) {
$due = $_REQUEST['due'];
$due = substr($due,0,6);
$year = substr($due,0,4);
$month = substr($due,4,2);

// 기본 검증
if($year<1900 || $year>2100) die("올바른 기간이 아닙니다. 201807과 같이 6자리 연+월 형식으로 입력해주세요.");
else if($month<1 || $month>12) die("올바른 기간이 아닙니다. 201807과 같이 6자리 연+월 형식으로 입력해주세요.");
}

$prevDue = date("Ym",strtotime($due."01 -1 month"));
$nextDue = date("Ym",strtotime($due."01 +1 month"));

if(isset($_REQUEST['for'])) {
$for = $_REQUEST['for'];
}

$prevHref = "/chart.php?for=".$for."&due=".$prevDue;
$nextHref = "/chart.php?for=".$for."&due=".$nextDue;

================ db
SELECT * FROM ranking WHERE rank.year = '$year' AND rank.month = '$month' ORDER BY...


이런식으로 구현하고, 오른쪽 왼쪽 화살표에 prevHref랑 nextHref로 링크를 걸어 주시면 됩니다. 혹시 html+javascript구현에 대한 질문은 아니었겠죠? 저런식으로 토글 애니메이션을 추구하지 않으신다면 위 소스만으로 처리 가능하실겁니다.
전체 2,412 |RSS
그누보드5 팁자료실 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT