복원 (데이터 등록)

MySQL -u사용자 -p암호 DB이름 < DB백업.sql -- DB가 존재 하지 않는 경우 미리 생성 후 진행 하여야 함.

윈도우에서 cmd 를 띄우고


mysql 을 설치한  폴더 bin 까지 이동한다


cd C:\Program Files\MySQL\MySQL Server 5.7\bin


이 상태에서 명령어를 치는데


특정데이터를  백업하려면 예를들어

academy데이터베이스를 백업하려면


mysqldump -uroot -p academy>academy.sql


전체데이터베이스를 백업하려면

mysqldump -uroot -p --all-databases>all.sql


그러면 암호를 치라고 나오고 그 후 bin 폴더에 가면 내가 지정한 all.sql 이 생성된걸 볼수 있다.



family
- 글번호 (실질적인 글 번호인 no와는 다름)
답변 글은 부모의 글의 family를 그대로 물려 받는다

orderby
-답변 글의 정렬 순서를 결정 (오름차순)
부모 글의 orderby에 1을 더한 값을 넣어주고, 부모 글과 family가 같고
부모글의 orderby보다 큰 게시물들의 ordery에 +1을 해주어 한 칸씩 뒤로 미루어 준다.

step
-몇 번째 단계의 답변인가를 판단하는 값
첫 번째 단계의 답변은 1, 그 답변의 답변은 2가 된다
결국 부모글의 step에 1을 더한값

 게시물 family  orderby  step 
 게시물3  3  0  0
 게시물2  2  0  0
      re 게시물2의 답변3  2  1  1
      re 게시물2의 답변2(부모)  2  2  1
         re 게시물2의 답변2의 답변1  2  3  2
      re 게시물2의 답변1  2  4  1
 게시물1  1  0  0
ORDER BY family DESC, orderby ASC

게시물2의 답변2에는
$data[family]=2
$data[orderby]=2
$data[step]=1 이다

게시물2의 답변2에 새로운 답변을 넣게 된다면 family는 부모의 것을그대로 물려 받게 되므로, 그대로 2가 된다
$family = $data[family] //답변글의 family

그리고 orderby와 step은 부모 글의 orderby와 step에 1을 더해준 값이므로
$orderby = $data[orderby]+1;
$step = $data[step] +1;

그런데 orderby에서는 부모글과 family가 같고, 부모글의 orderby보다 큰 모든 글의 orderby 에는 +1을 해줘야하므로
UPDATE  [테이블이름] SET orderby=orderby+1 WHERE family=$data[family] and orderby>$data[orderby]
위 쿼리문을 실행한다

즉 다시정리하면
family = 부모글의 family
orderby = 부모글의 family +1
step= 부모글의 step +1

UPDATE [테이블이름] SET orderby=orderby+1 WHERE family=부모글의 family and orderby>부모글의orderby

그런데 실제로 mysql에서의 정렬에서
내림차순DESC 정렬은 그리 효과적이지 못하다고 한다 속도가 ASC보다 느리기때문인데 따라서
ASC방법을 사용하기 위해 family에 -1을 곱해보자

 게시물 family  orderby  step 
 게시물3  -3  0  0
 게시물2  -2  0  0
      re 게시물2의 답변3  -2  1  1
      re 게시물2의 답변2(부모)  -2  2  1
         re 게시물2의 답변2의 답변1  -2  3  2
      re 게시물2의 답변1  -2  4  1
 게시물1  -1  0  0

물론 위와 같이 1씩 감소하는 형태가 되려면 family는 0에서부터 시작하여 답변 글이 아닌
새 글이 입력될때마다 -1을 해주도록 하면 간단하다

게시물1을 -1로 주고, 다음 게시물이 입력되면 family컬럼의 최소값을 구하여 새로운 게시물의 family값으로 넣어준다
SELECT MIN(family) FROM [테이블이름]

테이블에서 family컬럼의 최소값을 구하여 리턴하는데 우리는 이 값에 -1을 하여 새로운 게시물의 family값으로 사용한다.

위와 같이 family가 -1씩 감소하는 형태라면 게시물을 가져오는 정렬방법을 다음과 같이 수정해 주어야만 한다
ORDER BY family ASC, orderby ASC

기본적으로 우리가 기본키primary key로 지정한 칼럼은 인덱스가 설정되어 있기 때문에, 이 컬럼에 대해 오름차순정렬을 하고자 한다면 상당히 빠르게레코드를 가져올 수 있다.

이것은 우리가 꺼내오고자 하는레코드의 정렬방식이 오름차순ASC이기 때문이다

그런데 기본키로 지정하면 기본적으로 인덱스가 설정되지만
family와 orderby를 기본키로 설정할 수는 없는 것이므로,

INDEX라는 함수를 사용하여 테이블 생성할때 다음과 같이 인덱스를 걸어주자

CREATE TABLE [테이블이름] (
no int unsigned default '0' auto_increment primary key,
family int,
orderby int,
step int,
...
INDEX (family, orderby)
)

위와 같이 인덱스를 사용하면 사용하지 않은 테이블보다 훨씬 빠른 속도로 게시물을 가져 올 수가 있게된다.

하지만 단점은 인덱스 사용시
인덱스된 정보를 따로 저장해 놓기 때문에 mySQL의 용량이 그리 넉넉하지 않다면 인덱스는 그리 권장할 만한 것이 아닐것이다




글의내용보기
-GET방식으로 그 글의 기본키 값을 넘겨주는 것인데
글의 내용을 출력하는 페이지가
VIEW.PHP이고 테이블의 기본키가 no라고 한다면

글 목록의 글 제목에는다음과 같은 링크가 있어야 할 것이다
<a href='view.php?no=글번호'>

이렇게 글번호(no컬럼의 값)라는 기본키의 값을 view.php로 넘겨주면 view.php에서는
$no라는 값을 받아서, 테이블에서 no컬럼의 값이 $no와 같은 글을 꺼내어 그 내용을 출력하게 될 것이다.



테이블설계

CREATE TABLE bbs (
no int unsigned default '0' auto_increment primary key,
family int not null,
orderby int not null,
step int not null,
name char(20) not null,
title varchar(200) not null,
memo text not null,
hit int unsigned default '0'
)
->메모장에서 사용되었던 pass와 time컬럼은 간결한 소스를 위해 생략


write.php
<form method=post action=write_ing.php>
이름 <input type=text size=10 name=name><br>
제목 <input type=text size=30 name=title><br> 
<textarea cols=35 rows=5 name=memo></textarea><br>
<input type=submit value='글쓰기'>
</form>


write_ing.php (글의저장)
<?
include "connect.php"; // mySQL에 접속
include "lib.php"; // 함수 라이브러리

if (!$name) {error ('이름을 입력 하세요');} // 이름 체크
if (!$title) {error ('제목을 입력 하세요');} // 제목 체크
if (!$memo) {error ('내용을 입력 하세요');} // 내용 체크

$name = addslashes ($name); // 이름의 특수문자에 \를 붙임
$title = addslashes ($title); // 제목의 특수문자에 \를 붙임
$memo = addslashes ($memo); // 내용의 특수문자에 \를 붙임

$query = "SELECT MIN(family) FROM bbs"; //family컬럼의 최소값을구하여 그 값에 -1을 해준 값이 된다
$family = mysql_fetch_array (mysql_query ($query, $connect));
$family = $family[0]-1; //$family[0]대신에 $family["MIN(family)"]를 넣어주어도 결과는 같다
$orderby = 0;
$step = 0;

$query = "INSERT INTO bbs (family, orderby, step, name, title, memo)
VALUES ($family, $orderby, $step, '$name', '$title', '$memo')";
mysql_query ($query, $connect); // 글 저장

mysql_close ($connect); // mySQL 접속 끊기
move_page ("list.php"); // list.php로 이동
?>


list.php 글목록
<a href=write.php>글쓰기</a>

<table width=450 border=1>
<?
include "connect.php"; // mySQL에 접속

//페이징처리를 위한 구문
$query = "SELECT COUNT(*) FROM bbs"; // 갯수세기 쿼리문
$result = mysql_query ($query, $connect); // 쿼리문 입력
$total = mysql_result ($result, 0, 0); // 총 갯수 저장
$page = 10; // 페이지당 게시물 갯수
$pagesu = ceil ($total / $page); // 전체 페이지 갯수
$start = $page * $pagenum; // 시작위치

$number = $total - ($pagenum * $page); // 현재 페이지의 시작 글 번호

$query = "SELECT * FROM bbs ORDER BY family, orderby LIMIT $start,$page"; //bbs의 글 가져오기
$result = mysql_query ($query, $connect); // 글 꺼내기
while ($data = mysql_fetch_array ($result)) {
$data[name] = stripslashes ($data[name]); // 이름의 \제거
$data[title] = stripslashes ($data[title]); // 제목의 \제거

if ($data[step]) {$re = "re";} //step에 값이 있다는 것을 리플을 의미하므로 앞에 re를 붙여주자
else {$re = "";}

$blank="";
for ($i = 0; $i < $data[step]; $i++) {//step이 2이상이면 답변의 답변이므로 글목록을 좀더 안쪽으로 배치하기 위하여 공백문자를 더해주자
$blank .= "&nbsp;";
}

echo "<tr> //리스트에 보여주고자 하는 것을 출력하자 no, title, name, hit
<td width=1% nowrap>$number</td>
<td width=97%>$blank$re<a href=view.php?no=$data[no]>$data[title]</a>
</td>
<td width=1% nowrap>$data[name]</td>
<td width=1% nowrap>$data[hit]</td>
</tr>";


$number--; // 글 번호 감소
}
?>
<table>


<?
$pagegroup = 5; // 페이지 그룹당 페이지 수
$pageend = $pagestart +$pagegroup; // 페이지 그룹의 마지막 페이지
$pagegroupnum = ceil(($pagenum + 1) / $pagegroup); // 현재의 페이지 그룹
$pagestart = ($pagegroupnum - 1) * $pagegroup + 1; // 페이지 그룹의 첫 페이지
$pageend = $pagestart +$pagegroup - 1; // 페이지 그룹의 마지막 페이지

$prevgroup = $pagegroupnum - 1; // 이전 그룹
$prevstart = ($prevgroup - 1) * $pagegroup; // 이전 페이지 그룹의 첫 페이지
if ($pagegroupnum != 1) { // 이전 페이지 그룹으로 이동
echo "[<a href='$PHP_SELF?pagenum=$prevstart'>◀◀</a>] ";
}

for ($i = $pagestart; $i <= $pageend; $i++) { // 페이지 이동 버튼 출력
if ($i > $pagesu) {break;} // 페이지 체크
$j = $i - 1; // 넘겨줄 $pagenum
echo "[<a href='$PHP_SELF?pagenum=$j'>$i</a>] ";
}


$nextgroup = $pagegroupnum + 1; // 다음 그룹
$nextstart = ($nextgroup - 1) * $pagegroup; // 다음 페이지 그룹의 첫 페이지
if ($pagesu > ($nextstart + 1)) { // 다음 페이지 그룹으로 이동
echo " [<a href='$PHP_SELF?pagenum=$nextstart'>▶▶</a>]";
}
?>



view.php 글내용
<?
include "connect.php"; // mySQL에 접속

$query = "UPDATE bbs SET hit=hit+1 WHERE no=$no"; //조회수가 올라가는 쿼리문
mysql_query ($query, $connect); // 조회수 증가

$query = "SELECT * FROM bbs WHERE no=$no"; //선택한 글을 꺼내오는 쿼리
$data = mysql_fetch_array (mysql_query ($query, $connect))
;
$data[name] = stripslashes ($data[name]); // 이름의 \제거
$data[title] = stripslashes ($data[title]); // 이름의 \제거
$data[memo] = stripslashes ($data[memo]); // 내용의 \제거
$data[memo] =nl2br ($data[memo]); // 띄어쓰기
?>

<table width=450 border=1> //실제 데이터를 출력해주는부분
<tr><td>글쓴이</td><td><?=$data[name]?></td></tr>
<tr><td>조회수</td><td><?=$data[hit]?></td></tr>

<tr><td>제목</td><td><?=$data[title]?></td></tr>
<tr><td>내용</td><td><?=$data[memo]?></td></tr>
</table>
<a href=list.php>글 목록</a> //데이터하단에 목록으로 돌아가는링크와 리플링크를 추가해줌
<a href=reply.php?no=<?=$data[no]?>>답변 쓰기</a>


reply.php 답변쓰기
<form method=post action=reply_ing.php>
<input type=hidden name=no value=<?=$no?>>
이름 <input type=text size=10 name=name><br>
제목 <input type=text size=30 name=title><br> 
<textarea cols=35 rows=5 name=memo></textarea><br>
<input type=submit value='답변쓰기'>
</form>


reply_ing.php 답변글저장
<?
include "connect.php"; // mySQL에 접속
include "lib.php"; // 함수 라이브러리

if (!$name) {error ('이름을 입력 하세요');} // 이름 체크
if (!$title) {error ('제목을 입력 하세요');} // 제목 체크
if (!$memo) {error ('내용을 입력 하세요');} // 내용 체크

$name = addslashes ($name); // 이름의 특수문자에 \를 붙임
$title = addslashes ($title); // 제목의 특수문자에 \를 붙임
$memo = addslashes ($memo); // 내용의 특수문자에 \를 붙임

$query = "SELECT * FROM bbs WHERE no=$no"; //부모글의 값을 가져오는쿼리
$data = mysql_fetch_array (mysql_query ($query, $connect));

$family = $data[family];
$orderby = $data[orderby]+1;
$step = $data[step]+1;

$query = "UPDATE bbs SET orderby=orderby+1 WHERE family=$data[family] AND orderby>$data[orderby]";
mysql_query ($query, $connect);

$query = "INSERT INTO bbs (family, orderby, step, name, title, memo)
VALUES ($family, $orderby, $step, '$name', '$title', '$memo')";
mysql_query ($query, $connect); // 글 저장

mysql_close ($connect); // mySQL 접속 끊기
move_page ("list.php"); // list.php로 이동
?>

완벽한 게시판을 위해서는
비번을 입력받고, 삭제, 수정기능을 추가하여야 한다

출처; php초보탈출이야기 / 신동규/ PCBOOK[책도서]

각 메모장을 구분하는 id가 필요하다
그리고 그 id에 따라서 테이블 이름이 결정되는데, 그 형식은
exam_memo_id

예를들어 test라는 메모장을 생성한다면 테이블이름은 exam_memo_test가 될 것이다.
물론 스키마는 기존의 테이블과 같다 그렇기 때문에 같은 모양의 다른 내용의 메모장을 계속 생성해 줄 수가 있다

테이블이 생성되었으면 메모장 소스를 약간 손봐주어야 하겠는데,
메모장을 호출할때는 다음과 같이 GET방식으로 호출할 메모장의 ID를 넘겨주어야 하므로 주소창에
list.php?id=test
와 같이 넣어줘야 한다

쿼리문도 변경해야 한다
SELECT * FROM exam_memo_$id


글쓰기 폼의 경우도 변경해 준다
<a href='write.php?id=$id'>글쓰기 </a>


install.php
<?
include "connect.php"; //mysql접속
$query ="CREATE TABLE exam_memo_$id (
no int unsigned default '0' auto_increment primary key,
name char(20) not null,
memo text not null,
pass char(20) not null,
time int unsigned
)";
mysql_query ($query, $connect); //테이블 생성


write_ing.php
<?
$query="INSERT INTO exam_memo_$id ( name, memo, pass, time) VALUES ('$name', '$memo', '$pass', '$time')";
echo $query;


물론 글 입력 후 페이지 이동은
move_page ("list.php?id=test");
와 같이 해주어야 한다

검색을 하기 위한 폼을 list.php에 추가한다
<form method=get action=list.php>
</form>

여기서 액션이 list.php인 것은 검색을 하기 위해 입력된 검색어와 검색항목 등을 다시 list.php로 전해주기 위해서 이다.
list.php에서는 이렇게 검색을 실행하였을 때 전체의 글 리스트가 아닌검색된 글만을 보여주게 하겠다는 얘기

<form method=get action=list.php>
<input type=checkbox name=search_name value=1 checked> 이름에서 //체크가되면 1이라는 값이 들어가도록
<input type=checkbox name=search_memo value=1 checked> 메모에서
<input type=text size=10 name=search_word>
<input type=submit value='검색'>
</form>



2.검색의 실행
if ($search_word) { //검색어가 있을경우 검색을 실행
if (!search_name && !search_memo) {
error ('검색 항목을 선택 하세요');
}
}

name컬럼에 a라는 문자가 포함된 레코드만을 가져오려 한다면
SELECT * FROM exam_memo WHERE name LIKE '%a%'

memo컬럼에도 a라는 문자가 포함된 레코드를검색하도록 추가하려면
SELECT * FROM exam_memo WHERE name LIKE '%a%' OR memo LIKE '%a%'


$where = ""; //기본 where절
$query = "SELECT * FROM exam_memo $where ORDER BY no DESC LIMIT $start, $page";
$query = "SELECT COUNT(*) FROM exam_memo $where ";

$where에 들어가는 조건에 따라 쿼리문이 달라진다


정리해보면
$where = ""; //기본 where절
if ($search_name) { //이름에서 검색
$where .="WHERE name LIKE '%a%' ";
}
if ($search_memo) { //메모에서 검색
$where .="OR memo LIKE '%a%' ";
}
먼저 $search_name의 값만 있는 경우 결과는
WHERE name LIKE '%a%' 가 될것이다

그리고 $search_name과 $search_memo 가 모두 값을 가지고 있을 때는
WHERE name LIKE '%a%' OR memo LIKE '%a%' 가 될것이다

그런데 문제가 있다.
name에는 값이 없고, memo에만 값이 있는경우는 쿼리문법이 틀리다는 것을 알 수 있다
OR 대신에 WHERE를 넣어주어야 하는데
일단 OR 대신에 $or_where 변수를 넣어주도록 하자

$where = ""; //기본 where절
if ($search_name) { //이름에서 검색
$where .="WHERE name LIKE '%$search_word%' ";
$or_where="OR";
}
else {$or_where="WHERE";}
if ($search_memo) { //메모에서 검색
$where .="$or_where  memo LIKE '%$search_word%' ";
}



검색어강조하기
문자열을 치환하는 함수를 이용하여 (str_replace) 검색어를 강조항보자

if ($search_word) { //검색어 강조
$data[memo] = str_replace ( "$search_word", "<font color=red><b>$search_word</b></font>", $data[memo]);
$data[name] = str_replace ( "$search_word", "<font color=red><b>$search_word</b></font>", $data[name]);

6. 가상글번호붙이기

글이 16개 있는데 중간에 15번글을 삭제하면 그 번호가 비게 된다
이때 빠지는 글이 없도록 번호를 붙여줘야 하는데,

먼저 글 번호를 붙여주기 위해 글의 총 개수($total)을 이용한다.
총개수가 15개라면 첫번째 페이지의 글은15부터 감소하게 되는 것이다.

그리고 두번째 페이지의 글은 첫번째 페이지에서 페이지 당 글의 수($page)만큼의 번호를 사용하였기 때문에, 글의 총 개수($total)에서 페이지 당 글의 수($page)를 빼준 수부터 글 번호가 감소하게 된다.

결국
$number = $total - ($pagenum*$page); //현재 페이지의 시작 글번호
이 된다

예를들어
$total=15, $page=5일 경우, $pagenum은 첫번째 페이지가 0이므로
$total이 그대로 $number가 된다. 즉 글번호는 $total, 즉 15부터 감소해 나가는 것이다.

두번째페이지에서는 $pagenum이 1이므로 $page와의 곲은 5가 된다.
$total-5=10이므로 두번째 페이지는 10번부터 시작한다.

같은방법으로 세번째페이지를 계산하면 15-10=5, 글번호는 5번부터 시작한다


list.php소스에서 while문의 바로 앞에 위 소스를 추가해보자

$number = $total - ($pagenum * $page); //현재 페이지의 시작 글번호
while ($data=mysql_fetch_array($result)) { //글꺼내기
 $data[name]=stripslashes($data[name]); //이름의 \제거
 $data[memo]=stripslashes($data[memo]); //내용의 \제거
 $data[memo]=nl2br ($data[memo]); //띄어쓰기
 $data[time]=date('y-m-d', $data[time]); //시간포맷변환

 echo "
  <tr>
  <td>$number</td><td> $data[name]</td><td> $data[memo]</td><td> $data[time]</td></tr>";
$number--; //글번호 감소
}
mysql_close($connect);
?>
</table>


7. del.php(삭제)
아래 것을 리스트 소스에 덧붙여 주자 그래야 삭제 버튼이 생긴다
<a href='del.php?no=$data[no]'>삭제 </a>

del.php
<form method=post action =del_ing.php>
<input type=hidden name=no value=<?=no?>>
비밀번호 <input type=password size=10 name=pass>
<input type=submit value='삭제'>
</form>

del_ing.php
<?
include "connecct.php"; //mysql접속
include "lib.php"; //함수라이브러리
$query= "SELECT * FROM exam_memo WHERE no=$no"; //no컬럼의 값이 no인 글을 가져오라
$data=mysql_fetch_array ( mysql_query ($query, $connect)); //가져온 글을 연관배열에 저장해라

$pass = crypt ($pass,12) //비밀번호암호화
if ($pass==$data[pass]) {
mysql_query ("DELETE FROM exam_memo WHERE no=$no", $connect);
}
else {
error ("비밀번호가 정확하지 않습니다");
}

mysql_close ($connect);
move_page ("list.php");
?>


8. edit.php (수정)

list.php에 삭제에서와 같은 방법으로 수정버튼을 만들어준다
<a href='edit.php?no=$data[no]'>수정 </a>

edit.php
<?
include "connecct.php"; //mysql접속
include "lib.php"; //함수라이브러리
$query= "SELECT * FROM exam_memo WHERE no=$no"; //no컬럼의 값이 no인 글을 가져오라
$data=mysql_fetch_array ( mysql_query ($query, $connect)); //가져온 글을 연관배열에 저장해라

$data[name]= stripslashes ($data[name]); //이름의 \제거
$data[memo]= stripslashes ($data[memo]); //내용의 \제거
mysql_close ($connect);
?>


<form method=post action=Write_ing.php autocomplete=off>
<input type=hidden name=no value=<?=$no?> >
이름 <input type=text size=10 name=name>
비번 <input type=password size=10 name=pass> <br>
<textarea cols=30 rows=3 name=memo><?=$data[memo]?></textarea></br>
<input type=submit value='글수정'>
</form>




edit_ini.php
<?
include "connecct.php"; //mysql접속
include "lib.php"; //함수라이브러리
$query= "SELECT * FROM exam_memo WHERE no=$no"; //글정보꺼내기-no컬럼의 값이 no인 글을 가져오라
$data=mysql_fetch_array ( mysql_query ($query, $connect)); //가져온 글을 연관배열에 저장해라

$pass = crypt ($pass,12) //비밀번호암호화
if ($pass==$data[pass]) { //글수정

$name=addslashes ($name); //이름의 특수문자에 \를붙임
$memo=addslashes ($memo); //내용의 특숨ㄴ자에 \를붙임
mysql_query ("UPDATE exam_memo SET name='$name', memo='$memo' WHERE no=$no", $connect);
}
else {
error ("비밀번호가 정확하지 않습니다");
}

mysql_close ($connect);
move_page ("list.php");
?>

install.php
<?
include "connect.php"; //mysql접속

$query ="CREATE TABLE exam_memo(
no int unsigned auto_increment primary key,
name char(20) not null,
memo text not null,
pass char(20) not null,
time int unsigned
)";
mysql_query($query, $connect); //테이블생성
?>


페이지설계
connect.php -mysql에 접속, include하여 사용
install.php -exam_memo 테이블을 생성, 최초 설치시에만 실행
write.php -글 입력폼, 폼을 write_ing.php로 전송
write_ing.php - 입력된 글을 exam_memo테이블에 저장, 저장 후 list.php로 이동
list.php -입력된 글 리스트
del.php -선택된 글을 삭제하기 위해 비번을 입력받는 폼, 폼을 del_ing.php로 전송
del_ing.php - 선택된 글을 exam_memo테이블에서 삭제, 삭제후 리스트로 이동
edit.php - 선택된 글을 수정하기 위한 수정 폼, 폼을 edit_ing.php로 전송
edit_ing.php - 선택된 글을 수정, 수정 후 list.php로 이동
lib.php - 메모장 프로그램에 사용된 함수 라이브러리



lib.php 함수라이브러리
<?
//페이지 이동함수
function move_page ($url){
 echo "<meta http-equiv='refresh' content='0; url=$url'>";
}

//에러메시지출력함수
function error ($memo){
 echo "
  <script language=javascript>
  alert('$memo');
 history.go(-1);
 </script>
  ";
 exit;
}
?>



write.php
<form method=post action=write_ing.php autocomplete=off>//autocomplete은 자동완성기능
이름 <input type=text size=10 name=name>
비번 <input type=password size=10 name=pass><br>
<textarea cols=30 rows=3 name=memo></textarea>
<input type=submit value='글쓰기'>
</form>




write_ing.php 글의저장
글쓰기 폼에서 전송을 누르면 write_ing.php로 각 변수가 전송되는데
post방식으로 전송되었기 때문에 $name, $pass, $memo과 같은 일반적인 변수가 아닌
$HTTP_POST_VARS[name], $HTTP_POST_VARS[pass], $HTTP_POST_VARS[memo]과 같은 환경변수를 사용하는것이 정석이긴 하지만, 여기서는 일반변수로 사용한다고 해서 문제될 것이 없으므로
그냥 $name, $pass, $memo로 사용하도록 하겠다

<?
include "connect.php"; //mysql에 접속
include "lib.php"; //함수라이브러리

if (!$name){error ('이름을 입력하삼');} //이름체크
if(!$pass){error ('비번을 입력하삼');} //비번체크
if (!$memo){error ('내용을입력하삼');}//내용체크

$pass=crypt ($pass,12); //비번암호화
$time=time(); //현재시간저장
$name=addslashes($name); //이름의 특수문자에 \를 붙임
$memo=addslashes($memo); //내용의 특수문자에 \를 붙임

$query="INSERT INTO exam_memo (name, memo, pass, time) VALUES ('$name', '$memo', ''$pass', '$time')";
mysql_query($query); //글저장

mysql_close($connect); //mySQL접속끊기
move_page ("list.php"); //list.php로 이동
?>




list.php
<table width=450 border=1>
<?
include "connect.php"; // mySQL에 접속
$query="SELECT * FROM exam_memo ORDER BY no DESC";
$result =mysql_query($query, $connect);
while ($data=mysql_fetch_array($result)) {
 $data[name]=stripslashes($data[name]); //이름의 \제거
 $data[memo]=stripslashes($data[memo]); //내용의 \제거
 $data[memo]=nl2br ($data[memo]); //띄어쓰기
 $data[time]=date('y-m-d', $data[time]); //시간포맷변환

 echo "
  <tr>
  <td>$data[no]</td><td> $data[name]</td><td> $data[memo]</td><td> $data[time]</td></tr>";
}
mysql_close($connect);
?>
</table>




페이지이동로직
SELECT * FROM exam_memo ORDER BY no DESC LIMIT 0, 5 //첫번째페이지
SELECT * FROM exam_memo ORDER BY no DESC LIMIT 5, 5 //두번째페이지
SELECT * FROM exam_memo ORDER BY no DESC LIMIT 10, 5 //세번째페이지


$pagenum=1; //두번째 페이지로 설정
$page=5; // 페이지 당 게시물 개수
$total=16; //전체 게시물 수
$pagesu=총 페이지 수

$pagesu=ceil($total/$page); //올림하는 함수



LIMIT ($page*$pagenum), $page
LIMIT절에서의 시작위치는 페이지당 게시물 수에 $pagenum을 곱한 수가 되고,가져올 개수는 페이지 당 게시물 개수이다.

($page * $pagenum)을 $start라는 변수에 저장하자

$pagenum=1; //두번째 페이지로 설정
$page=5; // 페이지 당 게시물 개수
$total=16; //전체 게시물 수
$pagesu=ceil($total/$page); //올림하는 함수
$start=$page*$pagenum //시작위치

첫번째 페이지는 $pagenum=0 이다 0*5=0 그러므로 $start=0 결국 LIMIT 0, 5가 된다
두번째 페이지는 $pagenum=1 이다 1*5=5 그러므로 $start=5 결국 LIMIT 5, 5가 된다


일단 게시물의 전체갯수를 구하기 위하여 아래소스를 보자
$query="SELECT COUNT(*) FROM exam_memo "; //개수 세기 쿼리문
$result =mysql_query($query, $connect); //쿼리문입력
$total = mysql_result($result, 0, 0)//총개수저장

mysql_result 대신에 mysql_fetch_array 를 사용하는 방법도 있는데,
$query="SELECT COUNT(*) FROM exam_memo "; //개수 세기 쿼리문
$result = mysql_fetch_array (mysql_query($query, $connect)); //쿼리문입력
$total = $result["COUNT(*)"]; //총개수 저장

여기서 $result["COUNT(*)"] 대신에 $result[0]을 넣어주어도 같은 결과를 얻을 수 있다.

이제 $total 의 값을 구했으니 $total=16 부분은 삭제한다

$total=mysql_result ($result, 0,0);//총개수 저장
$pagenum=1; //두번째 페이지로 설정
$page=5; // 페이지 당 게시물 개수
$pagesu=ceil($total/$page); //올림하는 함수
$start=$page*$pagenum //시작위치




정리하면
<table width=450 border=1>
<?
include "connect.php"; // mySQL에 접속

$query="SELECT COUNT(*) FROM exam_memo"; //개수 세기 쿼리문
$result =mysql_query($query, $connect); //쿼리문입력
$total = mysql_result($result, 0, 0);//총개수저장

$pagenum=1; //두번째 페이지로 설정
$page=5; // 페이지 당 게시물 개수
$pagesu=ceil($total/$page); //올림하는 함수
$start=$page*$pagenum ;//시작위치

$query="SELECT * FROM exam_memo ORDER BY no DESC LIMIT $start, $page";
$result =mysql_query($query, $connect); //쿼리문입력-글꺼내기
while ($data=mysql_fetch_array($result)) { //글꺼내기
 $data[name]=stripslashes($data[name]); //이름의 \제거
 $data[memo]=stripslashes($data[memo]); //내용의 \제거
 $data[memo]=nl2br ($data[memo]); //띄어쓰기
 $data[time]=date('y-m-d', $data[time]); //시간포맷변환

 echo "
  <tr>
  <td>$data[no]</td><td> $data[name]</td><td> $data[memo]</td><td> $data[time]</td></tr>";
}
mysql_close($connect);
?>
</table>



페이지그룹만들기
[1] [2] [3] [4] [5] [▶▶]

페이지그룹 1 ->pagenum의 값:0,1,2,3,4
페이지그룹 2 ->pagenum의 값:5,6,7,8,9

pagegroup=5; //페이지 그룹 당 페이지 수


현재의 페이지그룹을 구하는 식은
$pagegroupnum = ceil (($pagenum+1) / $pagegroup); //현재의 페이지 그룹

왜 이런식이 나왔는지 차근차근  대입해 보면?
$pagenum=0 일때 -> ceil( (0+1)/5 )=1 따라서 $pagegroupnum은 1이 된다
$pagenum=5 일때 -> ceil( (5+1)/5 )=2 따라서 $pagegroupnum은 2가 된다


페이지그룹의 첫페이지 구하는 식은
$pagestart = ($pagegroupnum - 1) * $pagegroup + 1 //페이지그룹의 첫 페이지

첫번째페이지그룹(1)이라면 (1-1)*5+1=1 , 즉 첫번째페이지그룹의 첫페이지는 1페이지이고
두번째페이지그룹(2)이라면 (2-1)*5+1=6 , 즉 두번째페이지그룹의 첫페이지는 6페이지이다.


첫번째페이지를 구하였으니 페이지그룹의 마지막페이지를 구하는식은?
$pageend=$pagestart + $pagegroup;  //페이지 그룹의 마지막페이지

그런데 이렇게 해주면 첫번째 페이지 그룹의 시작페이지는 1이고, 페이지그룹 당 페이지수인 5를 더해주면
6이 되므로 -1을 해주어 5가 되도록 맞춰주도록 하자
$pageend=$pagestart + $pagegroup - 1;  //페이지 그룹의 마지막페이지


현재의 페이지 그룹을 결정하고 그 페이지 그룹의 첫 페이지와 마지막페이지를 알아내었으니,
for문으로 페이지 이동버튼을 출력해보자




지금까지 정리해 보면
<table width=450 border=1>
<?
include "connect.php"; // mySQL에 접속

$query="SELECT COUNT(*) FROM exam_memo"; //개수 세기 쿼리문
$result =mysql_query($query, $connect); //쿼리문입력
$total = mysql_result($result, 0, 0);//총개수저장

//$pagenum=1; //두번째 페이지로 설정
$page=5; // 페이지 당 게시물 개수
$pagesu=ceil($total/$page); //올림하는 함수
$start=$page*$pagenum ;//시작위치

$query="SELECT * FROM exam_memo ORDER BY no DESC LIMIT $start, $page";
$result =mysql_query($query, $connect); //쿼리문입력-글꺼내기
while ($data=mysql_fetch_array($result)) { //글꺼내기
 $data[name]=stripslashes($data[name]); //이름의 \제거
 $data[memo]=stripslashes($data[memo]); //내용의 \제거
 $data[memo]=nl2br ($data[memo]); //띄어쓰기
 $data[time]=date('y-m-d', $data[time]); //시간포맷변환

 echo "
  <tr>
  <td>$data[no]</td><td> $data[name]</td><td> $data[memo]</td><td> $data[time]</td></tr>";
}
mysql_close($connect);
?>
</table>


<?//페이지처리
$pagegroup = 5; //페이지그룹당 페이지수
$pageend = $pagestart + $pagegroup; //페이지그룹의 마지막페이지
$pagegroupnum= ceil(($pagenum+1)/$pagegroup); //현재의 페이지그룹
$pagestart = ($pagegroupnum-1) * $pagegroup +1; //페이지그룹의 첫 페이지
$pageend = $pagestart + $pagegroup -1 ; //페이지그룹의 마지막페이지

for ($i=$pagestart; $i <= $pageend; $i++) { //페이지 이동버튼 출력->1~5까지 루프가 돈다
 if ($i > $pagesu) {break;} //페이지체크-실제페이지수보다 많으면 중단
 echo "[$i]";
}
?>


이제 링크를 걸어 실제 페이지가 이동하도록 해보자
링크할 페이지는 자기자신, 즉 $PHP_SELF를 사용하고 GET방식으로 pagenum값을 넘겨주어야한다

<a href='$PHP_SELF?pagenum=$i'>
근데만약 위처럼 $i를 그대로 pagenum에 넣어주면 엉뚱한 펭지로 이동하게 될것이다
이것은 첫번째페이지일때 $pagenum=0이고
두번째페이지일때 $pagenum=1 인 것과 같이 $pagenum이 실제페이지보다 1만큼 작기때문이다
따라서 $i-1의 값을 넣어주어야 한다.


다음페이지 그룹으로 이동하기위해 [▶▶]
이전페이지 그룹으로 이동하기위해 [◀◀] 를 사용해보자

현재 페이지그룹이 2라면 다음페이지 그룹은 3이고, 이전페이지그룹은 1이 된다
따라서
$nextgroup = $pagegroupnum +1; //다음그룹
$prevgroup = $pagegroupnum -1; //이전그룹

이제 링크를 걸어주기위해 각각의 페이지 그룹에 속해 있는 페이지들의 첫 페이지를 구해준다.
$pagestart = ($pagegroupnum -1) * pagegroup +1; //페이지그룹의 첫페이지

$nextstart = ($nextgroup -1) * $pagegroup + 1; //다음 페이지 그룹의 첫 페이지
$prevstart = ($prevgroup -1) * $pagegroup +1; //이전 페이지 그룹의 첫 페이지

그런데 여기서는 몇번째 페이지인가를  생각하는 것이 아니라, 실제로 $pagenum으로 전달해 줄 값을 결정하는 것이므로
마지막의 +1은 하지 않도록 한다.
$nextstart = ($nextgroup -1) * $pagegroup ; //다음 페이지 그룹의 첫 페이지
$prevstart = ($prevgroup -1) * $pagegroup ; //이전 페이지 그룹의 첫 페이지

이제, 위의 $nextstart 와 $prevstart가 pagenum의 값으로 전달되도록 링크를 걸어주면된다
[<a href='$PHP_SELF?pagenm=$prevstart'>◀◀</a>]
[<a href='$PHP_SELF?pagenm=$nextstart'>▶▶</a>]

그런데 첫번째 페이지 그룹이라면 이전페이지가 존재하지 않기때문에, 첫번째 페이지 그룹이 아닐 경우에만 이전 페이지 그룹으로 이동하도록 if문을 하나 넣어준다
if ($pagegroupnum != 1) { //이전 페이지 그룹으로 이동
echo " [<a href='$PHP_SELF?pagenm=$prevstart'>◀◀</a>]";

다음페이지그룹으로의 이동에서도 마찬가지로 현재의 페이지 그룹이 마지막페이지그룹이라면
다음페이지그룹으로 이동할 필요는 없을 것이다.

따라서 다음페이지 그룹이 실제 존재하는지 알아보려면
전체 페이지 수($pagesu)가 다음페이지 그룹의 첫 번째 페이지($nextstart)+1 보다 큰지 알아보는 것이다.

전체 페이지 수가 크다면 아직 출력할 페이지들이 남아있는 것이 되므로
다음페이지 그룹은 실제로 존재하고 있다는 얘기가 된다

그리고 여기서 다음페이지 그룹의 첫페이지($nextstart)에 +1을 해준 이유는 우리가 구한 $nextstart는 $pageum의 값,
즉 첫번째 페이지가 1이 아닌 0을 갖기 때문이다.

결국 첫번째 페이지가 1이라는 값을 갖는 전체페이지 수와 값을 비교하기 위해 $nextstart에는 1을 더해줘야 한다

if($pagesu > ($nextstart +1) { //다음페이지그룹으로이동
echo " [<a href='$PHP_SELF?pagenum=$nextstart'>▶▶</a>]";
}
위 if문에서는 다음 페이지 그룹의 첫번째페이지($nextstart)가 전체 페이지 수보다 작은지를 검사하고,
만약 작다면 다음페이지 그룹이 존재하는 것으로 판단하여 이동버튼을 출력하도록 해준 것이다.


정리해보면
이전페이지그룹이동버튼
$prevgroup = $pagegroupnum -1; //이전그룹
$prevstart = ($prevgroup -1) * $pagegroup +1; //이전 페이지 그룹의 첫 페이지
if ($pagegroupnum != 1) { //이전 페이지 그룹으로 이동
echo " [<a href='$PHP_SELF?pagenm=$prevstart'>◀◀</a>]";
}

다음페이지그룹 이동버튼
$nextgroup = $pagegroupnum +1; //다음그룹
$nextstart = ($nextgroup -1) * $pagegroup ; //다음 페이지 그룹의 첫 페이지
if($pagesu > ($nextstart +1)) { //다음페이지그룹으로이동
echo " [<a href='$PHP_SELF?pagenum=$nextstart'>▶▶</a>]";
}


지금까지 한걸 정리해보면
list.php

<table width=450 border=1>
<?
include "connect.php"; // mySQL에 접속

$query="SELECT COUNT(*) FROM exam_memo"; //개수 세기 쿼리문
$result =mysql_query($query, $connect); //쿼리문입력
$total = mysql_result($result, 0, 0);//총개수저장

//$pagenum=1; //두번째 페이지로 설정
$page=5; // 페이지 당 게시물 개수
$pagesu=ceil($total/$page); //올림하는 함수
$start=$page*$pagenum ;//시작위치

$query="SELECT * FROM exam_memo ORDER BY no DESC LIMIT $start, $page";
$result =mysql_query($query, $connect); //쿼리문입력-글꺼내기
while ($data=mysql_fetch_array($result)) { //글꺼내기
 $data[name]=stripslashes($data[name]); //이름의 \제거
 $data[memo]=stripslashes($data[memo]); //내용의 \제거
 $data[memo]=nl2br ($data[memo]); //띄어쓰기
 $data[time]=date('y-m-d', $data[time]); //시간포맷변환

 echo "
  <tr>
  <td>$data[no]</td><td> $data[name]</td><td> $data[memo]</td><td> $data[time]</td></tr>";
}
mysql_close($connect);
?>
</table>


<?//페이지처리
$pagegroup = 5; //페이지그룹당 페이지수
$pageend = $pagestart + $pagegroup; //페이지그룹의 마지막페이지
$pagegroupnum= ceil(($pagenum+1)/$pagegroup); //현재의 페이지그룹
$pagestart = ($pagegroupnum-1) * $pagegroup +1; //페이지그룹의 첫 페이지
$pageend = $pagestart + $pagegroup -1 ; //페이지그룹의 마지막페이지

$prevgroup = $pagegroupnum -1; //이전그룹
$prevstart = ($prevgroup -1) * $pagegroup +1; //이전 페이지 그룹의 첫 페이지
if ($pagegroupnum != 1) { //이전 페이지 그룹으로 이동
echo " [<a href='$PHP_SELF?pagenm=$prevstart'>◀◀</a>]";
}


for ($i=$pagestart; $i <= $pageend; $i++) { //페이지 이동버튼 출력->1~5까지 루프가 돈다
 if ($i > $pagesu) {break;} //페이지체크-실제페이지수보다 많으면 중단
 echo "[$i]";
}


$nextgroup = $pagegroupnum +1; //다음그룹
$nextstart = ($nextgroup -1) * $pagegroup ; //다음 페이지 그룹의 첫 페이지
if($pagesu > ($nextstart +1)) { //다음페이지그룹으로이동
echo " [<a href='$PHP_SELF?pagenum=$nextstart'>▶▶</a>]";
}

?>

















로직
방문->총방문자수구하기->총방문자수+1 하고 저장 -> 방문자수출력

install.php
<?
include "connect.php"; //mysql접속

$query = "CREATE TABLE counter (
today int UNSIGNED,
total int UNSIGNED,
time int UNSIGNED
);";

$result=mysql_query($query, $connect); //쿼리문입력-테이블생성
mysql_close($connect); //접속해제
if ($result) {echo "설치성공";}
?>


INSERT INTO counter (today, total, time) VALUES (0,0,0);
->각 값을 0으로 초기화 해준다


<?
include "connect.php"; //mysql접속

$query = "SELECT * FROM counter LIMIT 1"; //쿼리문
//카운터테이블에서 1개의 모든 레코드의 모든 컬럼을 가져오라

$data=mysql_fetch_array(mysql_query($query, $connect)); //쿼리문실행-연관배열에 저장

$now = date(Ymd); //오늘날짜
$last = date(Ymd, $data[time]); //마지막방문날짜
if ($now == $last) {$data[today]++;} //오늘방문자수 구하기
else {$data[today]=1;}
$time = time(); //현재의 유닉스타임스탬프

$data[total]++; //총방문자 수 구하기

$query="UPDATE counter SET today=$data[today], total=$data[total], time=$time";
mysql_query ($query, $connect); //새로운 쿼리값 입력
echo "오늘:$data[today] 전체:$data[total]"; //출력

?>





위의 소스는 새로고침하면 계속 카운팅이 하므로 뭔가 제한을 걸어 줄 필요가 있다
쿠키를 이용해 만들어 보자

<?
setcookie("counter_cookie", "^_^", 0, "/"); //쿠키굽기

include "connect.php"; //mysql접속

$query = "SELECT * FROM counter LIMIT 1"; //쿼리문
//카운터테이블에서 1개의 모든 레코드의 모든 컬럼을 가져오라

$data=mysql_fetch_array(mysql_query($query, $connect)); //쿼리문실행-연관배열에 저장

$now = date(Ymd); //오늘날짜
$last = date(Ymd, $data[time]); //마지막방문날짜

if (!$HTTP_COOKIE_VARS[counter_cookie]) { //새로운 방문자일 경우
if ($now == $last) {$data[today]++;} //오늘방문자수 구하기
else {$data[today]=1;}
}
else { //새로운 방문자가 아닐경우
if ($now != $last) {$data[today]=0;}
}

$time = time(); //현재의 유닉스타임스탬프
if (!$HTTP_COOKIE_VARS[counter_cookie]) { //새로운방문자일 경우
$data[total]++; //총방문자 수 구하기
}

$query="UPDATE counter SET today=$data[today], total=$data[total], time=$time";
mysql_query ($query, $connect); //새로운 쿼리값 입력
echo "오늘:$data[today] 전체:$data[total]"; //출력

?>

1. COUNT
-가져온 레코드의 개수를 세어주는 함수

SELECT COUNT (*) 테이블이름

<?
include "connect.php"; //mysql접속

$query="SELECT COUNT(*) FROM student;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력

$count = mysql_result($result, 0, 0); //꺼내온 값의 저장

echo $count;
?>
결과는 3


저장될변수=mysql_result (쿼리결과, 열, 행);

 no name  year 
 (0,0) 0,1  0,2 
 1,0  1,1 1,2 


우리가 넣어준 sql쿼리문의 결과는 위와 같이 여러 개의 열과 행으로 나누어진 형태의 2차원 배열이 아니라,
단순한 레코드의 개수이기에 하나의 열과 행으로 이루어진 값이 될것이다. 그렇기에
mysql_result함수에는 0,0을 넣어 첫번째 열의 첫번째 행에 해당하는 값임을 알려주는 것이다.

만약 mysql_fetch_array함수를 사용하고자 한다면
<?
include "connect.php"; //mysql접속

$query="SELECT COUNT(*) FROM student;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력

$data = mysql_fetch_array ($result); //연관배열만들기
echo $data["COUNT(*)"];
?>

mysql_fetch_array함수 사용은 하나의 레코드를가져올때 사용했던 방법과 동일하지만
저장된 연관 배열의 원소를 나타낼때의 방법은 조금 다르다
$배열이름["함수(매개변수)"]
위와 같은 형식은 count함수가 아닌 다른 함수에서도 같은 방법으로 사용된다




2. SUM
-지정된 컬럼에 입력된 값들의 합계를 구함

SELECT SUM(컬럼이름) FROM 테이블이름

<?
include "connect.php"; //mysql접속

$query="SELECT SUM(no) FROM student;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력

$sum = mysql_result($result, 0, 0); //꺼내온 값의 저장

echo $sum;
?>
결과는 6
-> no컬럼에는 1,2,3의 값이 들어 있으므로 1+2+3이 되어 6이 되는 것이다.




3. MAX, MIN
-최대값과 최소값을 구하는 함수

SELECT MAX(컬럼이름) FROM 테이블이름
SELECT MIN(컬럼이름) FROM 테이블이름


<?
include "connect.php"; //mysql접속

$query="SELECT MAX(no) FROM student;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력

$max = mysql_result($result, 0, 0); //꺼내온 값의 저장

echo $max;
?>
결과는 3
->student 테이블의 no컬럼에서 가장큰 값은 3




4. AVG
-평균을 구하는 함수

SELECT AVG(컬럼이름) FROM 테이블이름

예>
SELECT AVG(no) FROM student

결과는 2
->1,2,3의 평균




5. ROUND
-반올림을 해주는 함수

SELECT ROUND(컬럼이름, 자릿수) FROM 테이블이름

자릿수를 입력하지 않거나 0으로 해준다면 소수첫째자리에서 반올림하여 정수형태가 된다
자릿수를 1로 해준다면 소수둘째자리에서 반올림하여 소수첫째자리까지만 표시한다.

SELECT ROUND(no,1) FROM student WHERE no=1
-> student테이블에서 no가 1인 레코드의 no값을 반올림하여 소수 둘째 자리에서 반올림하여
소수 첫째자리까지만 표시 하라는 것


SELECT ROUND(AVG(no)) FROM student WHERE no=1
->위와 같이 중복사용도 가능하다

<?
include "connect.php"; //mysql접속

$query="SELECT ROUND(AVG(no)) FROM student ;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력

$avg = mysql_result($result, 0, 0); //꺼내온 값의 저장

echo $avg;
?>




6. 기타함수

UNIX_TIMESTAMP() -현재의 유닉스타임스탬프를 리턴
HEX(n) - 10진수를 16진수로 변환
OCT(n) - 10진수를 8진수로 변환
BIN(n) - 10진수를 2진수로 변환
CONV(n, 진수1, 진수2) - n을 진수1에서 진수2로 변환
ASCII(문자열) - 문자열의 첫분자의 ASCII코드로 변환
LOWER(문자열) - 문자열을 소문자로 변환
UPPER(문자열) - 문자열을 대문자로 변환
REVERSE(문자열) - 문장ㄹ의 순서를 바꿈
INSERT (문자열1, 위치, 크기, 문자열2) - 문자열1의 지정된 위치에 지정된 크기만큼 문장열2를 추가
LTRIM(문자열) - 문자열의 왼쪽 공백을 제거
RTRIM(문자열) - 해당 문자열의 오른쪽 공백을 제거
CONCAT(문자열,문자열...) -해당문자열을 연결
LEFT(문자열,크기) -문자열에서 지정된 크기만큼 왼쪽부터 리턴
RIGHT(문자열,크기) -문자열에서 지정된 크기만큼 오른쪽부터 리턴
LOCATE(문자열1, 문자열2) -문자열2에서 문자열1의 위치를 리턴
LPAD(문자열1, 길이, 문자열2) -문자열1의 왼쪽에 문자열2를 길이 만큼 추가
RPAD(문자열1, 길이, 문자열2)- 문자열1의 오른쪽에 문자열2를 길이만큼 추가
USER() - 현재 mysql에 접속중인 사용자의 이름을 리턴
VERSION() -mysql의 버전을 리턴
PASSWORD(문자열) - 문자열을 암호화하여 리턴

SELECT
-테이블에 입력된 레코드를 가져오는 구문

SELECT 컬럼이름 FROM 테이블이름 WHERE 조건

SELECT no,name FROM student WHERE no=2
결과는
 
no name
      2 한 혁


테이블의 모든 컬럼의 값을 가져오게 하려 한다면, 가져올 컬럼이름대신에 *을 사용해주면 된다.
SELECT * FROM student WHERE no =2;
->no가 2인 레코드의 모든 컬럼에 해당하는 값을 가져온다

SELECT * FROM student WHERE no >=2;
->no가 2보다 크거나 같은 레코드를 모두 가져와라




PHP에서 SELECT 활용
connect.php
<?
$connect=mysql_connect("localhost", "asdf", "1234"); //mySQL에 접속
$mysql = mysql_select_db ("asdf_db", $connect); //db선택
?>

index.php
<?
include "connect.php"; //mysql접속

$query="SELECT * FROM student WHERE no >= 2;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력

while ($data = mysql_fetch_array ($result)) { //연관배열의 형태로 데이터를 변환
//여기서 $data의 연관배열은 $data[컬럼이름]의 형태
//예로, no컬럼의 값은 $data[no]에 저장된다
 echo "$data[no] $data[name] $data[year] <br>";

}
?>

위의 예제를 테이블과 같은 형태로 출력하고 싶다면 아래와 같이 수정하자
<table border=1>
<?
include "connect.php"; //mysql접속

$query="SELECT * FROM student WHERE no >= 2;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력

while ($data = mysql_fetch_array ($result)) { //연관배열의 형태로 데이터를 변환
//여기서 $data의 연관배열은 $data[컬럼이름]의 형태
//예로, no컬럼의 값은 $data[no]에 저장된다
 echo "<tr><td>$data[no]</td><td>$data[name]</td><td>$data[year]</td></tr> <br>";

}
?>
</table>


만약 가져올 레코드의 개수가 하나라면 while문을 사용해줄 필요가 없다
연관배열에 가져온 레코드 중 첫번째 레코드의 내용이 저장되기 때문이다
<?
include "connect.php"; //mysql접속

$query="SELECT * FROM student WHERE no = 1;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력

$data = mysql_fetch_array ($result));  //연관배열의 형태로 데이터를 변환
 echo "$data[no] $data[name] $data[year] ";

}
?>



ORDER BY
-꺼내온 레코드들을 정렬해 주는 역할

SELECT * FROM 테이블이름 WHERE 조건 ORDER BY 컬럼이름 ASC

ASC:오름차순 (생략가능)
DESC:내림차순

<table border=1>
<?
include "connect.php"; //mysql접속

$query="SELECT * FROM student ORDER BY year DESC;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력

while ($data = mysql_fetch_array ($result)) { //연관배열의 형태로 데이터를 변환
//여기서 $data의 연관배열은 $data[컬럼이름]의 형태
//예로, no컬럼의 값은 $data[no]에 저장된다
 echo "<tr><td>$data[no]</td><td>$data[name]</td><td>$data[year]</td></tr> <br>";

}
?>
</table>

두개 이상의 컬럼에 대해 순차적으로 ORDER BY를 적용하려면 ,로 컬럼이름을 연결하여 사용하면 된다
SELECT * FROM student ORDER BY year DESC, no DESC




LIMIT
-가져오는 레코드의 개수를 제한하는 구문

SELECT * FROM 테이블이름 WHERE 조건 ORDER BY 컬럼이름 LIMIT 갯수


SELECT * FROM 테이블이름 LIMIT 위치,갯수
-> 여기서 위치는 가져올 레코드의 가장 첫번째 레코드가 0이 되며, 가장 첫레코드부터 2개의 레코드를 가져오고자 한다면
LIMIT 0,2를 넣어주면 된다. 이는 LIMIT 2와 같다

하지만 LIMIT 1,2 라고 한다면
두번째 레코드부터 2개의 레코드를 가져오기 때문에 첫번째 레코드는 무시하고 no가 2,3인 레코드만을 가져온다

게시판에 유용하게 쓰일 수 있는데
총 20개의 글이 있을때, 한 페이지당 10개의 글 목록을 보여주려면
첫 페이지는 LIMIT 0,10
2페이지에는 LIMIT 10,10 으로 하면된다




DISTINCT
-가져올 레코드의 값들이 중복될때 그 중 하나만을 가져오는 역할

SELECT DISTINCT 컬럼이름 FROM 테이블이름

예로
student 의 year라는 컬럼에 1996, 1996, 1997 이라는 레코드가 저장되어 있는데
이 컬럼에 입력된 값에는 어떤 것들이 있는지 알고 싶을 때 사용한다
물론 그 결과는 1996과 1997이 된다
즉 중복되는 값은 무시하고 다른 어떤 값이 있는지를 계속해서 찾게된다

DISTINCT는 컬럼이름 대신 *를 사용할 수 없고
여러개의 컬럼을 동시에 가져올 수 없다
물론 WHERE , ORDER BY 는 사용이 가능하다

<table border=1>
<?
include "connect.php"; //mysql접속

$query="SELECT DISTINCT year FROM student ;"; //꺼내오기 쿼리문
$result=mysql_query($query, $connect); //쿼리문입력

while ($data = mysql_fetch_array ($result)) { //연관배열의 형태로 데이터를 변환
//여기서 $data의 연관배열은 $data[컬럼이름]의 형태
//예로, no컬럼의 값은 $data[no]에 저장된다
 echo "<tr><td>$data[year]</td></tr> ";

}
?>
</table>
DISTINCT는 레코드의 수가 많은 테이블에서 어떠한 값들이 저장되어 있는지, 그 값의 종ㄹ에 대해 알고 싶을때 유용하게 쓰이는 구문으로
예로, 메일링리스트와 같은 프로그램에서 같은 이메일 주소가 등록되었을때 중복된 메일 발송을 막기 위해 유용하게 사용될 수 있다.


























+ Recent posts