(2) 서브 테이블 아이디어 소개
최근 기사: 1) 높은 동시 데이터 수집 아키텍처 적용(Redis 애플리케이션)
2) 가용성이 높은 데이터 수집 플랫폼(3개 언어로 플레이하는 방법 php+.net+aauto)
키워드 매칭 프로젝트에 대한 단계별 교육은 기본적으로 완료되었습니다. 심층적인 연구는 시스템 성능을 분석하고 일부 환경의 자극에 따라 이루어져야 하는 몇 가지 변경 사항을 적용하는 것입니다.
키워드 매칭 프로젝트를 단계별로 가르쳐드립니다 : 키워드 매칭 프로젝트를 단계별로 가르쳐드립니다 (검색 엔진) ---- 1일차 ~ 키워드 매칭 프로젝트를 단계별로 가르쳐주세요 프로젝트(검색엔진) ---- 두 번째 열두일(총 22개 글)
심층 연구: 이전 섹션에서는 키워드 매칭 프로젝트에 대한 심층 연구-필터 소개에 대해 이야기했습니다.
각 기사는 문제의 원인, 해결책, 필요한 구현 계획으로 나누어집니다.
이 글은 공식적으로 시작됩니다.
문제 원인
자동으로 수집되는 데이터가 폭발적으로 증가함에 따라 어휘의 용량은 몇 와트의 데이터에서 수백만 개의 데이터로 날로 증가하고 있습니다. Xiao Shuaishuai는 데이터베이스의 쿼리를 볼 때 점점 더 무력감을 느낍니다.
게다가 Xiao Ding Ding이 Xiao Shuai Shuai에게 가장 자주 하는 말은 다음과 같습니다. 언제 그렇게 빨리 단어를 선택할 수 있습니까? 오랫동안 기다려도 응답이 없을 때마다 정말 죽도록 불안합니다.
리틀 미남도 더 불안하고 마음이 초췌해지네요 이게 정말 도전이구나 싶더라구요. Xiao Shuaishuai는 계속해서 보스를 찾을 수밖에 없었고 그에게 영리한 속임수로 보상을 해달라고 요청했습니다.
Yu 상사가 Xiao Shuaishuai의 어깨를 두드리며 말했습니다. 청년 여러분, 이 프로젝트가 얼마나 어려운지 아시겠습니까?
Xiao Shuaishuai는 다음과 같이 대답했습니다. 비웃지 마십시오. 나는 그것을 깊이 느꼈고 내 마음이 그것을 견딜 수 없을 것 같습니다.
유사장님: 이걸 못 참으시면 앞으로는 더 많이 받으실 것 같아요.
작은 미남: 형님, 이런 가상 행동은 말할 것도 없고, 서둘러 해결하세요.
유 사장: 왜 서두르세요? 서두르면 안 돼요. 길을 잘 알려드릴게요.
“각 아기는 카테고리 속성을 가지고 있나요? 이 수백만 개의 데이터 중 실제로 이 카테고리에 속하는 단어는 몇 개인가요? 이 카테고리의 어휘만 사용한다고 가정하면 우리 프로젝트가 계속 안정적으로 진행될 수 있을까요?
솔루션
특정 비즈니스 요구에 따라 데이터 테이블을 수직 또는 수평으로 분할하여 성능을 효과적으로 최적화할 수 있습니다.
수직 분할은 일반적이지 않은 열이나 긴 필드를 분할하여 엔터티가 상대적으로 적용 가능한 상태인지 확인하는 것입니다.
행 분할이라고도 하는 수평 분할은 특정 비즈니스에 따라 데이터 레코드를 분할하고 이를 다른 테이블에 저장합니다. 일반적인 테이블 분할 작업에는 날짜 분할이 포함됩니다.
이 사례에서는 수평 분할을 사용하여 데이터를 카테고리로 분할합니다.
실시계획
데이터 테이블의 구조가 변경되지 않도록 이렇게 설계했습니다. 테이블 이름을 기준으로 프로젝트에서 어떤 데이터 테이블을 사용하는지 구분합니다. 이로 인한 변화는 상대적으로 적습니다. 이 문제를 해결하려면 코드를 약간만 변경하면 되는데, 이는 매우 실망스러운 일입니다.
키워드 코드를 수정하고 데이터 소스를 추가하세요.
<?<span>php </span><span>define</span>('DATABASE_HOST','127.0.0.1'<span>); </span><span>define</span>('DATABASE_USER','xiaoshuaishuai'<span>); </span><span>define</span>('DATABASE__PASSWORD','xiaoshuaishuai'<span>); </span><span>define</span>('DATABASE_CHARSET','utf-8'<span>); </span><span>class</span><span> Keyword { </span><span>public</span> <span>$word</span><span>; </span><span>public</span> <span>static</span> <span>$conn</span> = <span>null</span><span>; </span><span>public</span> <span>function</span><span> getDbConn(){ </span><span>if</span>(self::<span>$conn</span> == <span>null</span><span>){ self</span>::<span>$conn</span> = <span>mysql_connect</span>(DATABASE_HOST,DATABASE_USER,<span>DATABASE__PASSWORD); </span><span>mysql_query</span>("SET NAMES '".DATABASE_CHARSET."'",self::<span>$conn</span><span>); </span><span>mysql_select_db</span>("dict",self::<span>$conn</span><span>); </span><span>return</span> self::<span>$conn</span><span>; } </span><span>return</span> self::<span>$conn</span><span>; } </span><span>public</span> <span>function</span><span> save(){ </span><span>$sql</span> = "insert into keywords(word) values ('<span>$this</span>->word')"<span>; </span><span>return</span> <span>mysql_query</span>(<span>$sql</span>,<span>$this</span>-><span>getDbConn()); } </span><span>public</span> <span>static</span> <span>function</span> getWordsSource(<span>$cid</span>,<span>$limit</span>=0,<span>$offset</span>=40<span>){ </span><span>$sql</span> = "SELECT * FROM keywords_<span>$cid</span> LIMIT <span>$limit</span>,<span>$ffset</span>"<span>; </span><span>return</span> DB::MakeArray(<span>$sql</span><span>); } </span><span>public</span> <span>static</span> <span>function</span> getWordsCount(<span>$cid</span><span>){ </span><span>$sql</span> = "SELECT count(*) FROM keywords_<span>$cid</span>"<span>; </span><span>return</span> DB::QueryScalar(<span>$sql</span><span>); } }</span>
총액 계산에 사용되는 DB 클래스에 새로운 QueryScalar가 추가되었습니다
<?<span>php </span><span>#</span><span>@author oShine</span> <span>define</span>('DATABASE_HOST','127.0.0.1'<span>); </span><span>define</span>('DATABASE_USER','xiaoshuaishuai'<span>); </span><span>define</span>('DATABASE__PASSWORD','xiaoshuaishuai'<span>); </span><span>define</span>('DATABASE_CHARSET','utf-8'<span>); </span><span>class</span><span> DB { </span><span>public</span> <span>static</span> <span>$conn</span> = <span>null</span><span>; </span><span>public</span> <span>static</span> <span>function</span><span> Connect(){ </span><span>if</span>(self::<span>$conn</span> == <span>null</span><span>){ self</span>::<span>$conn</span> = <span>mysql_connect</span>(DATABASE_HOST,DATABASE_USER,<span>DATABASE__PASSWORD); </span><span>mysql_query</span>("SET NAMES '".DATABASE_CHARSET."'",self::<span>$conn</span><span>); </span><span>mysql_select_db</span>("dict",self::<span>$conn</span><span>); </span><span>return</span> self::<span>$conn</span><span>; } </span><span>return</span> self::<span>$conn</span><span>; } </span><span>public</span> <span>static</span> <span>function</span> Query(<span>$sql</span><span>){ </span><span>return</span> <span>mysql_query</span>(<span>$sql</span>,self::<span>Connect()); } </span><span>public</span> <span>static</span> <span>function</span> makeArray(<span>$sql</span><span>){ </span><span>$rs</span> = self::Query(<span>$sql</span><span>); </span><span>$result</span> = <span>array</span><span>(); </span><span>while</span>(<span>$data</span> = <span>mysql_fetch_assoc</span>(<span>$rs</span><span>)){ </span><span>$result</span>[] = <span>$data</span><span>; } </span><span>return</span> <span>$result</span><span>; } </span><span>public</span> <span>static</span> <span>function</span> QueryScalar(<span>$sql</span><span>){ </span><span>$rs</span> = self::Query(<span>$sql</span><span>); </span><span>$data</span> = <span>mysql_fetch_array</span>(<span>$rs</span><span>); </span><span>if</span>(<span>$data</span> == <span>false</span> || <span>empty</span>(<span>$data</span>) || !<span>isset</span>(<span>$data</span>[1])) <span>return</span> 0<span>; </span><span>return</span> <span>$data</span>[1<span>]; } } </span>
단어 선택을 위한 선택기 코드 수정:
<?<span>php </span><span>#</span><span>@Filename:selector/Selector.php</span><span> #</span><span>@Author:oshine</span> <span>require_once</span> <span>dirname</span>(<span>__FILE__</span>) . '/SelectorItem.php'<span>; </span><span>require_once</span> <span>dirname</span>(<span>__FILE__</span>) . '/charlist/CharList.php'<span>; </span><span>require_once</span> <span>dirname</span>(<span>__FILE__</span>) . '/charlist/CharlistHandle.php'<span>; </span><span>require_once</span> <span>dirname</span>(<span>dirname</span>(<span>__FILE__</span>)) . '/lib/Logger.php'<span>; </span><span>class</span><span> Selector { </span><span>private</span> <span>static</span> <span>$charListHandle</span> = <span>array</span><span>( </span>"黑名单" => "BacklistCharListHandle", "近义词" => "LinklistCharListHandle"<span> ); </span><span>public</span> <span>static</span> <span>function</span> select(<span>$num_iid</span><span>) { </span><span>$selectorItem</span> = SelectorItem::createFromApi(<span>$num_iid</span><span>); Logger</span>::trace(<span>$selectorItem</span>-><span>props_name); </span><span>$charlist</span> = <span>new</span><span> CharList(); </span><span>foreach</span> (self::<span>$charListHandle</span> <span>as</span> <span>$matchKey</span> => <span>$className</span><span>) { </span><span>$handle</span> = self::createCharListHandle(<span>$className</span>, <span>$charlist</span>, <span>$selectorItem</span><span>); </span><span>$handle</span>-><span>exec</span><span>(); } </span><span>$selectWords</span> = <span>array</span><span>(); </span><span>$wordsCount</span> = Keyword::getWordsCount(selectorItem-><span>cid); </span><span>$offset</span> = 40<span>; </span><span>$page</span> = <span>ceil</span>(<span>$wordsCount</span>/<span>$offset</span><span>); </span><span>for</span>(<span>$i</span>=0;<span>$i</span><=<span>$page</span>;<span>$i</span>++<span>){ </span><span>$limit</span> = <span>$i</span>*<span>$offset</span><span>; </span><span>$keywords</span> = Keyword::getWordsSource(selectorItem->cid,<span>$limit</span>,<span>$offset</span><span>); </span><span>foreach</span> (<span>$keywords</span> <span>as</span> <span>$val</span><span>) { </span><span>#</span><span> code...</span> <span>$keywordEntity</span> = SplitterApp::<span>split</span>(<span>$val</span>["word"<span>]); </span><span>#</span><span> code...</span> <span>if</span>(MacthExector::macth(<span>$keywordEntity</span>,<span>$charlist</span><span>)){ </span><span>$selectWords</span>[] = <span>$val</span>["word"<span>]; } } } </span><span>return</span> <span>$selectWords</span><span>; } </span><span>public</span> <span>static</span> <span>function</span> createCharListHandle(<span>$className</span>, <span>$charlist</span>, <span>$selectorItem</span><span>) { </span><span>if</span> (<span>class_exists</span>(<span>$className</span><span>)) { </span><span>return</span> <span>new</span> <span>$className</span>(<span>$charlist</span>, <span>$selectorItem</span><span>); } </span><span>throw</span> <span>new</span> <span>Exception</span>("class not exists", 0<span>); } }</span>
요약
샤오슈아이슈아이가 새로운 지식 포인트를 배웠습니다. 이것이 상사에게 보상을 주는 방법인가요? 당신도 나에게 보상을 주고 싶나요?
위 내용은 키워드 매칭 프로젝트(2)에 대한 심층적인 연구를 소개한 것입니다. - 내용의 측면을 포함한 하위 테이블의 아이디어 소개가 PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.