sitelink1  
sitelink2  
sitelink3  
sitelink4  
sitelink5  
sitelink6  
http://www.okjsp.pe.kr/seq/98829

계층형(답변형) 게시판에서 최근 답변이 하단으로 배치되길 원해서 방법을 찾던 중
ASP로 설명된 소스가 있어 그것을 기반으로 정리 해봤습니다.
http://www.dotnetkorea.com/boardview.asp?BoardName=ServerScript&Num=186

최근 답변이 상단으로 가는것은 부모글의 STEP보다 큰 글들을 1칸씩 밀고(STEP+1)
현재 답변이 부모글 다음 STEP으로(부모STEP+1) 들어가기 때문에 위로 배치됩니다.

select * from BOARD
order by REF desc, STEP asc

NO REF STEP LVL SBJ
2 2 0 0 2
3 2 1 1 _2-1
1 1 0 0 1

위 상태에서 2번글에 답변을 달면

update BOARD
   set STEP = STEP + 1
 where REF = 2    --부모REF
   and STEP > 0   --부모STEP

ref = 2 + 1   // 부모REF + 1
lvl = 0 + 1   // 부모STEP + 1

이런 방식으로 처리가 되므로 결과는 아래와 같이 상단으로 배치됩니다.

NO REF STEP LVL SBJ
2 2 0 0 2
4 2 1 1 _2-2
3 2 2 1 _2-1
1 1 0 0 1


이제 답변을 하단로 배치시키는 방법을 설명하겠습니다.
아래 상태가 원하는 형태이고 이 상태에서 설명합니다.

NO REF STEP LVL SBJ
2 2 0 0 2
3 2 1 1 _2-1
5 2 2 2 __2-1-1
7 2 3 3 ___2-1-1-1
4 2 4 1 _2-2
6 2 5 2 __2-2-1
1 1 0 0 1

위 상태에서 답변을 할때 배치될 위치를 찾아보면 두가지 형태로 구분됩니다.
2,4,6번글에 답변을 하면 6,1번글 사이에 배치되면 됩니다.
3,5,7번글에 답변을 하면 7,4번글 사이에 배치되면 됩니다.

조금 바꿔 말하면
2,4,6번글에 답변을 하면 마지막 STEP 다음으로 들어가면 됩니다.
3,5,7번글에 답변을 하면 4번글의 STEP으로 끼어 들어가면 됩니다.

코딩하는 식으로 설명하면
2,4,6번글에 답변을 하면 최대STEP에 +1한 후 현재STEP으로 세팅해서 등록하면 됩니다.
3,5,7번글에 답변을 하면 4번글의 STEP보다 크거나 같은 글들의 STEP을 +1하고
현재STEP을 4번글의 STEP으로 세팅해서 등록하면 됩니다.

이제 해결할게 2,4,6번글과 3,5,7번글을 구분하는 방법과 4번글 STEP을 찾을 수 있으면 되는데
아래 SQL으로 구분하고 찾을 수 있습니다.

select min(STEP) from BOARD
 where REF = 부모REF
   and STEP > 부모STEP
   and LVL <= 부모LVL

이 쿼리 결과가 null이면 2,4,6번글 형태(맨 밑으로 가는)이고
null이 아니면 3,5,7번글 형태(중간에 끼어 들어가는)이며 결과가 4번글의 STEP이 됩니다.

step = 결과STEP;

if (step == null) then {  // 맨 밑으로 가는 형태
    select max(STEP) + 1
      from BOARD
     where REF = 부모REF
  
    step = 결과STEP;
} else {                  // 중간에 끼어 들어가는 형태
    update BOARD
       set STEP = STEP + 1
     where REF = 부모REF
       and STEP >= step
}

lvl = 부모LVL + 1;

이렇게 처리 후 insert하면 하단으로 답변이 배치됩니다.


NO REF STEP LVL SBJ
2 2 0 0 2
3 2 1 1 _2-1
5 2 2 2 __2-1-1
7 2 3 3 ___2-1-1-1
4 2 4 1 _2-2
6 2 5 2 __2-2-1
1 1 0 0 1

4번글에 답변을 하면
NO REF STEP LVL SBJ
2 2 0 0 2
3 2 1 1 _2-1
5 2 2 2 __2-1-1
7 2 3 3 ___2-1-1-1
4 2 4 1 _2-2
6 2 5 2 __2-2-1
8 2 6 2 __2-2-2
1 1 0 0 1

3번글에 답변을 하면
NO REF STEP LVL SBJ
2 2 0 0 2
3 2 1 1 _2-1
5 2 2 2 __2-1-1
7 2 3 3 ___2-1-1-1
8 2 4 2 __2-1-2
4 2 5 1 _2-2
6 2 6 2 __2-2-1
1 1 0 0 1


삭제시 자식글이 있는지 체크나 자식글 모두 삭제에도 처음 SQL을 이용하면 됩니다.

NO REF STEP LVL SBJ
2 2 0 0 2
3 2 1 1 _2-1
5 2 2 2 __2-1-1
7 2 3 3 ___2-1-1-1
4 2 4 1 _2-2
6 2 5 2 __2-2-1
1 1 0 0 1

4번글의 자식글 목록
select min(STEP) from BOARD
 where REF = 2    --4번REF
   and STEP > 4   --4번STEP
   and LVL <= 1   --4번LVL

결과 없음 : null

select * from BOARD
 where REF = 2    --3번REF
   and STEP > 4   --3번STEP
order by REF desc, STEP asc

결과 : 6번글


3번글의 자식글 목록
select min(STEP) from BOARD
 where REF = 2    --3번REF
   and STEP > 1   --3번STEP
   and LVL <= 1   --3번LVL

결과 있음 : 4

select * from BOARD
 where REF = 2    --3번REF
   and STEP > 1   --3번STEP
   and STEP < 4   --결과STEP
order by REF desc, STEP asc

결과 : 5,7번글


한가지 더 얘기하면 게시글목록에서 order by REF desc, STEP asc로 정렬을 하는데
REF, SET에 대한 인덱스를 잡고 신규글 등록할때 REF를 음수로 등록하면
order by REF asc, STEP asc가 가능하므로 쉽게 index scan을 할 수 있습니다.

기존방식
select * from BOARD
order by REF desc, STEP asc

NO REF STEP LVL SBJ
2 2 0 0 2
3 2 1 1 _2-1
5 2 2 2 __2-1-1
7 2 3 3 ___2-1-1-1
4 2 4 1 _2-2
6 2 5 2 __2-2-1
1 1 0 0 1

SELECT STATEMENT Optimizer Mode=CHOOSE
  SORT ORDER BY
    TABLE ACCESS FULL  BOARD

음수방식
select * from BOARD
order by REF, STEP

NO REF STEP LVL SBJ
2 -2 0 0 2
3 -2 1 1 _2-1
5 -2 2 2 __2-1-1
7 -2 3 3 ___2-1-1-1
4 -2 4 1 _2-2
6 -2 5 2 __2-2-1
1 -1 0 0 1

SELECT STATEMENT Optimizer Mode=CHOOSE
  TABLE ACCESS BY INDEX ROWID BOARD
    INDEX FULL SCAN  IX_BOARD


아래는 테스트한 테이블과 샘플데이터에 대한 SQL입니다.

CREATE TABLE BOARD
(
  NO    INT             NOT NULL,
  REF   INT             NOT NULL,
  STEP  INT             DEFAULT 0   NOT NULL,
  LVL   INT             DEFAULT 0   NOT NULL,
  SBJ   VARCHAR(100),
  PRIMARY KEY (NO)
);

CREATE INDEX IX_BOARD ON BOARD (REF, STEP);

INSERT INTO BOARD (NO, REF, STEP, LVL, SBJ) VALUES (1, 1, 0, 0, '1');
INSERT INTO BOARD (NO, REF, STEP, LVL, SBJ) VALUES (2, 2, 0, 0, '2');
INSERT INTO BOARD (NO, REF, STEP, LVL, SBJ) VALUES (3, 2, 1, 1, '_2-1');
INSERT INTO BOARD (NO, REF, STEP, LVL, SBJ) VALUES (4, 2, 4, 1, '_2-2');
INSERT INTO BOARD (NO, REF, STEP, LVL, SBJ) VALUES (5, 2, 2, 2, '__2-1-1');
INSERT INTO BOARD (NO, REF, STEP, LVL, SBJ) VALUES (6, 2, 5, 2, '__2-2-1');
INSERT INTO BOARD (NO, REF, STEP, LVL, SBJ) VALUES (7, 2, 3, 3, '___2-1-1-1');
COMMIT;

이제 javaservice.net처럼 최근 답변이 아래로 가는 게시판을 만들어 보세요.

 


번호 제목 글쓴이 날짜 조회 수
103 J2SE 5.0 - 제네릭(GENERIC) 황제낙엽 2007.08.27 389
102 Cookie Test file 황제낙엽 2007.08.27 280
101 쿠키 유틸리티 클래스 CookieBox 만들기 file 황제낙엽 2007.08.27 420
100 통합을 위한 요소 기술, Java와 XML 황제낙엽 2007.08.27 419
99 중복 로그인 제한 기법에 대하여 황제낙엽 2007.08.23 457
98 interface와 abstract클래스의 차이점 황제낙엽 2007.07.28 520
97 javadoc - The Java API Documentation Generator 황제낙엽 2007.07.25 574
96 자바의 I/O 예제 [3] file 황제낙엽 2007.07.16 454
95 자바의 I/O 예제 [2] file 황제낙엽 2007.07.14 292
» 계층형(답변형) 게시판 로직(최근 답변 하단으로) 황제낙엽 2007.07.11 434
93 J2SE 5.0 - 주석(annotation,표식) 개요 황제낙엽 2007.07.03 393
92 include문과 logging 설정 황제낙엽 2007.03.23 551
91 [BPP] 게시판 페이징 로직 분석 - M1.1 - 샘플 다운로드 및 사용법 file 황제낙엽 2007.06.15 440
90 [BPP] 게시판 페이징 로직 분석 - (5) 페이지 계산 file 황제낙엽 2007.06.15 438
89 [BPP] 게시판 페이징 로직 분석 - (4) 쿼리문의 자동완성 file 황제낙엽 2007.06.14 489
88 [BPP] 게시판 페이징 로직 분석 - (3) 검색과 정렬 file 황제낙엽 2007.06.13 354
87 [BPP] 게시판 페이징 로직 분석 - (2) 간단한 페이징 기법 황제낙엽 2007.06.08 826
86 [BPP] 게시판 페이징 로직 분석 - (1) 클래스 목록 file 황제낙엽 2007.06.06 393
85 문자열의 앞뒤space제거처리 성능체크 황제낙엽 2007.06.03 418
84 간단한 서블릿 예제들 file 황제낙엽 2007.05.12 323