프로그래밍/PHP

PHP - MYSQL과 PHP를 이용한 게시판 속도 업그레이드

가카리 2014. 6. 22. 17:55
반응형

이전에 만든 데이터 베이스에서 100만개의 게시글을 넣어봅시다.


db_info.php


<?

$board="threadboard";

$conn=@mysql_connect("localhost", "디비 아이디","디비 비번") or die('데이터베이스에 연결할 수 없습니다');
@
mysql_select_db("php_brain", $conn) or die('선택한 데이터베이스를 사용할 수 없습니다.');
@
mysql_query("set names euckr");

?>


다음 php파일은 100만개의 게시글을 올리는 소스입니다.


이 소스의 실행시간이 오래 걸리니까 좀 기다려야 할 겁니다.


mil_ins.php


<?
//스크립트 종료할때까지
set_time_limit
(0);

//데이터 베이스 연결하기
include "db_info.php";

// 글 등록에 대한 기본적인 정보
$name = "브라운";
$pass = "1234";
$email = "happybrown@naver.com";

if (ob_get_level() == 0) ob_start();

for ($i=1;$i<=1000000;$i++)
{
    $title = "$i 번째 테스트 게시물";
   
$content = "$i 번째 테스트 게시물 내용";

   
// 답글을 위해 thread 값은 index 값의 1000배
    $max_thread = $i * 1000;

   
$query = "INSERT INTO $board (id,thread,depth,name,pass,email,
    title,view,wdate,ip,content) "
;
   
$query .= "VALUES ('',$max_thread,0,'$name','$pass','$email',
    '$title',0, UNIX_TIMESTAMP(), '$REMOTE_ADDR','$content')"
;
   
$result=mysql_query($query, $conn);

   
if ($result) {
        $success++;
       
print("$i INSERT 성공<BR> ");
   
}
    else {
        $failure++;
       
print("$i INSERT <B>실패</B><BR> ");
   
}
   
   
// 이 프로그램이 시스템 자원을 많이 할당받는것을 막기위해
    // 10000번당 1초씩 쉬어줍니다.
    if(($i%10000) == 0) sleep(1);
}
//데이터베이스와의 연결 종료
mysql_close
($conn);
?>


만약에 위의 실행결과가
















이렇게 검은 화면과 함께 웹브라우저가 멈춘 듯 보이면 이것은 출력 값이 제대로 웹 브라우저


에 출력되지 않아서 생기는 현상입니다. 그 이유는 PHP가 PHP 버퍼에 출력 결과를 저장해두


고 웹 브라우저로 출력 값을 전송하지 않았기 때문에 발생합니다. 윈도우 기반의 웹서버의 경


우 이런경우가 많은데 이때 PHP의 flush()함수를 써서 버퍼의 쌓인 결과 값을 바로 내보내면


이런 현상이 없어질 것 입니다.


sleep()호출전에 flush()를 호출해보세요!









만약 이전의 게시판에서 id가 primary key로 되있는데 thread값 또한 유일한 값이므로


thread 값에도 인덱스를 설정해주는 것이 중요합니다. 만약에 UNIQUE로 설정해두면 실수로


중복되어 thread 값이 중복이 되는 것을 방지해줍니다.


인덱스 추가 방법


ALTER TABLE threadboard ADD UNIQUE thread_index(thread);


인덱스 삭제방법


 DROP index thread_index on threadboard;


인덱스를 사용하지 않았을 때


SELECT name FROM threadboard ORDER BY thread DESC LIMIT 500000, 10; 실행 결과




인덱스를 사용했을 때


SELECT name FROM threadboard ORDER BY thread DESC LIMIT 500000, 10; 실행 결과







속도를 올리는 방법 두번째

ORDER BY thread DESC는 느리다.


ASC가 DESC보다 빠르다. 이유는 가장 최근에 등록된 값이 큰 id와 thread 값을 가지고 있기 때문에 내림차순으로 정렬하려면 불러올 때 다시 거꾸로 뒤집어야한다.


ASC형 게시판을 만들기위해서 다음과 같은 두가지 방법을 사용함.


1. 글 번호를 음수로 하여 1000씩 빼가면서 등록

2. 글 번호를 9999999000과 같은 큰 값에서 1000씩 빼가면서 등록


본격적으로 음수를 사용하는 게시판을 만들기에 앞서 기존의 100만개 레코드를 음수로 변경하도록 합시다.


UPDATE threadboard SET thread = -1*thread;


여기서 thread 는 반드시 int 타입이어야합니다.


그리고 이전 강의때 만들었던 list.php에서


다음과 같이 쿼리문을 바꿔줘야합니다


원래 아래였는데

$query = "SELECT * FROM $board ORDER BY thread DESC LIMIT $no,$page_size";


이걸로 바꿔야합니다.

$query = "SELECT * FROM $board ORDER BY thread LIMIT $no,$page_size";


단순히 DESC만 지워졌습니다.


list.php 파일


<?
//데이터 베이스 연결하기
include "db_info.php";

###################################################################
# LIST 설정
# 1. 한 페이지에 보여질 게시물의 수
$page_size=10;

# 2. 페이지 나누기에 표시될 페이지의 수
$page_list_size = 10;

###################################################################
//$no 값이 안넘어 오거나 잘못된(음수)값이 넘어오는 경우 0으로 처리
$no = $_GET[no];
if (!$no || $no <0) $no=0;
###################################################################

// 데이터베이스에서 페이지의 첫번째 글($no)부터 $page_size 만큼의 글을 가져온다.
$query = "SELECT * FROM $board ORDER BY thread LIMIT $no,$page_size";
$result = mysql_query($query, $conn);

// 총 게시물 수 를 구한다.
//count 를 통해 구할 수 있는데 count(항목) 과 같은 방법으로 사용한다. * 는 모든 항목을 뜻한다.
//총 해당 항목의 값을 가지는 게시물의 개수가 얼마인가를 묻는것이다.
//따라서 전체 글수가 된다. count(id) 와 같은 방법도 가능하지만
//이례적으로 count(*)가 조금 빠르다. 일반적으로는 * 가 느리다.
$result_count=mysql_query("SELECT count(*) FROM $board",$conn);
$result_row=mysql_fetch_row($result_count);
$total_row = $result_row[0];

//결과의 첫번째 열이 count(*) 의 결과다.
###################################################################
# 총 페이지 계산
if ($total_row <= 0) $total_row = 0; // 총게시물의 값이 없거나 할경우 기본값으로 세팅
// 총게시물에 1을 뺀뒤 페이지 사이즈로 나누고 소수점이하를 버린다.

$total_page = floor(($total_row - 1) / $page_size);
# 총페이지는 총 게시물의 수를 $page_size 로 나누면 알수있다.
# 총 게시물이 12개(1을 빼서 11이된다)이고 페이지 사이즈가 10이라면 결과는 1.1 이 나올것이다.
# 1.1 라는 페이지수는 한 페이지를 다 표시하고도 글이 더 남아있다는 뜻이다.
# 따라서 실제의 페이지수는 2가된다. 한 페이지는 2개의 글만 표시될것이다.
# 그러나 내림을 해주는 이유는 페이지수가 0부터 시작하기 때문이다. 따라서 1은 두번째 페이지이다.
# 총 게시물에 1을 빼주는 이유는 10페이지가 되면 10/10 = 1 이기 때문이다.
# 앞에서도 말했지만 1은 2번째 페이지를 뜻한다.
# 그러나 총게시물이 10개인 경우 한페이지에 모두 출력이 되어야 한다.
# 그래서 1을 빼서 10개인 경우 (10-1) / 10 = 0.9 로 한페이지에 출력하게 한다.
# 글이 0개가 있는 경우는 결과가 -1 이 되지만 -1은 무시된다.
# ( floor 는 내림을 하는 수학함수이다.)

###################################################################
# 현재 페이지 계산
$current_page = floor($no/$page_size);
# $no 을 통해서 페이지의 첫번째 글이 몇번째 글인지 전달된다.
# 따라서 페이지 사이즈로 나누면 현재가 몇번째 페이지인지 알수있다.
# $no 이 10이고 페이지사이즈가 10 이라면 결과는 1이다. 앞서 페이지는 0부터
# 시작이라고 했으니 두번째 페이지임을 나타낸다.
# 그렇다면 $no 이 11이라면 1.1 이 되어버린다. 11번째 글도 두번째 페이지에 존재하므로 0.1
# 은 무의미하니 버린다.
# 그런데 $no 이란 값이 $page_size 만큼씩 증가되는 값이기때문에 (0,10,20,30 과 같은
# 등차수열) 내림을 하는것 또한 무의미하다.
# 그러나 내림을 하는 이유는 $no 값에 11과 같은 값이 들어와도 제대로 출력되기를 바라는
# 마음에서 해놓은것이다.
?>
<html>
<head>
<title>계층형 게시판</title>
<style>
<!--
td
{ font-size : 9pt; }
A:link { font : 9pt; color : black; text-decoration : none;
font-family: 굴림; font-size : 9pt;
}
A:visited { text-decoration : none; color : black;
font-size : 9pt;
}
A:hover { text-decoration : underline; color : black;
font-size : 9pt;
}
-->
</style>
</head>
<body topmargin=
0 leftmargin=0 text=#464646>
<center>
<BR>
<!-- 게시물 리스트를 보이기 위한 테이블 -->
<table width=
580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>
<!-- 리스트 타이틀 부분 -->
<tr height=
20 bgcolor=#999999>
    <td width=30 align=center>
        <font color=white>번호</font>
    </td>
    <td width=
370 align=center>
        <font color=white>제 목</font>
    </td>
    <td width=
50 align=center>
        <font color=white>글쓴이</font>
    </td>
    <td width=
60 align=center>
        <font color=white>날 짜</font>
    </td>
    <td width=
40 align=center>
        <font color=white>조회수</font>
    </td>
</tr>
<!-- 리스트 타이틀 끝 -->
<!-- 리스트 부분 시작 -->
<?
    while($row=mysql_fetch_array($result))
    {
?>
<!-- 행 시작 -->
<tr>
    <!-- 번호 -->
    <td height=
20 bgcolor=white align=center>
        <a href=
"read.php?id=<?=$row[id]?>&no=<?=$no?>">
       
<?=$row[id]?></a>
    </td>
    <!-- 번호 끝 -->
    <!-- 제목 -->
    <td height=
20 bgcolor=white>&nbsp;
       
<?
       
if ($row[depth] >0)
           
echo "<img height=1 width=" . $row[depth]*7 . ">└";//이부분은 답변을 달때 들여쓰기를 위한 곳. 7씩 늘어나게 들여쓰기함
        ?>
        <a href="read.php?id=<?=$row[id]?>&no=<?=$no?>">
       
<?=strip_tags($row[title]);?></a>
    </td>
    <!-- 제목 끝 -->
    <!-- 이름 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black>
        <a href=
"mailto:<?=$row[email]?>"><?=$row[name]?></a>
        </font>
    </td>
    <!-- 이름 끝 -->
    <!-- 날짜 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
date("Y-m-d",$row[wdate])//여기서는 date 함수를 써서 유닉스 타임 스탬프 값을 날짜 형식으로 출력함. ?></font>
    </td>
    <!-- 날짜 끝 -->
    <!-- 조회수 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
$row[view]?></font>
    </td>
<!-- 조회수 끝 -->
</tr>
<!-- 행 끝 -->
<?
    } // end While

//데이터베이스와의 연결을 끝는다.

mysql_close
($conn);
?>
</table>
<!-- 게시물 리스트를 보이기 위한 테이블 끝-->
<!-- 페이지를 표시하기 위한 테이블 -->
<table border=
0>
<tr>
    <td width=
600 height=20 align=center rowspan=4>
    <font color=gray>
    &nbsp;
<?
###################################################################
# 페이지 리스트
# 페이지 리스트의 첫번째로 표시될 페이지가 몇번째 페이지인지 구하는 부분이다.

$start_page = (int)($current_page / $page_list_size)
    *
$page_list_size;

#현재 페이지를 페이지 리스트 수로 나누면 현재 페이지가 몇번째 페이지리스트에 있는지 알게된다.
# 이또한 0을 기준으로 하기에 형변환(타입 캐스팅)을 해주었다.
# 형변환은 앞 강좌에서 배웠지만 위의 나누어지는 수가 1.2와 같이 유리수로 표시되기때문에
# int(정수) 형으로 형변환을 하게되면 소수점자리가 사라지게 된다.
# 즉, 위에서 사용한 floor 랑 같은 효과를 하게 되는 것이다.
# 여기에 floor 함수를 취하거나 위의 floor 를 형변환을 해도 상관없다.
# 페이지 리스트의 마지막 페이지가 몇번째 페이지인지 구하는 부분이다.

$end_page = $start_page + $page_list_size - 1;
if ($total_page <$end_page) $end_page = $total_page;

# 보여주는 페이지 리스트중에서 마지막 페이지가 되는 경우는 두가지이다.
# 1. 페이지가 페이지리스트 크기보다 더 많이 남아있을때
# 10개씩 뿌려주는데 총 11페이지가 존재한다면 11페이지는 두번째 목록페이지에 뿌려진다.
# 그렇다면 마지막 페이지 리스트는 10페이지 즉, 첫번째 페이지 + 9 번째 페이지이다.
# 2. 10개씩 뿌려주는데 5페이지 밖에 없다면?
# 마지막 리스트 페이지는 5 페이지가 된다.

###################################################################
# 이전 페이지 리스트 보여주기
# 페이지 리스트가 10인데 13번째 페이지에 있다면 두번째 목록페이지를 보고 있는것이다.
# 이전 목록페이지로 가고 싶을 때 사용한다.
# 이전 페이지 리스트가 필요할때는 페이지 리스트의 첫 페이지가 페이지 리스트 수보다 클때다.
# 페이지가 적어도 페이지 리스트 수보다는 커야 이전 페이지 리스트가 존재할테니까 말이다.
# 페이지 리스트의 수가 10인데 총 5페이지밖에 없다면 이전 페이지 리스트는 존재하지 않는다.

if ($start_page >= $page_list_size) {

# 이전 페이지 리스트값은 첫번째 페이지 리스트에서 뒤로 리스트의 수만큼 이동하면된다.
# $page_size 를 곱해주는 이유는 글번호로 표시하기 위해서이다.

    $prev_list = ($start_page - 1)*$page_size;
   
echo "<a href="$PHP_SELF?no=$prev_list">◀</a> ";
}
# 페이지 리스트를 출력
for ($i=$start_page;$i <= $end_page;$i++) {
    $page=$page_size*$i; // 페이지값을 no 값으로 변환.
    $page_num = $i+1; // 실제 페이지 값이 0부터 시작하므로 표시할때는 1을 더해준다.
   
   
if ($no!=$page){ //현재 페이지가 아닐 경우만 링크를 표시
        echo "<a href="$PHP_SELF?no=$page">";
   
}

    echo " $page_num "; //페이지를 표시

    if ($no!=$page){
        echo "</a>";
   
}
}
# 다음 페이지 리스트가 필요할때는 총 페이지가 마지막 리스트보다 클 때이다.
# 리스트를 다 뿌리고도 더 뿌려줄 페이지가 남았을때 다음 버튼이 필요할 것이다.
if($total_page >$end_page)
{
    # 다음 페이지 리스트는 마지막 리스트 페이지보다 한 페이지 뒤로 이동하면 된다.
    $next_list = ($end_page + 1)* $page_size;
   
echo "<a href=$PHP_SELF?no=$next_list>▶</a><p>";
}
?>
</font>
</td>
</tr>
</table>
<a href=write.php>글쓰기</a>
</center>
</body>
</html>


실행 화면


다음은 글 삽입을 담당하는 insert.php 파일입니다.

insert.php


글 삽입시 다음과 같은 알고리즘을 적용하게 됩니다.


1. 글 번호의 최소값을 구한다.

2. 구해진 최소값을 이용하여 일반 글의 번호를 구한다.

3. 일반 글의 번호에 1000을 뺀다.



따라서 글쓰기 소스는 다음과 같이 변경됩니다.


$query = "SELECT max(thread) FROM $board";

$max_thread_result = mysql_query($query, $conn);

$max_thread_fetch = mysql_fetch_row($max_thread_result);

$max_thread = ceil($max_thread_fetch[0]/1000)*1000+1000;


에서


$query = "SELECT min(thread) FROM $board";

$max_thread_result = mysql_query($query, $conn);

$max_thread_fetch = mysql_fetch_row($max_thread_result);

$max_thread = floor($max_thread_fetch[0]/1000)*1000-1000;


로 바뀝니다.


실행 화면






답변달기 파일 수정


답변 달기 알고리즘


1. 부모 글의 번호로부터 일반 글의 번호를 찾는다.

2. 일반 글에 1000을 더해서 바로 아래의 일반 글 번호를 계산한다.

3. 부모 글과 아래의 일반 글 사이에 존재하는 답변 글의 번호에 1씩 더한다.

4. 비워진 자리에 답변 글을 등록한다.



기존의 답변 달기


$prev_parent_thread = ceil($_POST[parent_thread]/1000)*1000 - 1000;//ceil는 올림함수인것을 잊지말자.


$query = "UPDATE $board SET thread=thread-1 WHERE

        thread > $prev_parent_thread and thread < $_POST[parent_thread]";

        $update_thread = mysql_query($query, $conn);


에서


$prev_parent_thread = floor($_POST[parent_thread]/1000)*1000 + 1000;//floor는 내림함수인것을 잊지말자.


        $query = "UPDATE $board SET thread=thread+1 WHERE

        thread < $prev_parent_thread and thread > $_POST[parent_thread]";

        $query .= " ORDER BY thread DESC";

        $update_thread = mysql_query($query, $conn);


($_POST[parent_thread]+1)로 바꿔야됨. 원래 -1임




insert_reply.php


<?
    //데이터 베이스 연결하기
    include "db_info.php";

   
   
$prev_parent_thread = floor($_POST[parent_thread]/1000)*1000 + 1000;//floor는 내림함수인것을 잊지말자.

    //원본글보다는 작고 위값보다는 큰 글들의 thread 값을 모두 1씩 낮춘다.
    //만약 부모글이 2000이면 prev_parent_thread는 1000이므로 2000> x >1000 인 x값을 모두 -1을 한다.
    //만약 부모글이 1950이면 prev_parent_thread는 1000이므로 1950> x >1000 인 x값을 모두 -1을 한다.
    $query = "UPDATE $board SET thread=thread+1 WHERE
    thread <$prev_parent_thread and thread >$_POST[parent_thread]"
;
   
$query .= " ORDER BY thread DESC";
   
$update_thread = mysql_query($query, $conn);

   
//원본글보다는 1작은 값으로 답글을 등록한다.
    //원본글의 바로 밑에 등록되게 된다.
    //depth는 원본글의 depth + 1 이다. 원본글이 3(이글도 답글이군)이면 답글은 4가된다.
    $query = "INSERT INTO $board (thread,depth,name,pass,email";
   
$query .= ",title,view,wdate,ip,content)";
   
$query .= " VALUES ('" . ($_POST[parent_thread]+1) . "'";
   
$query .= ",'" . ($parent_depth+1) ."','$_POST[name]','$_POST[pass]','$_POST[email]'";
   
$query .= ",'$_POST[title]',0, UNIX_TIMESTAMP(),'$_SERVER[REMOTE_ADDR]'";
   
$query .= ",'$_POST[content]')";
   
$result=mysql_query($query, $conn);

   
//데이터베이스와의 연결 종료
    mysql_close($conn);

   
// 새 글 쓰기인 경우 리스트로..
    echo ("<meta http-equiv='Refresh' content='1; URL=list.php'>");
?>
<center>
<font size=
2>정상적으로 저장되었습니다.</font>


실행화면




마지막으로 글 읽기 페이지를 수저해봅시다.


글 읽기의 경우 윗글 아랫글을 수정해야하고 하단에 위치한 관련 글 목록을 새로운 알고리즘에 맞게 수정해야합니다.


 read.php파일에서


기존 값

$query = "SELECT id, name, title FROM $board

WHERE thread > $row[thread] and depth=0 LIMIT 1";

$query=mysql_query($query, $conn);

$up_id=mysql_fetch_array($query);


$query = "SELECT id, name, title FROM $board WHERE

thread < $row[thread] and depth=0  ORDER BY thread DESC LIMIT 1";

$query=mysql_query($query, $conn);

$down_id=mysql_fetch_array($query);

//-- 중략--

$thread_end = ceil($row[thread]/1000)*1000;

$thread_start = $thread_end - 1000;


$query = "SELECT * FROM $board WHERE thread <= $thread_end and

thread > $thread_start ORDER BY thread DESC";

$result = mysql_query($query, $conn);


수정된 값


$query = "SELECT id, name, title FROM $board

WHERE thread < $row[thread] and depth=0 ORDER BY thread DESC LIMIT 1";

$query=mysql_query($query, $conn);

$up_id=mysql_fetch_array($query);


$query = "SELECT id, name, title FROM $board WHERE

thread > $row[thread] and depth=0  LIMIT 1";

$query=mysql_query($query, $conn);

$down_id=mysql_fetch_array($query);


//-- 중략--


$thread_end = floor($row[thread]/1000)*1000;

$thread_start = floor($row[thread]/1000)*1000+1000;


$query = "SELECT * FROM $board WHERE thread >= $thread_end and

thread < $thread_start ORDER BY thread ";

$result = mysql_query($query, $conn);




read.php 소스


<?
//데이터 베이스 연결하기
include "db_info.php";

$no = $_GET[no];
$id = $_GET[id];

// 조회수 업데이트
$query = "UPDATE $board SET view=view+1 WHERE id=$_GET[id]";
$result=mysql_query($query, $conn);

// 글 정보 가져오기
$query = "SELECT * FROM $board WHERE id=$_GET[id]";
$result=mysql_query($query, $conn);
$row=mysql_fetch_array($result);
?>
<html>
<head>
<title>계층형 게시판</title>
<style>
<!--
td
{ font-size : 9pt; }
A:link { font : 9pt; color : black; text-decoration : none;
font-family: 굴림; font-size : 9pt;
}
A:visited { text-decoration : none; color : black;
font-size : 9pt;
}
A:hover { text-decoration : underline; color : black;
font-size : 9pt;
}
-->
</style>
</head>
<body topmargin=
0 leftmargin=0 text=#464646>
<center>
<BR>
<table width=
580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>
<tr>
    <td height=
20 colspan=4 align=center bgcolor=#999999>
        <font color=white><B><?=strip_tags($row[title]);?>
        </B></font>
    </td>
</tr>
<tr>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>글쓴이</td>
    <td width=240 bgcolor=white><?=$row[name]?></td>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>이메일</td>
    <td width=240 bgcolor=white><?=$row[email]?></td>
</tr>
<tr>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>
        날&nbsp;&nbsp;&nbsp;짜</td><td width=240 bgcolor=white>
       
<?=date("Y-m-d", $row[wdate])?></td>
    <td width=
50 height=20 align=center bgcolor=#EEEEEE>조회수</td>
    <td width=240 bgcolor=white><?=$row[view]?></td>
</tr>
<tr>
    <td bgcolor=white colspan=
4 style="word-break:break-all;">
        <font color=black>
        <pre><?=
strip_tags($row[content]);?></pre>
        </font>
    </td>
</tr>
<!-- 기타 버튼 들 -->
<tr>
    <td colspan=
4 bgcolor=#999999>
    <table width=100%>
    <tr>
        <td width=
280 align=left height=20>
            <a href=
list.php?no=<?=$no?>><font color=white>
           
[목록보기]</font></a>
            <a href=reply.php?id=
<?=$id?>><font color=white>
           
[답글달기]</font></a>
            <a href=write.php><font color=white>
           
[글쓰기]</font></a>
            <a href=edit.php?id=
<?=$id?>><font color=white>
           
[수정]</font></a>
            <a href=predel.php?id=
<?=$id?>><font color=white>
           
[삭제]</font></a>
        </td>
    </tr>
    </table>
    </td>
</tr>
</table>

<table width=
580 bgcolor=white style="border-bottom-width:1;
border-bottom-style:solid;border-bottom-color:cccccc;"
>
<?
// 현재 글보다 thread 값이 큰 글 중 가장 작은 것의 id를 가져온다. depth가 0인것은 글만 찾기위해서임 depth가 1이상이면 그건  RE: 글이다.
$query = "SELECT id, name, title FROM $board
WHERE thread <$row[thread] and depth=0 ORDER BY thread DESC LIMIT 1"
;
$query=mysql_query($query, $conn);
$up_id=mysql_fetch_array($query);

if ($up_id[id]) // 이전 글이 있을 경우
{
    echo "<tr><td width=500 align=left height=25>";
   
echo "<a href=read.php?id=$up_id[id]>△ $up_id[title]</a></td>
    <td align=right>$up_id[name]</td></tr>"
;
}

// 현재 글보다 thread 값이 작은 글 중 가장 큰 것의 id를 가져온다. 오름차순으로하고 thread <$row[thread]로 해도 같다.
$query = "SELECT id, name, title FROM $board WHERE
thread >$row[thread] and depth=0  LIMIT 1"
;//원래 ORDER BY thread DESC 있던것 없어짐
$query=mysql_query($query, $conn);
$down_id=mysql_fetch_array($query);

if ($down_id[id])
{
    echo "<tr><td width=500 align=left height=25>";
   
echo "<a href=read.php?id=$down_id[id]>▽ $down_id[title]</a>
    </td><td align=right>$down_id[name]</td></tr>"
;
}
?>
</table>
<BR>
<?
//리스트 출력을 위해 thread를 계산한다.
//출력될 리스트는 글 전체 리스트가 아니라
//1000의 배수인 새글과 이를 포함한 답변글들의 리스트이다.
//답변글이 없는 경우 원본글만 리스트에 나오고
//답변글이 있으면 답변글 모두가 다 나오게된다.
//현재 글이 답변글이어도 새글부터 전체 답변글까지 나온다.
//그럴려면 1000~2000 과 같이 새글사이에 글들을 모두 뿌려주면 된다.

//만약 원본글이 삭제됬다면 답변글만 있다.
//만약 답변글이 1999라면 1999/1000=1.999 에서 올림을 하면 2가 됨 그리고 *1000을 하면 2000이 됨.
//즉 2000>= x >1000 의 범위의 값을 모두 찾아야됨.
$thread_end = floor($row[thread]/1000)*1000;
$thread_start = floor($row[thread]/1000)*1000+1000;

$query = "SELECT * FROM $board WHERE thread >= $thread_end and
thread <$thread_start ORDER BY thread "
;
$result = mysql_query($query, $conn);
?>
<!-- 게시물 리스트를 보이기 위한 테이블 -->
<table width=
580 border=0 cellpadding=2 cellspacing=1 bgcolor=#777777>
<!-- 리스트 타이틀 부분 -->
<tr height=
20 bgcolor=#999999>
    <td width=30 align=center>
        <font color=white>번호</font>
    </td>
    <td width=
370 align=center>
        <font color=white>제 목</font>
    </td>
    <td width=
50 align=center>
        <font color=white>글쓴이</font>
    </td>
    <td width=
60 align=center>
        <font color=white>날 짜</font>
    </td>
    <td width=
40 align=center>
        <font color=white>조회수</font>
    </td>
</tr>
<!-- 리스트 타이틀 끝 -->
<!-- 리스트 부분 시작 -->
<?
    while($row=mysql_fetch_array($result))
    {
?>
<!-- 행 시작 -->
<tr>
<!-- 번호 -->
    <td height=
20 bgcolor=white align=center>
        <a href=
"read.php?id=<?=$row[id]?>&no=<?=$no?>"><!-- =$noecho $no와 같은 의미 -->
       
<?=$row[id]?></a>
    </td>
    <!-- 번호 끝 -->
    <!-- 제목 -->
    <td height=
20 bgcolor=white>&nbsp;
       
<? //depth 값을 통해서 들여쓰기를 한다. 투명이미지의 가로사이즈를 늘이는 방법
        if ($row[depth] >0)
           
echo "<img src=img/dot.gif height=1 width=" .
           
$row[depth]*7 . ">->";
       
?>
        <a href="read.php?id=<?=$row[id]?>&no=<?=$no?>"><!-- =$noecho $no와 같은 의미 -->
       
<?=strip_tags($row[title], '<b><i>');?></a>
    </td>
    <!-- 제목 끝 -->
    <!-- 이름 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black>
        <a href=
"mailto:<?=$row[email]?>"><?=$row[name]?></a>
        </font>
    </td>
    <!-- 이름 끝 -->
    <!-- 날짜 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
date("Y-m-d",$row[wdate])?></font>
    </td>
    <!-- 날짜 끝 -->
    <!-- 조회수 -->
    <td align=center height=
20 bgcolor=white>
        <font color=black><?=
$row[view]?></font>
    </td>
<!-- 조회수 끝 -->
</tr>
<!-- 행 끝 -->
<?
    } // end While
mysql_close
($conn);
?>
</center>
</body>
</html>



실행 화면




지금까지 thread 항목이 오름차순으로 된 것을 속도를 빠르게 하기위해서 내림차순으로 바꿨습니다.



소스 출처 : http://brown.ezphp.net/85



반응형