- JAVA 스터디 중 스터디장이 댓글 게시판 숙제로 구글 중 내가 적용한 알고리즘(까먹을까봐-_-)
계층형 게시판을 위한 테이블의 구성 및 알고리즘은 워낙 다양하기 때문에 특별히 정해진 솔류션은 존재하지 않습니다.
여기서는 많은 책자에서 소개되어 있는 간단한 계층형 게시판의 구조와 알고리즘에 대해서 알아봅니다.
설명을 위해 테이블에는 다음과 같은 컬럼들만 있다고 가정합니다. 실제로는 더 많겠죠.
No : 글번호(Primary Key)
Title : 글제목
Grp : 같은 주제를 갖는 게시물의 고유번호. 부모글과 부모글로부터 파생된 모든 자식글은 같은 번호를 갖습니다.
Seg : 같은 그룹내 게시물의 순서
Lvl : 같은 그룹내 계층
게시판에 첫번째 글이 올라오면, 테이블에는 다음과 같은 정보가 저장됩니다.
====================================
No, Title , Grp, Seq, Lvl
====================================
1, '안녕하세요' , 1, 1, 0
====================================
새 글에서 No는 시퀀스로부터 받아온 값, Grp는 No와 동일한 값, Seq는 1, Lvl은 0입니다.
두번째 글과 세번째 글이 올라옵니다.
====================================
No, Title , Grp, Seq, Lvl
====================================
3, '모임이 있습니다', 3, 1, 0
2, '날씨가 맑습니다', 2, 1, 0
1, '안녕하세요 ', 1, 1, 0
====================================
첫번째 글에 답글이 올라옵니다.
====================================
No, Title , Grp, Seq, Lvl
====================================
3, '모임이 있습니다', 3, 1, 0
2, '날씨가 맑습니다', 2, 1, 0
1, '안녕하세요 ', 1, 1, 0
4, ' 반가워요 ', 1, 2, 1
====================================
답글의 경우, Grp는 부모글의 Grp 값, Seq는 부모글의 Seq+1, Lvl은 부모글의 Lvl+1이 됩니다.
첫번째 글의 답글에 답글이 올라옵니다. 즉, 네번째 글의 답글이 올라옵니다.
====================================
No, Title , Grp, Seq, Lvl
====================================
3, '모임이 있습니다', 3, 1, 0
2, '날씨가 맑습니다', 2, 1, 0
1, '안녕하세요 ', 1, 1, 0
4, ' 반가워요 ', 1, 2, 1
5, ' 감사합니다 ', 1, 3, 2
====================================
첫번째 글의 두번째 답글이 올라옵니다.
====================================
No, Title , Grp, Seq, Lvl
====================================
3, '모임이 있습니다', 3, 1, 0
2, '날씨가 맑습니다', 2, 1, 0
1, '안녕하세요 ', 1, 1, 0
6, ' 환영합니다 ', 1, 2, 1
4, ' 반가워요 ', 1, 2, 1
5, ' 감사합니다 ', 1, 3, 2
====================================
여기서, 두번째 답글이 첫번째 답글보다 먼저 표시되려면, 동일한 그룹 번호에 있으면서 부모의 Seq 번호보다 큰 게시물의 Seq 번호를 모두 1만큼 증가시킵니다.
====================================
No, Title , Grp, Seq, Lvl
====================================
3, '모임이 있습니다', 3, 1, 0
2, '날씨가 맑습니다', 2, 1, 0
1, '안녕하세요 ', 1, 1, 0
6, ' 환영합니다 ', 1, 2, 1
4, ' 반가워요 ', 1, 3, 1
5, ' 감사합니다 ', 1, 4, 2
====================================
여섯번째 게시물에 답글이 올라옵니다.
====================================
No, Title , Grp, Seq, Lvl
====================================
3, '모임이 있습니다', 3, 1, 0
2, '날씨가 맑습니다', 2, 1, 0
1, '안녕하세요 ', 1, 1, 0
6, ' 환영합니다 ', 1, 2, 1
7, ' 감사합니다 ', 1, 3, 2
4, ' 반가워요 ', 1, 3, 1
5, ' 감사합니다 ', 1, 4, 2
====================================
마찬가지로 동일한 그룹 번호에 있으면서 부모의 Seq 번호보다 큰 게시물의 Seq 번호를 모두 1만큼 증가시킵니다.
====================================
No, Title , Grp, Seq, Lvl
====================================
3, '모임이 있습니다', 3, 1, 0
2, '날씨가 맑습니다', 2, 1, 0
1, '안녕하세요 ', 1, 1, 0
6, ' 환영합니다 ', 1, 2, 1
7, ' 감사합니다 ', 1, 3, 2
4, ' 반가워요 ', 1, 4, 1
5, ' 감사합니다 ', 1, 5, 2
====================================
검색 할 때는 Grp를 내림차순으로 Seq를 오름차 순으로 정렬하면 됩니다. 인덱스는 기본키와 Grp+Seq의 복합 인덱스를 설정하면 됩니다.
실제 오라클에서 테이블을 구성하고 검색해봅니다.
drop table qnaboard;
create table qnaboard
(no number,
title varchar2(100),
contents varchar2(4000),
writer varchar2(20),
wdate date,
grp number,
seq number,
lvl number);
drop sequence qnaboard_no_seq;
create sequence qnaboard_no_seq
start with 1
increment by 1;
create index qnaboard_no_idx on qnaboard(no) reverse;
alter table qnaboard
add constraint qnaboard_no_pk primary key (no);
create index qnaboard_grp_seq on qnaboard(grp desc, seq asc);
alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
첫번째 게시물 입력 - 새 글 입력
insert into qnaboard
values(qnaboard_no_seq.nextval, '안녕하세요', null, '길동', sysdate, qnaboard_no_seq.currval, 1, 0);
두번째 게시물 입력 - 새 글 입력
insert into qnaboard
values(qnaboard_no_seq.nextval, '날씨가 맑습니다', null, '철수', sysdate, qnaboard_no_seq.currval, 1, 0);
세번째 게시물 입력 - 새 글 입력
insert into qnaboard
values(qnaboard_no_seq.nextval, '모임이 있습니다', null, '영희', sysdate, qnaboard_no_seq.currval, 1, 0);
네번째 게시물 입력 - 첫번째 게시물의 답글
답글이 올라오는 경우에는 답글에 부여 할 seq를 먼저 확보해줍니다.
update qnaboard
set seq=seq+1
where grp=1 and seq>1;
insert into qnaboard
values(qnaboard_no_seq.nextval, '반가워요', null, '만수', sysdate, 1, 2, 1);
다섯번째 게시물 입력 - 네번째 게시물의 답글
update qnaboard
set seq=seq+1
where grp=1 and seq>2;
insert into qnaboard
values(qnaboard_no_seq.nextval, '감사합니다', null, '길동', sysdate, 1, 3, 2);
여섯번째 게시물 입력 - 첫번째 게시물의 두번째 답글
update qnaboard
set seq=seq+1
where grp=1 and seq>1;
insert into qnaboard
values(qnaboard_no_seq.nextval, '환영합니다', null, '찬호', sysdate, 1, 2, 1);
일곱번째 게시물 입력 - 여섯번째 게시물의 답글
update qnaboard
set seq=seq+1
where grp=1 and seq>2;
insert into qnaboard
values(qnaboard_no_seq.nextval, '감사합니다', null, '길동', sysdate, 1, 3, 2);
게시판을 검색하는 경우, grp로 내림차순, seq로 오름차순으로 정렬하면 됩니다.
select case when lvl=0 then no
when lvl>0 then null end no
, rpad('+', lvl, '-')||title title
, writer
, wdate
from qnaboard
order by grp desc, seq;
NO TITLE WRITER WDATE
----- -------------------- ---------- -------------------
3 모임이 있습니다 영희 2007-09-15 19:54:00
2 날씨가 맑습니다 철수 2007-09-15 19:53:55
1 안녕하세요 길동 2007-09-15 19:53:50
+환영합니다 찬호 2007-09-15 19:54:21
+-감사합니다 길동 2007-09-15 19:54:26
+반가워요 만수 2007-09-15 19:54:08
+-감사합니다 길동 2007-09-15 19:54:15