Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

트리구조에서 자신의 자식 또는 부모 찾기

처음 계층형 게시판을 접했을 때부터 나의 고민은 이거였다. 자신의 자식 또는 부모 찾기....

물론 이건 물론 만드는 사람의 정책에 따라 결정되는 문제이긴 한데 내가 생각하기에는 상당히 필요한 거였고 이게 또 계층형 혹은 트리구조는 여기저기에서 상당히 많이 필요한 것이기 때문에 자주 부딪히는 문제거리였다.

게시판의 계층형 글
(예시가 상당히 허접스럽긴 하지만 대충 이해해주고 봐주길 바란다.)

계층형 게시판에서 흔히 볼수 있는 구조이고 보통 계층형을 구현하면 무한계층이기 때문에 저런식의 구조로 맘껏 할 수 있다. 문제는 여기서 삭제를 할때 생긴다.(혹은 트리메뉴에서 통째로 이동을 시킬 때....)

"테스트 2"를 삭제할 때 하위메뉴가 달렸으면 삭제를 못하게 할 수도 있고 테스트2를 삭제하면 그하위에 달린 것도 삭제되게 할 수도 있다. 어쨌든 자신의 상위관계랑은 묶여다녀야 한다. 상위만 사라지고 하위만 남는 경우는 당연히 생기면 안된다.

요즘은 Flag를 하나 두고도 하긴 하지만 기본적으로 계층형일때는 3개의 플래그를 둔다. Group, Refer, Step이렇게 3개인데 꽤나 고민했었는데 이 3개로 자신의 하위를 골라내기가 어렵더란 말이지. 여기서 자신의 하위란 것은 "테스트 2"를 골랐을때 4,5는 나오지 않고 3만 골라낼 수 있어야 한다는거지.

이게 딱 필요한 상황이 생겼는데 동기인 J녀석이 해결해냈다. 먼가 깔끔하진 않은것 같지만 어쨌든 돌아가긴 잘 돌아간다. 오랫동안 고민하던건데 해결되서 기쁘다.. ㅎㅎ 현재 ASP를 하고 있기 때문에 예제가 ASP소스이다.. ㅎ


' 부모 찾기
do while bbsNum <> ""

    sql =       " SELECT TOP 1 bbsNum FROM board_table "
    sql = sql & " WHERE bbs_step < (SELECT bbs_step FROM board_table WHERE bbsNum="& bbsNum &")"
    sql = sql & " AND bbs_level = (SELECT bbs_level FROM board_table WHERE bbsNum="& bbsNum &") - 1"
    sql = sql & " AND bbs_group = (SELECT bbs_group FROM board_table WHERE bbsNum="& bbsNum &")"
    sql = sql & " ORDER BY bbs_step DESC "

    rs.open sql,con,3,1

    if rs.eof=false then
        bbsNum = rs(0)
        bbsNum = bbsNum & ""
    else                  '//부모가 없으면
        BGRPT_IDNO = ""   '//루프 끝냄
    end if

    rs.close
loop

어째보면 좀 무식해 보이긴 하지만 우리수준에서는 이정도 밖에 할 수 없었다. 어쨌든 삭제든 머든 하려고 할 때 현재의 bbsNum은 가지고 있을테고 그걸 가지고 step는 작고 level은 -1 작고 group가 같은 걸 찾아서 있으면 다시 bbsNum에 넣어서 loop를 돌리고 없으면 bbsNum에 공백을 넣어서 loop를 끝내는 구조이다.

먼가 더 좋은 해결책이 있을것 같기도 하지만...


'자식 찾기
sql =       " SELECT * FROM board_table "
sql = sql & " WHERE bbs_step >= (SELECT bbs_step FROM board_table WHERE bbsNum="& bbsNum &")"
sql = sql & " AND bbs_group = (SELECT bbs_group FROM board_table WHERE bbsNum="& bbsNum &")"
sql = sql & " ORDER BY bbs_step "

rs.open sql,con,3,1

if rs.eof=false then level = rs("bbs_level")

isStart = true

do while rs.eof=false
    bbsNum = rs("bbsNum")
    '//레벨이 크면 자식이다.
    if level < rs("bbs_level") or isStart=true then   
        '//여기서 먼가 액션을.....
        isStart = false
        rs.MoveNext
    '//레벨같거나 작은 거 만나면 루프멈춤
    else               
        Exit do
    end if
loop

자식을 찾을때도 물론 좀 무식한 방법이다. 같은 group의 step가 크거나 같은 목록을 가져와서 자신의 level을 기억해 둔 다음에 loop를 돌리면서 각 글마다 level을 비교해서 자식인지 아닌지를 비교하는 것이다.

왠만한건 돌려봤는데 큰 무리는 없이 잘 돌아갔다. 근데 지금 소스를 좀 보고 있자니 무한계층수준까지 죽~ 올라갔을대도 과연 잘 돌아갈지는 잘 모르겠네... ㅎㅎㅎㅎ 개량하다보면 좀더 좋은게 나타나겠지...
2007/10/22 00:08 2007/10/22 00:08