계층형 게시판은 게시판에 질문글이 올라왔을때 누군가 답글을 달면 이 답글을 질문글 바로 아래에 보여지게 하는 게시판입니다. 사실 웹상에 거의 99.9%의 게시판이 이런 계층형 게시판입니다. 얼추 게시판 만들기를 할 수 있다면 이제 이런 계층형 게시판만들기에 도전해보도록 합시다.

먼저 계층형 게시판의 대략적인 설명입니다. 계층형 게시판을 만들려고 하면 기존의 게시물을 새롭게 추가할때와 보여줄때에 정렬방식을 이용하기 위하여 3가지의 필드를 더 사용해야 합니다. 여기서는 편의상 어떻게 돌아가는가만 알아보는 의미에서 DB안 테이블에는 총 4개의 필드를 가지고 있고 각각 다음과 같이 이용한다고 생각합니다.

tite - 게시물의 제목저장
ref - 기준번호저장
pos - 위치저장
depth - 깊이 저장



이런 필드에 값을 저장할때는 다음과 같은  규칙을 이용하여 저장합니다. 편의상 답변이 달리는 글을 부모글이라고 하겠습니다.

(1) 새로운글 일때

새로운글의 ref = (기존레코드들중 가장 큰값의 ref) + 1
새로운글의 pos =  1
새로운글의 depth =  1



(2) 답변글 일때

답변글의 ref = 부모글의 ref
답변글의 depth = 부모글의 depth + 1

답변글의 pos = (기존에 레코드들중에서 ref가 부모글의 ref와 같은 레코들을 먼서 선택하고 이런 글중에서 pos값이 부모글의 pos보다 큰것은 무조건 +1 시킨후 ) 부모글의 pos + 1한값을 저장한다. 큰값이 없으면 그냥 pos = pos + 1 한다.




무슨 말인지 예를 들어보자. 위에서 언급한 방식대로만 저장하면 된다.

먼저 게시판에 질문이 올라왔다. ( 아무런 글도 없는데 답변글이 있을리 없다 ) 그럼 다음과 같이 저장한다.

저장되는 순서는

ref,pos,depth,title의 순으로 저장된다고 가정한다.

참고로 게시판에 제일 처음 글을 올리면 기존레코드들중 가장큰값의 ref는 널값을 가진다. 왜냐하면 레코드가 없으니깐(널이니깐) 이럴때 조건문을 이용해서 널일때는 무조건 1의 값을 가지도록 처리하면 된다. 자 새로운 글이 올라면 다음과 같이 기록이 된다.

1 (ref) -  1 (pos) - 1 (depth) - 질문(1)(title)



이 상태에서 두번째 글이 올라왔다. 그럼 우선 기존 레코드중 가장 큰 ref갑을 찾는다(여기서는 1) 그리고 +1 한값을 ref에 저장하고 pos와 depth에는 무조건 1의 값을 써준다. 다음은 그 결과이다.

1-1-1-질문(1)
2-1-1-질문(2) <-- 추가된글



이 상태에서 세번째글이 올라왔다. 여기 새로운글이니깐 같은 방식으로 ref=(ref최고값+1)

1-1-1-질문(1)
2-1-1-질문(2)
3-1-1-질문(3) <-- 추가된글



신난다 하나 더 올려보자.

1-1-1-질문(1)
2-1-1-질문(2)
3-1-1-질문(3)
4-1-1-질문(4) <-- 추가된글


앗 이때 누군가 질문(1)에 대한 리플을 달았다. 그럼 이제 질문(1)은 부모글이 되고 답글에 저장되는 값은 각각 다음과 같다.

1-1-1-질문(1) <-- 부모글
2-1-1-질문(2)
3-1-1-질문(3)
4-1-1-질문(4)



답변글 ref = (부모글 ref) = 1
답변글 depth = (부모글 depth) + 1 = 2
답변글의 pos = 먼저 부모글같은 ref 값이 있는지 검사. 있으면 그넘들의 pos값을 무조건 + 1 시킨다. 여기서는 그런 넘이 없으므로 무시하고 그냥 (부모글의 pos) + 1 = 2 의 값 저장

결과 다음과 같이 저장된다.

1-1-1-질문(1) <-- 부모글
2-1-1-질문(2)
3-1-1-질문(3)
4-1-1-질문(4)
1-2-2-질문(1)답(1) <-- 답글


이번에는 질문(3)에 대한 리플을 달면
1-1-1-질문(1)
2-1-1-질문(2)
3-1-1-질문(3) <-- 부모글
4-1-1-질문(4)
1-2-2-질문(1)답(1)



답글이니깐 방식(2)를 적용시키면 다음과 같다.

1-1-1-질문(1)
2-1-1-질문(2)
3-1-1-질문(3) <-- 부모글
4-1-1-질문(4)
1-2-2-질문(1)답(1)
3-2-2-질문(3)답(1) <-- 답글


이번에는 답글이 아니라 새글이 들어오면 방식(1)을 적용시켜 각각의 값은 다음과 같다.

1-1-1-질문(1)
2-1-1-질문(2)
3-1-1-질문(3)
4-1-1-질문(4)
1-2-2-질문(1)답(1)
3-2-2-질문(3)답(1)
5-1-1-질문(5) <-- 추가된글


자 이렇게 대충 쓰고 정렬시킨다. 제일 먼저 ref를 기준으로 정렬시켜보자.

select * from Table order by ref

이렇게 하면 ref값을 기준으로 내림차순정렬된다. 만약 ref값이 같으면 먼저 쓰여진 넘이 위에 있게 된다.

1-1-1-질문(1)
1-2-2-질문(1)답(1)
2-1-1-질문(2)
3-1-1-질문(3)
3-2-2-질문(3)답(1)
4-1-1-질문(4)
5-1-1-질문(5)



요렇게 된넘의 순서를 뒤집으면 ( select * from Table order by ref desc )

5-1-1-질문(5)
4-1-1-질문(4)
3-2-2-질문(3)답(1)
3-1-1-질문(3)
2-1-1-질문(2)
1-2-2-질문(1)답(1)
1-1-1-질문(1)



이런상태에서 이번에는 pos를 기준으로 내림 차순 정렬시키면 ( select * from Table order by ref desc, pos )

5-1-1-질문(5)
4-1-1-질문(4)
3-1-1-질문(3)
3-2-2-질문(3)답(1)
2-1-1-질문(2)
1-1-1-질문(1)
1-2-2-질문(1)답(1)



자 이걸 화면에 뿌리면 질문에 대한 답글이 바로 아래에 위치하게 된다.

좀더복잡한 경우를 보자. 일단 레코드에는 다음과 같다.

1-1-1-질문(1)
2-1-1-질문(2)
3-1-1-질문(3)
4-1-1-질문(4)
1-2-2-질문(1)답(1)
3-2-2-질문(3)답(1)
5-1-1-질문(5)


여기서 질문(1)답(1)에 대한 답글이 올라오면

1-1-1-질문(1)
2-1-1-질문(2)
3-1-1-질문(3)
4-1-1-질문(4)
1-2-2-질문(1)답(1) <-- 부모글
3-2-2-질문(3)답(1)
5-1-1-질문(5)


방식(2)를 적용시킨다.

답글 ref = 부모글 ref = 1
답글 depth = 부모글 depth + 1 = 3
답글 pos = 다음과 같이 구한다.

먼저 부모글의 ref와 같은넘을  찾는다.

1-1-1-질문(1) <-- 부모글의 ref와 같은놈    
2-1-1-질문(2)
3-1-1-질문(3)
4-1-1-질문(4)
1-2-2-질문(1)답(1) <-- 부모글
3-2-2-질문(3)답(1)
5-1-1-질문(5)


이넘들중에서 pos값이 부모글의 pos값보다 큰넘은 +1 해준다. 있나? 없다. 그럼 무시하고
답글 pos =  부모글 pos + 1 = 3

1-1-1-질문(1)    
2-1-1-질문(2)
3-1-1-질문(3)
4-1-1-질문(4)
1-2-2-질문(1)답(1) <-- 부모글
3-2-2-질문(3)답(1)
5-1-1-질문(5)
1-3-3-질문(1)답(1)답(1) <-- 답글


이번에도 다시 질문(1)답(1)에 대한 답글이 올라왔다.

1-1-1-질문(1)    
2-1-1-질문(2)
3-1-1-질문(3)
4-1-1-질문(4)
1-2-2-질문(1)답(1) <-- 부모글
3-2-2-질문(3)답(1)
5-1-1-질문(5)
1-3-3-질문(1)답(1)답(1)



역시 방식(2)를 적용시킨다.

답글 ref = 부모글 ref = 1
답글 depth = 부모글 depth + 1 = 3
답글 pos = 다음과 같이 구한다.

먼저 부모글의 ref와 같은넘을  찾는다.

1-1-1-질문(1) <-- 부모글의 ref와 같은놈    
2-1-1-질문(2)
3-1-1-질문(3)
4-1-1-질문(4)
1-2-2-질문(1)답(1) <-- 부모글
3-2-2-질문(3)답(1)
5-1-1-질문(5)
1-3-3-질문(1)답(1)답(1) <-- 부모글의 ref와 같은놈



이넘들 중에 pos값이 부모글 pos값보다 큰넘을 찾아 +1 시킨다.

1-1-1-질문(1) <-- 부모글의 ref와 같은놈    
2-1-1-질문(2)
3-1-1-질문(3)
4-1-1-질문(4)
1-2-2-질문(1)답(1) <-- 부모글
3-2-2-질문(3)답(1)
5-1-1-질문(5)
1-3-3-질문(1)답(1)답(1) <-- 부모글의 ref와 같은놈 : pos값이 큰놈



이놈의 pos값을 +1 시킨다.

1-1-1-질문(1) <-- 부모글의 ref와 같은놈    
2-1-1-질문(2)
3-1-1-질문(3)
4-1-1-질문(4)
1-2-2-질문(1)답(1) <-- 부모글
3-2-2-질문(3)답(1)
5-1-1-질문(5)
1-4-3-질문(1)답(1)답(1) <-- 부모글의 ref와 같은놈 : pos값이 큰놈



그리고 답글의 pos = 부모글 pos + 1 = 3 이 되므로 다음과 같이 된다.

1-1-1-질문(1)  
2-1-1-질문(2)
3-1-1-질문(3)
4-1-1-질문(4)
1-2-2-질문(1)답(1) <-- 부모글
3-2-2-질문(3)답(1)
5-1-1-질문(5)
1-4-3-질문(1)답(1)답(1)
1-3-3-질문(1)답(1)답(2)



이걸 정렬시켜보자 먼저 ref를 기준으로 정렬시키면 ( order by ref )

1-1-1-질문(1)
1-2-2-질문(1)답(1)
1-4-3-질문(1)답(1)답(1)
1-3-3-질문(1)답(1)답(2)
2-1-1-질문(2)
3-1-1-질문(3)
3-2-2-질문(3)답(1)
4-1-1-질문(4)
5-1-1-질문(5)



요걸 역순으로 정렬시키면 ( order by ref desc )

5-1-1-질문(5)
4-1-1-질문(4)
3-2-2-질문(3)답(1)
3-1-1-질문(3)
2-1-1-질문(2)
1-3-3-질문(1)답(1)답(2)
1-4-3-질문(1)답(1)답(1)
1-2-2-질문(1)답(1)
1-1-1-질문(1)



요 상태에서 pos를 기준으로 정렬시키면 ( order by ref desc, pos )

5-1-1-질문(5)
4-1-1-질문(4)
3-1-1-질문(3)
3-2-2-질문(3)답(1)
2-1-1-질문(2)
1-1-1-질문(1)
1-2-2-질문(1)답(1)
1-3-3-질문(1)답(1)답(2)
1-4-3-질문(1)답(1)답(1)



정렬끝


의문사항 : depth는 왜 정렬하는데 쓰이지 않는데 머하러 값을 주는가?

답 : depth는 말 그래도 들어간 깊이를 말하는것입니다. 정렬하는데는 쓰이지 않지만 나중에 게시판에 보여질때 답글은 부모글보다 약간 안쪽으로 들어가게 해야 합니다. 그 들어가는 깊이를 말하는거죠.

최초 질문글이 올라오면 depth는 1의 값을 가집니다. 이때를 기준으로 잡아서 맨앞에 놓고 답글이 올라오면 질문글에 대한 답글이므로 depth는 그 답글보다 하나 높은 값을 가집니다. 그러므로 이것을 이용해서 앞에 여백을 몇개 넣으주면 게시판에서 답글은 질문글보다 들어가게 보이게 할수있는데 사용된답니다.

이걸 안써도 정렬하는데에는 이상없습니다. 하지만 정렬시키고 웹상에 보여주는데 있어 들어간것