1000만건 게시판에 도전합니다. 첫번째 > 개발자팁

개발자팁

개발과 관련된 유용한 정보를 공유하세요.
질문은 QA에서 해주시기 바랍니다.

1000만건 게시판에 도전합니다. 첫번째 정보

MySQL 1000만건 게시판에 도전합니다. 첫번째

본문

그누보드4 개발후 유지보수만 하면서

그누보드5 개발때도 주축으로 일을 하지 않아

머리가 굳어 버렸습니다.

 

그누보드4의 게시판 알고리즘이 생각나지 않아 테이블 구조를 보면서도 한참을 헤매였네요.

기분전환에 공부도 할겸 예전에 만들지 못한 1000만건 게시판에 도전해볼까 합니다.

 

그누보드4, 5의 경우 원글과 댓글을 하나의 게시판으로 합쳐 테이블수를 줄였다고는 하지만

하나의 게시판에 하나의 테이블이 존재하여 많은수의 게시판을 운영하려면 많은 게시판 테이블이

생성될수 밖에 없는 구조입니다.

 

이번에는 이것을 완전한 하나의 테이블로 제작할까 합니다.

좀더 쉽게 얘기하자면 다음이나 네이버의 카페와 비슷한 구조라고나 할까요?

 

네이버 카페에는 전체글보기라는 메뉴가 있고 그 아래 여러 게시판들이 존재합니다.

여러 게시판이 모여 전체글을 구성하는 것이지요.

어떻게 보면 전체글에 각각의 게시판 아이디가 부여되어 여러 게시판을 구성하고 있다는 보는것이 맞는 표현이겠습니다.

 

1000만건 게시판에 가장 중요한 속도 문제를 해결하기 위해 다음과 같은 조건을 충족해야 합니다.

1. 가장 끝 페이지의 목록은 1초 이내로 표시가 되어야 한다.

   (limit 를 사용하는 경우 가장 끝 페이지를 쿼리하는데 속도가 가장 오래 걸립니다.)

2. 글 읽기시 0.1 초 내에 표시가 되어야 한다.

   (글과 댓글을 모두 표시하는데 최대한 빠른 시간에 화면 표시가 되어야 합니다.

    로봇들이 상주하여 글을 읽어가는 경우가 많으므로 딜레이가 되면 안됩니다.)

3. 전체글 검색시 0.1 초를 넘지 않아야 한다.

   (like 검색 사용 불가) 

 

 

테이블의 구조는 다음과 같은 형식으로 구성을 하였습니다.

 

--

-- 테이블 구조 `8post`

--

 

CREATE TABLE IF NOT EXISTS `8post` (

  `po_id` mediumint(8) unsigned NOT NULL,

  `bo_id` smallint(6) NOT NULL,

  `po_parent` mediumint(8) unsigned NOT NULL,

  `po_num` mediumint(8) unsigned NOT NULL,

  `po_reply` varchar(10) NOT NULL,

  `po_comment` bit(1) NOT NULL,

  `po_comment_cnt` smallint(5) unsigned NOT NULL,

  `ca_name` varchar(255) NOT NULL,

  `mb_id` varchar(20) NOT NULL,

  `po_title` varchar(255) NOT NULL,

  `po_content` text NOT NULL,

  `po_tag` varchar(255) NOT NULL,

  `po_datetime` datetime NOT NULL,

  `po_title_ft` text NOT NULL,

  `po_content_ft` text NOT NULL,

  `po_tag_ft` text NOT NULL

) ENGINE=MyISAM DEFAULT CHARSET=utf8;

 

--

-- 덤프된 테이블의 인덱스

--

 

--

-- 테이블의 인덱스 `8post`

--

ALTER TABLE `8post`

  ADD PRIMARY KEY (`po_id`),

  ADD KEY `mb_id` (`mb_id`),

  ADD KEY `po_menu` (`bo_id`,`po_comment`,`po_num`) USING BTREE,

  ADD KEY `po_parent` (`po_comment`,`po_parent`) USING BTREE,

  ADD KEY `po_comment_2` (`po_comment`,`po_num`) USING BTREE,

  ADD FULLTEXT KEY `po_title_ft` (`po_title_ft`);

ALTER TABLE `8post`

  ADD FULLTEXT KEY `po_content_ft` (`po_content_ft`);

ALTER TABLE `8post`

  ADD FULLTEXT KEY `po_tag_ft` (`po_tag_ft`);

 

--

-- 덤프된 테이블의 AUTO_INCREMENT

--

 

 

이전의 그누보드와 다른점은 num 과 reply 를 글과 댓글에서 공동으로 사용한다는 것입니다.

 

글은 아래와 같은 방식으로 등록이 됩니다.

 

9bab3b04b6a67a536066169efb539fe4_1446192009_4899.png
 

po_num 은 원글(댓글이 아닌)일 경우 원글의 num 을 따르며, 댓글(댓답글이 아닌)일 경우 계속 1씩 증가가 됩니다.

 

po_reply 는 답변의 depth 이며 36진수를 사용하여 z 부터 시작하고 1 까지 순차적으로 감소합니다. 

즉 하나의 글에 답변은 35개 까지 가능하며 depth 는 po_reply 의 varchar 갯수만큼 가능합니다.

 

그런데 이 구조로 40만개 정도의 원글을 25개씩 잘라 마지막 페이지를 노출했더니 1초가 넘는 속도가 나왔습니다.

그래서 이 구조는 적용하기가 어렵다고 판단되어 다른 방법이나, 테이블을 원글과 댓글로 나누어 두개의 테이블로 운영하는 것을 고려해 봐야겠습니다.

 

-끝-

추천
2

댓글 3개

예전 10년전에 asp + mssql 조합으로 했을때 (물론 dbms 가 달라서 동일하다고 볼수없겠지만..)
원글 + 댓글 + 파일 테이블로 나누었을때가 가장 이상적이었습니다.
그때는 지금정도의 서버사양은 아니라서 100만건기준으로 잡았었습니다.

검색은 like 검색을 사용할경우 아래와 같이 인덱스를 타도록 처리해주었습니다.
mysql> select * from tablename where name LIKE "dino%";
mysql> select * from tablename where name LIKE "di%sf%";
FULLTEXT 의 장점은 '그누보드' 라는 단어의 경우 그누보드, 누보드, 보드, 드 까지 검색이 된다는 것입니다.
LIKE 검색과는 결과가 다를것 같습니다.
말씀 감사합니다.
전체 250
개발자팁 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT