키워드 매칭 프로젝트 심층 연구 (2) - 하위 테이블 아이디어 소개

WBOY
풀어 주다: 2016-08-08 09:31:53
원래의
923명이 탐색했습니다.

(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 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿