강좌
클라우드/리눅스에 관한 강좌입니다.
프로그램 분류

망. 웹 게시판 구상하기 - 2

작성자 정보

  • 웹관리자 작성
  • 작성일

컨텐츠 정보

본문

[강좌] php+mysql 게시판 만들기 #망-2

안녕하세요. 디망쉬입니다.

아. 강좌쓰면서 격려의 메일을 받았습니다. 처음입니다.
T_T 그 분은 어떻게 아셨는지 제 e-mail 주소로 격려를 해주셨습니다. 흑흑.

그리고 어떤 분은 메모로도 격려를 해주셨습니다. T^T
이제 강좌 시작인데 격려 해주신 몇 몇 분들께 감사드립니다.
그다지 강좌를 많이 쓰진 않았지만 여지껏 한 6편의 강좌, 혹은 비스므리한 글을 쓰면서 격려받기는 처음인 듯. ^^;
아아.

자 그런 의미에서 힘내서 이얍!

####################################
2000년 6월 29일 이전의 본 글에 오류가 있어
2000년 6월 29일에 급히 강좌 오류를 수정했습니다.
갈무리하신 분은 새로 갈무리하세요. ^^; 죄송~
####################################



icon04.gif 망. 웹 게시판 구상하기

b. 게시판 구조 (DB)
어이쿠. 드디어 꽤나 골치 아픈 부분을 다루게 되는군요. @_@

게시판 구조를 설명하기에 앞서 이전의 강좌에서 다루지 않았던 DB 에 대해 좀 더 자세한 설명을
할 필요가 있는 듯 합니다.

정보처리 기능사나 워드 프로세스 필기 공부하신 분들은 데이터론(?)에서 이런 걸 보셨을 겁니다.

데이터 - 레코드 - 테이블 - 데이터베이스

에. 아닌 듯 하군요. 이거 공부한지가 2년째에 접어드니 기억도 안나내요. ^^; 위의 것은
단지 이론이 아니라 실질적으로 사용되는 개념임다.

게시판의 게시물은 무엇 무엇으로 구성될까요?

제목, 작성자명, 작성자email, 작성자homepage, 게시물 비번, 게시물 내용, 글 번호 정도로 구성될 것입니다.
이러한 것들을 데이터라고 하죠. 예를 들면

글번호 : 1
제목 : 디망쉬는 귀여워 수줍 *^^*
작성자명 : 디망쉬
email : dimanche@creple.com
homepage : http://creple.com
게시물비번 : 1234
게시물 내용 : 아잉. 아잉. *(-- )* *( --)*


이라고 할 경우 각 각의 내용이 데이터입니다.
이런 것들을 한 곳에 모아 관리하는 것을 테이블이라 하고 이 테이블을 모은 개념이 데이터베이스라고
생각하시면 편하실 겁니다.

보통의 경우 게시판 하나는 테이블 하나입니다.

자 그럼 우리가 만들 게시판의 테이블은 어떤 구조를 하면 좋을까요?
게시물에 들어갈 정보는 다 나왔습니다.
이외에 부과적으로 들어가야할 것이 있습니다.
바로 관련글과 파일 업로드 관련입니다.

관련글. 이거 굉장히 골치 아픈 부분입니다.
이것을 어떻게 짜느냐에 따라 게시판 속도가 좀 더 빨라지느냐 느려지느냐가 결정됩니다.
관련글 기능이 없다면 속도도 매우 빠르고 매우 코딩도 단순해집니다.

그리고 파일 업로드 기능을 넣는다면 게시물은 두 가지 정보를 가져야 합니다.
파일의 경로명과 파일명이지요.

그럼 한 번 짜볼까요?

CREATE TABLE testboard (
no int(5) DEFAULT '0' NOT NULL auto_increment,
usrtitle tinytext,
contents text,
hit int(5) DEFAULT '0' NOT NULL,
usrname varchar(12),
usrpasswd char(28),
usremail varchar(80),
usrhomepage varchar(80),
filluptime int(11) DEFAULT '0' NOT NULL,
PRIMARY KEY (no)
)

 

에구. 모르는 말 투성이군요. 아니.

CREATE TABLE testboard {

 

이건 뭔지 아시겠죠? 예이. 테이블 생성을 하라는 거죠. 테이블을 어떻게 생성하느냐.
그건 아래에 주욱 나와있습니다.

일단 맨 앞부분 단어들(?)은 attribute 입니다.
(이전 강좌에서 말했듯이 원래 명칭을 모르므로 걍 스키마라고 했었는데 알아보니 attribute 인 듯
싶내요. ^^; )
이런 attribute 들이 무어냐. 이겁니다.

no = 글번호
usrtitle = 게시물 제목
contents = 게시물 본문 내용
hit = 조회수
usrname = 작성자명
usrpasswd = 게시물 비밀번호
usremail = 작성자 email 주소
usrhomepage = 작성자 홈페이지 주소
filluptime = 글 입력 시각


입니다. ^^; 그리고 이런 각 attribute 의 형태(type)은 숫자형인지 문자형인지 뭐 이런 걸
정해주는 건 뒷 부분입니다.

no int(5) DEFAULT '0' NOT NULL auto_increment,


이건 글 번호로 쓴다는 걸 앞서 밝혔습니다.
절대(absolute) 글 번호죠. 절대 글 번호가 뭔지는 일단 설명 안하겠습니다.
이건 관련글에 대해 설명 할 때 나올 설명인지라.
^^; 아무튼 attribute 뒤 내용을 보니

int(5) DEFAULT '0' NOT NULL auto_increment,


라고 나와있죠. 여기서 int(5) 는 no 를 숫자형으로 선언하며 이것의 길이는 최고 5자리라고 해주는
겁니다. 즉 no 에는 최고 99999 번까지 입력이 되죠. 만약 100000 번이 들어가면 overflow
(넘침)이 일어나죠. (어떤 일이 생기더라. 긁적)

DEFAULT '0' NOT NULL auto_increment,


그리고 여기서 DEFAULT '0' NOT NULL 이란 디폴트 값으로, 즉 아무 값도 안정해졌을 때는
0을 넣으라는 거죠. 아니라면? -_-; 흠.

auto_increment,

이건 자동으로 증가시켜라는 겁니다.
게시물 번호는 글 추가가 일어날 때마다 자동으로 글 번호를 추가시켜줘야겠죠.
글이 어떻게 입력되건간에 어쨌듯 글이 추가된다는 것은 글 번호 추가를 의미합니다.
바로 그런 의미입니다.

usrtitle tinytext,


매우 간단합니다. usrtitle 의 type 이 tinytext 라는 겁니다.
tinytext 는 문자형을 의미하며 최고 256 bytes 까지 저장이 가능하죠.
이와 비슷한 것들이 있습니다.

tinytext : 255 bytes. 방금 배운거.
text : 65535 bytes.
mediumtext : 16777215 bytes.
longtext : 4294967295 bytes.

보통 제목은 tinytext 로 충분히 처리 가능하며, 대부분의 경우 게시물 내용도 text 로 처리가 가능합니다.
참고로 본 강좌도 편당 6~7000 bytes 정도입니다. 여지껏 쓴 거 모두 text 에 저장되죠.
만약 게시판을 강좌나 그런 것으로 쓸 것이 아니라면 용량 낭비 및 속도 낭비 하지 않게 text 하는 것이
훨 낫습니다. ^^;

usrname varchar(12),


varchar(12). ? 뭔가 신기하죠?
문자형 type 에는 char, varchar, 그리고 저 text 패밀리가 있습니다.
이중 text 패밀리는 배웠고 char 와 varchar 를 배워야겠죠?
아니. 차이점만 알면 됩니다.

char 는 고정 타입입니다. char(12) 라고 하면 DB 는 항상 12의 칸을 잡습니다.
내용에 1 bytes 가 들어가건 2 bytes 가 들어가건 항상 12 bytes 로 잡고 있는거죠.

그에 비해 varchar 는 동적인 타입입니다.
varchar(12) 라고 하면 DB 는 최고 12 bytes 로 잡고 들어온 값에 맞게 알아서 잡습니다.
만약 2 bytes 가 들어오면 2 bytes 만 잡습니다.
최고 12 bytes 까지 들어오고요.

각 각의 장단점이 있습니다.
char 는 용량 낭비가 있지만(항상 정해진 값으로 처리하니까) 검색 속도가 varchar 보다 빠릅니다.
varchar 는 반대로 용량 낭비는 없지만 속도가 char 보다 느립니다.

이런 점을 잘 생각해야하죠.
이용자 이름은 항상 6 bytes (한글 3자) 이진 않습니다.
2 bytes 일 수도 있습니다. 즉 더 적은 크기일 수 있다는거죠.
때문에 varchar 를 쓰는게 좋습니다.

그에 비해 비밀 번호는 항상 같은 자리일 것입니다.
비밀 번호를 입력받아지는 그대로 저장한다면야 크기(길이)가 다 다르겠지만 crypt 함수를 사용해
비밀번호 자체를 암호화해버리면 항상 같은 자리가 됩니다.
이것이 Linux 의 경우 13 bytes, FreeBSD 의 경우 28 bytes 입니다. Windows 는 모르겠내요.
Windows 용 PHP 에서 crypt 함수 쓰려하면 꼭 에러가 나서리. 쩝. 그래서

usrpasswd char(28),


라고 잡힌 겁니다. 강좌 0 번에서 밝혔듯이 제 테스트 환경은 FreeBSD 이기 때문에 28 bytes 로,
그것도 char 로 잡은거죠. 뭐 비밀 번호를 검색할 일은 전혀 없으므로 varchar 로 잡으셔도 상관 없습니다.

만약 리눅스에서 본 강좌대로 게시판을 짜시는 분들은

usrpasswd char(28),

대신

usrpasswd char(13),

로 해야합니다.


이걸로 attribute type 선언은 끝났군요.
이제 key 에 대해서 알아보죠.

게시판에서 글 번호는 절대적입니다. 중복될 수 없지요.
또한 게시판 테이블과 관련한 기능의 테이블이 있을 때 각 데이터의 식별해주는 것이 바로 글 번호입니다.
중복되선 안되기 때문이죠.
(관련 기능이란 추천 기능도 있을 수 있겠고 메일링 리스트도 될 수 있겠고 다양하죠)

여기서 게시판의 글 번호는 중복되지 않기 때문에 unique 라고 합니다.

잘 모르겠죠? 걍 그렇구나라며 넘어가세요. ^^;
아무튼 PRIMARY KEY 를 살펴보자면, 게시판의 각 게시물을 unique 하게 식별할 수 있는 속성
이라 할 수 있습니다.
이런 역할을 글 번호인 no 가 하므로 no 를 PRIMARY KEY 로 해줘야 하지요.

참고로 PRIMARY KEY 의 특징으로는

- PRIMARY KEY 는 반드시 unique 하며
- PRIMARY KEY 는 null 을 허용하지 않고
- 테이블에는 하나의 PRIMARY KEY 가 존재

한다는 겁니다. 그러기 때문에!

PRIMARY KEY (no)


를 해준겁니다. :] 필수죠.

filluptime int(11) DEFAULT '0' NOT NULL,

마지막이군요. 이게 뭔지는 위에서 알려드렸듯이
입력시각입니다. 이게 왜 숫자로 11 자리나 차지하게 했을까요?
그건 php 의 time 함수가 숫자형으로 11 bytes 를 사용하기 때문이죠.
이렇게 생성되는 11 자리의 숫자에는 년도, 월, 일, 시간, 분, 초까지 갖고 있습니다.
그래서 11 자리로 한 것입니다.


자 그럼 상당히 골치 아픈 관련글을 위한 attribute 를 추가해보죠. 일단 attribute 를
추가하고 살펴보죠.


1. 첫 번째 타입


CREATE TABLE testboard (
no int(5) DEFAULT '0' NOT NULL auto_increment,
num int(5) DEFAULT '0' NOT NULL, # 여기 추가
idx int(5) DEFAULT '0' NOT NULL, # 여기 추가
usrtitle tinytext,
contents text,
replyon int(1) DEFAULT '0' NOT NULL, # 추가
replyto int(5) DEFAULT '0' NOT NULL, # 추가
replyfrom int(5) DEFAULT '0' NOT NULL, # 추가
replydepth int(5) DEFAULT '0' NOT NULL, # 추가
hit int(5) DEFAULT '0' NOT NULL,
usrname varchar(12),
usrpasswd char(28),
usremail varchar(80),
usrhomepage varchar(80),
filluptime int(11) DEFAULT '0' NOT NULL,
PRIMARY KEY (no)
)

 


2. 두 번째 타입

CREATE TABLE testboard (
no int(5) DEFAULT '0' NOT NULL auto_increment,
num int(5) DEFAULT '0' NOT NULL, # 여기 추가
idx tinytext, # 여기 추가
usrtitle tinytext,
contents text,
replydepth int(5) DEFAULT '0' NOT NULL, # 추가
hit int(5) DEFAULT '0' NOT NULL,
usrname varchar(12),
usrpasswd char(28),
usremail varchar(80),
usrhomepage varchar(80),
filluptime int(11) DEFAULT '0' NOT NULL,
PRIMARY KEY (no)
}



위와 같이 두 종류를 생각해볼 수 있습니다.

첫 번째 타입은 jsboard 에서 빌려온 타입입니다.
(http://jsboard.kldp.org) 이건 상당히 재미있는 구조입니다.
일단 no 는 절대 글 번호이고, num 는 실제 글 번호입니다.
무슨 말인가하면 no 는 앞서 설명했듯이 글 추가되면 무조건 글 번호가 추가됩니다.
일반 글이건 관련 글이건 간에요.
하지만 num 은 관련 글일 경우는 글 번호가 올라가지 않습니다. 아래와 같다고 보죠.

글번호 : 제목
------+-----------------------
3 : 커헉. 진짜다!
2 : 와우. 1번을 드시다니!
1 : 안녕하세요!
- : re: 어서오세요
- : re: re: 감사합니다.
- : re: 반가워요.


라고 되어 있다고 보죠. 그러면 글 번호(no) 는 다음과 같을 겁니다.

 

no : 제목
----+----------------------
1 : 안녕하세요!
2 : re: 반가워요.
3 : re: 어서오세요.
4 : re: re: 감사합니다.
5 : 와우. 1번을 드시다니!
6 : 커헉. 진짜다!

그러나 관련 글에는 글 번호를 출력해서는 안되죠.
그렇게 할 경우

글번호 : 제목
------+-----------------------
6 : 커헉. 진짜다!
5 : 와우. 1번을 드시다니!
1 : 안녕하세요!
3 : re: 어서오세요
4 : re: re: 감사합니다.
2 : re: 반가워요.

으로 출력될 것입니다. 그래서 글을 식별하는 번호는 no 가 담당하고 출력을 담당하는 것은 num 이 합니다.
num 은 일반 글일 때만 숫자가 증가하죠. 관련 글일 때는 0 을 넣어주고요.
그러면 이렇게 되겠죠.

no : num : 제목
----+-----+-----------------
1 : 1 : 안녕하세요!
2 : 0 : re: 반가워요.
3 : 0 : re: 어서오세요.
4 : 0 : re: re: 감사합니다.
5 : 2 : 와우. 1번을 드시다니!
6 : 3 : 커헉. 진짜다!

 


이것을 no 역순으로 출력해주면 되겠죠. 하지만 문제가 발생됩니다. 두 가지 문제. (엄밀히 말하면 한 가지 문제)

관리자는 게시판에서 게시물의 갯수를 페이지마다 10개씩 출력되기를 희망합니다.
하지만 no 나 num 를 기준으로 가져올 경우 10개보다 많이 출력될 수 있습니다. 왜냐하면 관련글 때문입니다. 관련글이 없다면 10개가 출력되겠지만 관련글을 가진 글이 있고 이 관련 글의 수가 3개일 경우 총 13개의
글이 출력됩니다. 이러면 안되죠.

또한 글이 삭제될 경우 해당 글 번호가 비는데 이럴 경우 글 정렬때 정상적으로 정렬이 안됩니다.
글 번호(no)를 기준으로 정렬할 때

1
2
3
4
5
6

이렇게 있다면 상관없지만, 4번 글이 삭제되어

1
2
3
5
6

으로 있다면 게시물은 1 번부터 3번까지만 뜰겁니다. 4번이 없기 때문에 5 6 이 안뜨죠.
그렇다고 글 삭제될 때마다 뒷 번호 글들의 글번호(no)를 1씩 줄여주자니 글 번호 자체가
바뀌어서 좋지 않구요.

그래서

idx int(5) DEFAULT '0' NOT NULL, # 여기 추가

이게 추가된 것입니다. idx 는 바로 게시물의 출력 인덱스죠.
글 정렬은 idx 를 기준으로 하며 글 추가(일반글/관련글)일 때 idx 값들이 변하죠.
만약 어떠 어떠한 글 중간에 관련글이 뜰 경우 그 관련글 이후의 모든 글의 idx 는 1 씩 더해집니다.
또한 어떠 어떠한 글 중간의 어떤 글을 삭제할 경우 글 삭제한 뒤 삭제된 뒤의 글의 idx 를 1씩 줄여줍니다.
이러면 어떻게 해서든 idx 는 1 2 3 4 5 ... 식으로 이어지죠. 설령 글 번호는 1 2 4 5 .. 식으로 될 지라도요.

이렇게 idx 를 쓰면 좋은 점이 또 있는데 글의 총 갯수나 사용자가 현재 몇 페이지의 글 번호를 읽고 있는지 알아내기가 수월합니다.
idx 의 맨 마지막 번호가 곧 글의 총 갯수죠.
또 전체 글 수에서 현재 글의 idx 를 뺀 뒤 이것을 페이지당 출력될 글 수로 나눈 뒤 정수형으로 변환하여 1 을 더하면 현재 사용자가 읽는 글이 속해있는 페이지 번호를 알아낼 수 있죠.

어렵다구요? ^^; 어쩔 수 없습니다.
일단은 글 자체만 이해하시고 내용 이해는 차후에 직접 게시판을 짜면서 이해하는 수 밖에.
(저도 이론을 정리할 때는 몰랐다가 직접 게시판을 만들면서 아! 하며 무릎을 탁 쳤죠)

위의 것을 DB 에서 살펴보면

no : num : idx : 제목
----+-----+-----------------
1 : 1 : 4 : 안녕하세요!
2 : 0 : 1 : re: 반가워요.
3 : 0 : 3 : re: 어서오세요.
4 : 0 : 2 : re: re: 감사합니다.
5 : 2 : 5 : 와우. 1번을 드시다니!
6 : 3 : 6 : 커헉. 진짜다!

이렇게 되어 있습니다. idx 역순으로 정리하면

no : num : idx : 제목
----+-----+-----------------
6 : 3 : 6 : 커헉. 진짜다!
5 : 2 : 5 : 와우. 1번을 드시다니!
1 : 1 : 4 : 안녕하세요!
3 : 0 : 3 : re: 어서오세요.
4 : 0 : 2 : re: re: 감사합니다.
2 : 0 : 1 : re: 반가워요.

이렇게 되어 있습니다. 게시판에 출력되야할

글번호 : 제목
------+-----------------------
6 : 커헉. 진짜다!
5 : 와우. 1번을 드시다니!
1 : 안녕하세요!
3 : re: 어서오세요
4 : re: re: 감사합니다.
2 : re: 반가워요.

과 동일하죠? :]


그럼 두 번째 방식을 알아보죠.
이 방식은 제가 처음 접해보고 "사람은 정말 만물의 영장답다" 를 느끼게 했습니다.
http://www.phpschool.com 에서 똥....(umean2me@netian.com)님께서 올리신 글에서 접했죠.

이 방식은 글 정렬하는 attribute 를 문자형으로 처리하는 방식입니다.
첫번째 방식은 idx 가 글 정렬을 담당하며 이것이 숫자형이죠.
이 방식의 문제점은 글이 중간에 추가되거나 관련글 작성시때마다 idx 의 숫자들을 모두 수정하는 방식입니다. (sql 에서 UPDATE 문) 때문에 글 수가 많고 앞 번호의 글에 관련글을 달거나 할 경우 서버가 버겁게 일을 처리하게 됩니다.
만약 글 갯수가 10만개이고 어떤 이용자가 1번 글에 답신글을 추가했다고 합시다.
그러면 2번부터 10만번까지의 글들의 idx 를 모두 1을 더해줘야 합니다.

하지만 이 방식은 update 자체를 하지 않습니다.
다만 문자열의 소트 방식을 아주 교묘히 이용했습니다.

글번호 : 제목
------+-----------------------
3 : 커헉. 진짜다!
2 : 와우. 1번을 드시다니!
1 : 안녕하세요!
- : re: 어서오세요
- : re: re: 감사합니다.
- : re: 반가워요.


이것은

no : idx : 제목
----+-----+-----------------
1 : 1 : 안녕하세요!
2 : 11 : re: 반가워요.
3 : 12 : re: 어서오세요.
4 : 111 : re: re: 감사합니다.
5 : 2 : 와우. 1번을 드시다니!
6 : 3 : 커헉. 진짜다!

이렇게 해주는 식입니다. 만약 1 번글에 관련 글이 붙으면 1 을 뒤에 붙여줍니다.
그럼 11 이 되겠죠. 그리고 다시 이 글에 관련 글이 붙으면 다시 1 이 뒤에 붙으므로 111 이 되겠죠.
만약 idx 가 2 번에 관련 글이 붙으면 여기에도 1 을 뒤에 붙이겠죠.
그럼 21 이 되구요.

이걸 idx 역순으로 정렬하면 놀랍게도

no : idx : 제목
----+-----+-----------------
6 : 3 : 커헉. 진짜다!
5 : 2 : 와우. 1번을 드시다니!
3 : 12 : re: 어서오세요.
4 : 111 : re: re: 감사합니다.
2 : 11 : re: 반가워요.
1 : 1 : 안녕하세요!

해줍니다.
문자형은 뭐가 큰지 작은지에 대한 개념이 없기 때문에 숫자순, 알파벳순으로 정렬을 하기에 위와 같이 되는게 가능하죠.
물론

replydepth int(7) DEFAULT '0' NOT NULL, # 추가

을 통해 관련 글이 있을 경우 매달린 관련 글 보다 늦게(위에) 출력을 해주면 되겠죠.


위의 두 내용이 쉽게 이해가 안가실 겁니다.
단지 저의 부족한 글 솜씨로 이해되기에는 위 내용이 꽤나 복잡한 내용이기 때문이죠.

하지만 확실한 건 전자의 방식, 즉 idx 값들을 1씩 증가해주거나 감소시켜주는 방식이 후자의 방식보다 더 쉽다면 쉽습니다.
그래서 저는 전자의 방식을 사용하겠습니다.
후자의 방식은 차후에 여러분이 직접 적용해보시거나 이런 방식도 있구나하며 참고하세요. :]

CREATE TABLE testboard (
no int(5) DEFAULT '0' NOT NULL auto_increment,
num int(5) DEFAULT '0' NOT NULL,
idx int(5) DEFAULT '0' NOT NULL,
usrtitle tinytext,
contents text,
replyon int(1) DEFAULT '0' NOT NULL,
replyto int(5) DEFAULT '0' NOT NULL,
replyfrom int(5) DEFAULT '0' NOT NULL,
replydepth int(5) DEFAULT '0' NOT NULL,
hit int(5) DEFAULT '0' NOT NULL,
filepath varchar(100), # 추가
filename varchar(100), # 추가
filesize int(4), # 추가
usrname varchar(12),
usrpasswd char(28),
usremail varchar(80),
usrhomepage varchar(80),
filluptime int(11) DEFAULT '0' NOT NULL,
PRIMARY KEY (no)
)

위의 추가된 부분은 파일 업로드를 위한 겁니다.
일단 파일을 업로드하면 해당 파일이 저장될 경로를 갖고 있을 필요가 있습니다.
물론 파일 이름도요. 그리고 파일 사이즈까지 갖고 있으면 파일 크기별로 검색을 할 때 편리할 것입니다.


끝났내요. 휴우. 이번 강좌는 굉장히 길군요. 치느라 힘 다 빠졌습니다.
ToT 이번 편은 쓰느라 2시간 30분이나 걸렸습니다.
php manual (kldp.org 에 있는거) 보고 직접 굴려보고 종이에 계산해보고 하느라 . 크흑.

이 강좌가 올라오고 한 동안 다음 강좌는 못올라 올 겁니다.
내용이 길어서가 아니라 다음 편인 '쉬'편을 한 번에 올려야 하거든요.
때문에 이 다음 회를 다 써놓고 곧바로 다음 편을 써놔야 합니다. 흑.
그러니 6월 28일까지는 이 다음 회 안올라옵니다. ^^;

다음 강좌는 게시판 만들 때 염두해야할 보안상의 주의점을 알아보겠습니다.
이번 강좌 따라오시느라 수고하셨어요. ^^/

다음 강좌에서 뵈요.

----------------------------
함께하면 즐거운 사이트들 (-_-; 광고임 -_-;)
http://game.creple.com/delthia
http://creple.com
http://coco.st
----------------------------


- ?! 디망쉬

관련자료

댓글 0
등록된 댓글이 없습니다.

공지사항


뉴스광장


  • 현재 회원수 :  60,056 명
  • 현재 강좌수 :  35,908 개
  • 현재 접속자 :  216 명