강의 컨설팅 트레이닝 무료진단 무료책자 마케팅편지 마케팅정보공유 다이어리 서비스제휴 고객센터

역인덱스 게시판 |
작성자 : 13 김영철
등록날짜 : 2009.01.14 12:59
1,244
여러가지 대용량 게시판에 관한 글들이 산재해 있습니다.
그중에 부분업데이트 게시판이 가장 눈에 들어왔으며
나름대로 변형하여 만들어 보았습니다.
어쩌면 독창적일지도...  :D

우선 테이블 구조는 아래와 같습니다.


CREATE TABLE `board_news` (
  `c_no` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `c_group_no` INT NOT NULL DEFAULT '-1',
  `c_depth_no` INT UNSIGNED NOT NULL,
  `c_order_no` INT UNSIGNED NOT NULL,
  `subject` VARCHAR(50) NOT NULL,
  `contents` TEXT NOT NULL,
  `reg_date` INT UNSIGNED NOT NULL,
  `hits` INT UNSIGNED NOT NULL,
  PRIMARY KEY(`c_no`),
  INDEX `idx1`(`c_group_no`, `c_order_no`)
);


위의 테이블은 뉴스 게시판을 만들면서 적용한 것을 예로 든것입니다.
중요한 필드는 c_group_no, c_depth_no, c_order_no 입니다.
제가 생각하는 대용량 게시판은 첫 페이지나 마지막 페이지나 검색속도가
일정해야 한다는 것입니다.
그렇지 않은 게시판은 대용량 게시판이라고 할 수 없다고 생각합니다.
그럼 위의 테이블이 어떻게 첫 페이지나 마지막 페이지에서 속도가 같을까요?

차례차례 살펴보겠습니다.

우선 새로운 게시물을 삽입할 때 처리하는 방법입니다.
일반적으로 게시판의 구조는 계층형입니다.
아래의 예를 보세요.


No.     Order No.   Subject
9             9           다섯번째 게시물
8             5           네번째 게시물
7             4           세번째 게시물
6             2           두번째 게시물
5             6           →두번째 게시물의 첫번째 응답
4             8           →→두번째 게시물의 첫번째 응답의 응답
3             7           →두번째 게시물의 두번째 응답
2             1           첫번째 게시물
1             3           →첫번째 게시물의 응답


위와 같은 리스트가 전형적인 계층형 게시판입니다.
Order No. 는 게시물이 작성된 순서입니다.

우선 게시물을 삽입할 때 아래의 쿼리문을 날려줍니다.


$link_id = @mysql_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD) or
           die('데이터베이스 서버(' . DB_SERVER . ')에 접속할 수 없습니다.');
// Table Lock
$query      = "LOCK TABLES " . DB_DBNAME . ".board_news WRITE";
$result_id  = @mysql_query($query, $link_id) or
              die('SQL: ' . $query . '<br><br>' . mysql_errno() . ': ' . mysql_error());

// 최근 게시물 정보 가져오기
$query      = "SELECT MIN(c_group_no) " .
              "FROM " . DB_DBNAME . ".board_news";
$result_id  = @mysql_query($query, $link_id) or
              die('SQL: ' . $query . '<br><br>' . mysql_errno() . ': ' . mysql_error());

$query_data = mysql_fetch_array($result_id);
$c_group_no = ($query_data[0]) ? $query_data[0] - 1 : -1;

// 변수 초기화
$reg_date = time();

// 게시물 등록
$query      = "INSERT INTO " . DB_DBNAME . ".board_news (" .
                  "c_group_no, subject, contents, reg_date) " .
              "VALUES (" .
                  "$c_group_no, '$subject', '$contents', $reg_date)";
$result_id  = @mysql_query($query, $link_id) or
              die('SQL: ' . $query . '<br><br>' . mysql_errno() . ': ' . mysql_error());


위의 코드는 단순히 c_group_no 에 -1 을 해준것입니다.

그럼 아래의 코드를 보세요. 답변글에 대한 처리입니다.


// Table Lock
$query      = "LOCK TABLES " . DB_DBNAME . ".board_news WRITE";
$result_id  = @mysql_query($query, $link_id) or
              die('SQL: ' . $query . '<br><br>' . mysql_errno() . ': ' . mysql_error());

// 상위 게시물 정보 가져오기
$query      = "SELECT c_group_no, c_depth_no, c_order_no " .
              "FROM " . DB_DBNAME . ".board_news " .
              "WHERE c_no = $c_no";
$result_id  = @mysql_query($query, $link_id) or
              die('SQL: ' . $query . '<br><br>' . mysql_errno() . ': ' . mysql_error());

$query_num_rows = mysql_num_rows($result_id);
if ($query_num_rows) {
    $query_data = mysql_fetch_array($result_id);
    $c_group_no = $query_data['c_group_no'];
    $c_depth_no = $query_data['c_depth_no'] + 1;
    $c_order_no = $query_data['c_order_no'] + 1;

    // 게시물 정렬을 위한 정보 가져오기
    $query      = "SELECT c_depth_no, c_order_no " .
                  "FROM " . DB_DBNAME . ".board_news " .
                  "WHERE c_group_no = $c_group_no " .
                  "AND c_order_no >= $c_order_no " .
                  "ORDER BY c_order_no ASC";
    $result_id  = @mysql_query($query, $link_id) or
                  die('SQL: ' . $query . '<br><br>' . mysql_errno() . ': ' . mysql_error());

    while ($query_data = mysql_fetch_array($result_id)) {
        if ($c_depth_no > $query_data['c_depth_no']) {
            break;
        } else {
            $c_order_no = $query_data['c_order_no'] + 1;
        }
    }

    // 게시물 정렬(부분업데이트)
    $query      = "UPDATE " . DB_DBNAME . ".board_news " .
                  "SET c_order_no = c_order_no + 1 " .
                  "WHERE c_group_no = $c_group_no " .
                  "AND c_order_no >= $c_order_no";
    $result_id  = @mysql_query($query, $link_id) or
                  die('SQL: ' . $query . '<br><br>' . mysql_errno() . ': ' . mysql_error());

    // 변수 초기화
    $reg_date = time();

    // 게시물 등록
    $query      = "INSERT INTO " . DB_DBNAME . ".board_news (" .
                      "c_group_no, c_depth_no, c_order_no, subject, contents, reg_date) " .
                  "VALUES (" .
                      "$c_group_no, $c_depth_no, $c_order_no, '$subject', '$contents', $reg_date)";
    $result_id  = @mysql_query($query, $link_id) or
                  die('SQL: ' . $query . '<br><br>' . mysql_errno() . ': ' . mysql_error());
} else {
    exit('상위 게시물 정보가 없습니다.');
}


위 코드에서 주목할 부분은 게시물 정렬부분입니다.
기본적으로 답변글 처리에서 $c_no 는 당연히 상위 게시물이고
상위 게시물의 기본 정보에서 c_group_no, c_depth_no, c_order_no 는
일단 가져와서 게시판에 같은 c_group_no 중 c_order_no 가 크거나 같은 것들을
전부 +1 씩 하는 것입니다.(부분업데이트)
그리고 빈자리에 답변글을 잽싸게 집어 넣습니다.ㅋ

여기서 DB 내부를 들여다보죠.


부분업데이트 전
c_no    c_group_no      c_depth_no      c_order_no      subject
9             -5                    0                     0               다섯번째 게시물
8             -2                    2                     2               →→두번째 게시물의 첫번째 응답의 응답
7             -2                    1                     2               →두번째 게시물의 두번째 응답
6             -2                    1                     1               →두번째 게시물의 첫번째 응답
5             -4                    0                     0               네번째 게시물
4             -3                    0                     0               세번째 게시물
3             -1                    1                     1               →첫번째 게시물의 응답
2             -2                    0                     0               두번째 게시물
1             -1                    0                     0               첫번째 게시물

부분업데이트 후
c_no    c_group_no      c_depth_no      c_order_no      subject
9             -5                    0                     0               다섯번째 게시물
8             -2                    2                     2               →→두번째 게시물의 첫번째 응답의 응답
7             -2                    1                     3               →두번째 게시물의 두번째 응답
6             -2                    1                     1               →두번째 게시물의 첫번째 응답
5             -4                    0                     0               네번째 게시물
4             -3                    0                     0               세번째 게시물
3             -1                    1                     1               →첫번째 게시물의 응답
2             -2                    0                     0               두번째 게시물
1             -1                    0                     0               첫번째 게시물



대충 설명이 끝났습니다.

그럼 어떻게 보여줘야 할 것까요?
아래의 코드를 보세요. 코드를 보여주는 것이 가장 빠른 설명이라 자꾸 코드를 보여줍니다.


// get GET parameters.
$row_no = (int)$_GET['row_no']; // 페이징할 때 주로 쓰이는 변수이다.

// 변수 초기화
$list_scale = 10;

// 페이지 시작 인덱스 값 가져오기
$query      = "SELECT c_group_no, c_order_no " .
              "FROM " . DB_DBNAME . ".board_news " .
              "ORDER BY c_group_no ASC, c_order_no ASC " .
              "LIMIT $row_no, 1";
$result_id  = @mysql_query($query, $link_id) or
              die('SQL: ' . $query . '<br><br>' . mysql_errno() . ': ' . mysql_error());

$query_data = mysql_fetch_array($result_id);

// 게시물 리스트
$query      = "SELECT c_no, c_depth_no, subject, contents, reg_date, hits " .
              "FROM " . DB_DBNAME . ".board_news " .
              "WHERE (c_group_no = {$query_data['c_group_no']} " .
              "AND c_order_no >= {$query_data['c_order_no']}) " .
              "OR c_group_no > {$query_data['c_group_no']} " .
              "ORDER BY c_group_no ASC, c_order_no ASC " .
              "LIMIT 0, $list_scale";
$result_id  = @mysql_query($query, $link_id) or
              die('SQL: ' . $query . '<br><br>' . mysql_errno() . ': ' . mysql_error());


위 코드는 당연히 게시물이 있을 경우 수행되어야 합니다.
그리고, $row_no, $list_scale 변수는 페이징할 때 주로 쓰이는 것이므로 설명을 생략하겠습니다.

[출처]  마루아라

"쇼핑몰·홈페이지·오픈마켓
블로그·페이스북·이메일 등의 각종 마케팅 글쓰기,
각종 광고, 영업, 판매, 제안서, 전단지
반응율 3배×10배 이상 높이는 마법의 8단계 공식"
자세히보기

Comments

번호 제목 글쓴이 날짜 조회
3285 이것은 AI파일 미리보기입니다. 댓글3 M 최고의하루 01.15 3593
3284 이미지미리보기pds파일미리보기파일입니다^^ 댓글2 99 단국강토 01.14 2830
3283 동영상 캡쳐(Capture) 아주 쉽게 하기~ 99 단국강토 01.14 2621
3282 자판기안의 특수문자 99 단국강토 01.13 2535
3281 ntdll.dll 오류 해결방법 M 최고관리자 01.12 4401
3280 인터넷 동영상 저장하기 - 넷트랜스포터 사용 - M 최고의하루 01.12 3104
3279 옛날 기사를 찾아보고 싶을때 99 단국강토 01.08 2234
3278 CD 음악 mp3로 바꾸기 99 단국강토 01.08 2504
3277 알씨로 초간단 동영상 슬라이드쇼 만들기 99 단국강토 01.07 2849
3276 IP 추적은 어떻게 하는가? 99 단국강토 01.07 2399
3275 일본어로 된 웹을 한글로 즐기기 99 단국강토 01.06 2356
3274 이것은 AI파일 미리보기입니다. 댓글2 M 최고의하루 01.15 4052
3273 이미지미리보기pds파일미리보기파일입니다^^ 99 단국강토 01.14 2453
3272 동영상 캡쳐(Capture) 아주 쉽게 하기~ 99 단국강토 01.14 2789
3271 공유기 차단 무력화 시키는 법 99 단국강토 01.13 3550
3270 자판기안의 특수문자 99 단국강토 01.13 2368
3269 ntdll.dll 오류 해결방법 M 최고의하루 01.12 3670
3268 인터넷 동영상 저장하기 - 넷트랜스포터 사용 - M 최고의하루 01.12 3231
3267 옛날 기사를 찾아보고 싶을때 99 단국강토 01.08 2174
3266 CD 음악 mp3로 바꾸기 99 단국강토 01.08 2489
3265 알씨로 초간단 동영상 슬라이드쇼 만들기 99 단국강토 01.07 3315
3264 IP 추적은 어떻게 하는가? 99 단국강토 01.07 2216
3263 일본어로 된 웹을 한글로 즐기기 99 단국강토 01.06 2311
3262 [컴퓨터 키보드, 특수문자 정식 명칭들] M 최고의하루 12.18 3705
3261 하드,CPU,RAM 지원표 M 최고의하루 12.18 2594
3260 award bios 어워드 바이오스 설정법 M 최고의하루 12.18 3949
3259 내장 그래픽카드 죽이는 법 M 최고의하루 12.04 4888
3258 컴퓨터 조립 M 최고의하루 12.04 2840
3257 USB 버젼 속도 차이 2 천진난만 02.20 2379
3256 제가 사용하고 있는 마케팅프로그램입니다 댓글1 3 천지인 05.23 13198
마케팅
특별 마케팅자료
다운로드 마케팅자료
창업,경영
기획,카피,상품전략
동기부여,성취