2013. 11. 22. 11:00

결론:

SELECT * FROM tb_b1 WHERE b_index > 10 ORDER BY b_index ASC LIMIT 1;  [이전글]

SELECT * FROM tb_b1 WHERE b_index < 23 ORDER BY b_index DESC LIMIT 1; [다음글]

참조:

http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=19972&sca=&sfl=wr_subject%7C%7Cwr_content&stx=%C0%C0%B4%E4%C7%FC+%B0%D4%BD%C3%C6%C7&sop=and

시판에서 글보기를 했을시 하단에 전체 글목록을 보여주는 방법도 있지만

현재 보는글과 관련된글(답글)을 보여주면서 동시에 이전글, 다음글로 바로 이동하게 하는 방법도 있습니다.

이전글, 다음글로 바로 이동할때는 글을 보는 페이지(view.php)에서 이전글, 다음글에 해당하는 데이터를 알아야 합니다.

우선 묻지마보드의 경우에는 글보기를 할때 키값이 글번호입니다.

그럼 현재 보는글에서 다음글, 이전글에 대한 글번호를 구할수가 있어야 합니다.


예전에 초기버전의 묻지마보드의 경우에는 디비에 저장되는 글번호의 형식이 auto_increment 형식이 아닌

일반 int 형식으로 글을 작성할때마다 직접적인 번호조작에 의해서 1부터 차례대로 디비에 저장이 되게 됩니다.

그래서 이전글, 다음글을 불러올때는 아주 간편하게 해결이 됩니다.


예전 게시판처럼 글번호가 1,2,3,4 이렇게 무조건 순차적으로 저장이 될경우에는

이전글은 현재보는 글번호 + 1

다음글은 현재보는 글번호 - 1

이런식으로 되게됩니다. 그렇다면 이렇게 간편한데.. 왜 그런 방식을 채택하지 않냐는 의문이 생깁니다.

바로 효율성때문입니다. 현재는 글번호 필드가 auto_increment로 저장이 되며 글삭제시 그 삭제된부분의 

번호는 뻥뚤리게 됩니다. 그러면 글목록을 불러올때 글번호가 차례대로 출력되는건 가상번호때문입니다.

이 가상번호란 디비에 저장되어있는것이 아니라 리스팅할때 list.php 파일속에서 자체적으로 번호를 순차적으로 만들어 줍니다.


현재 묻지마보드의 경우 이러한 가상번호로 리스팅할때 순차적으로 번호가 주어지게 되며, 실제로 디비에 저장되는

글번호(no)는 아래 그림처럼 글이 삭제된경우에는 순차적인게 아니라 삭제된 부분의 번호는 비어있게 됩니다.


<그림 1>



답글이 달려도 그러하고 글이 삭제된 경우에도 그부분에 해당하는 글번호는 비게됩니다.

이러한 경우에는 이전글, 다음글을 가져올때 위의 방법처럼 1을 더하고 1을 뺀다고해서 해결될 문제가 아닙니다.

운이 좋다면 1을 더했을때 이전글을 추출할수 있을것이고 운이 나쁘다면 못할것입니다. 근데 우리는 운을 믿어서는 안되죠..^^


이제 본격적으로 이전글, 다음글을 구하는 Logic에 대해서 알아보도록 하겠습니다.

기본 원리는 시간을 이용한것입니다.


<그림 2>




이전글은 현재 보고있는 글보다 분명 먼저 작성된 글이다. (즉, date 값이 작음)

다음글은 현재 보고있는 글보다 분명 이후에 작성된 글이다. (즉, date 값이 큼)


여기서 말하는 date값이란 디비에 저장되는 글쓴시간의 타임스탬프 값입니다.


<그림 2>에서 현재 보고있는글은 503번 글이라고 한다면 우리에게 필요한것은 504번글과 502번글의 글 고유번호입니다.

이것을 구하기 위해서 503번글이 작성된 시간을 바탕으로 쿼리를 날리게 됩니다.


<그림 3>



이 쿼리에서 que1은 다음글을 구해오는 쿼리이며 que2는 이전글을 구하는 쿼리입니다.

que1을 보면 디비에서 date가 현재 우리가 보는 글이 쓰여진 날짜($row[date])보다 작은걸 가져옵니다.

즉, <그림2>에서 503번글 밑으로의 글들을 말하는거죠.

근데 이때 문제는 502번, 501번, 500번 즉, 503번 밑으로 모든 글들은 날짜가 $row[date]보다 작습니다.

그래서 뒤에 따라오는게 바로 "order by no desc limit 1" 입니다.

즉, 날짜가 작은것 중에서 역순으로 딱 한개만 쿼리하는거죠. 결과적으로 말하면 이 쿼리가 바로 <그림2>에서 502번을 가져오는거죠.


이전글을 구하는 쿼리 역시 같습니다. 위에서 설명한대로 하지만 단 한가지 다른점은 이번에는 역순(desc)으로 가져오는게 

아니라 정순(asc)로 가져와야합니다. 잘 생각해보시면 이해가 될겁니다. <그림2>에서 503번 위쪽에서 딱 하나를 가져올때는

가장 밑에 글을 가져와야만 그게 504번글이 되기때문이죠.


이해가 되셨나요??

이부분이 이전글, 다음글을 구하는 알고리즘의 가장 핵심부분입니다.

이것만 view.php 파일속에 제대로 삽입했다면 그다음에는 여러분이 원하시는데로 만들수 있습니다.

저같은 경우에는 다음 그림처럼 보이게 만들었습니다.


<그림 4>

위 그림에서 아래쪽 화살표를 클릭하면 다음글을.. 위쪽 화살표를 클릭하면 이전글을 보게 됩니다.

근데 저는 여기에 약간의 기능을 더 추가했습니다.


이전글이나 다음글이 없다면, 즉, 현재 보는글이 가장 첨의 글이거나 가장 나중의 글이라면

이전글, 다음글 버튼을 회색으로 처리했습니다. 그리고 그 버튼을 눌르면 "존재하지 않는 글을 선택하셨습니다." 라는

경고창을 띄우고 되돌려 보내게 했습니다.


이부분의 구현방법은 <그림 3>과 아래 그림을 잘 비교해보시면 이해가 갈겁니다.

<그림 3>은 게시판 자체 view.php 파일이며, 아래 그림은 스킨폴더속의 view_foot.php파일의 한 부분입니다.


<그림 5>



이제 구현하시겠습니까??

사실 간단해 보이지만 이 부분을 구현해내기위해서 혼자서 데이터베이스의 필드를 조작해보기도 하고

새로운 필드(prev_no, next_no)를 추가해보기도 했습니다. 근데 너무 일이 복잡해질듯해서 생각해본 결과

이렇게 간단하게 해결이 되더군요. 한번 해보시기 바랍니다.

Posted by hoonihoon