程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 關鍵詞匹配項目深入研究(二)- 分表思想的引入,關鍵詞深入研究

關鍵詞匹配項目深入研究(二)- 分表思想的引入,關鍵詞深入研究

編輯:關於PHP編程

關鍵詞匹配項目深入研究(二)- 分表思想的引入,關鍵詞深入研究


(二)分表思想的引入

近期的文章: 1)高並發數據采集的架構應用(Redis的應用)

                    2)高可用數據采集平台(如何玩轉3門語言php+.net+aauto)

 

手把手教你做關鍵詞匹配項目這塊基本已經完成,深入研究是對系統的性能作為分析,在一些環境的刺激下所必需要做的一些改變。

手把手教你做關鍵詞匹配項目: 手把手教你做關鍵詞匹配項目(搜索引擎)---- 第一天~手把手教你做關鍵詞匹配項目(搜索引擎)---- 第二十二天 (共22篇)

深入研究:上節講到 關鍵詞匹配項目深入研究-過濾器的引入。

每一篇會分為問題的前因解決方案以及有些必要的實現方案

本篇正文正式開始。

問題的前因

        隨著自動采集數據的爆炸式的增長,詞庫的容量蒸蒸日上,一下從幾W數據猛增幾百萬數據,小帥帥看著數據庫的查詢越來越感到無能為力。

      再加上小丁丁常對小帥帥說的最多的一句:何時那麼選詞能快一點,每次我都等好久都莫有反應,真是急死我了。

      小帥帥也比較焦急,心力憔悴,真正的感覺到原來這就是挑戰。小帥帥無可奈何的繼續找到於老大,求於老大賞賜高招。

      於老大拍拍小帥帥的肩膀:小伙子,知道項目的難度了吧!

      小帥帥回答道:別挖苦我了,我已深深的感受到了,我想我心髒估計快承受不了了。

      於老大:就這點你就承受不了,那估計以後有的是給你受的。

      小帥帥:大哥,別說這些虛的行不,趕緊的解決方案丫。

      於老大:急啥,事情是急不來的,過來,哥給你指條明路。

      “每個寶貝是不是有類別的屬性,那麼這幾百萬數據真正屬於這個類別的詞能夠有多少?假設我們只取這個類別的詞庫我們的項目是否可以繼續穩定下來”。

解決方案

        按照某種業務需要,我們可以對數據表實行分割,可以縱向或者橫向分割,可以有效的進行性能優化。

       縱向分割也稱列分割,把不常用的列或者長字段分割來保證實體處於一個相對適用的狀態,常見的有一對一關聯。

       橫向分割也稱行分割,按照某種業務拆分數據的記錄來存放在不同的表,常見的有按日期分表操作。

       本案例是使用橫向分割,把數據按照類別的形式進行拆分。

實現方案

        我們為了不更改數據表的結構,這樣設計了,我們按照表名來區分項目使用那個數據表。這樣一來的改動相對是非常少的。我們只需稍微改動下代碼就可以解決了,這很心塞的一件事情。

        修改Keyword的代碼,增加獲取數據源。

<?php
define('DATABASE_HOST','127.0.0.1');
define('DATABASE_USER','xiaoshuaishuai');
define('DATABASE__PASSWORD','xiaoshuaishuai');
define('DATABASE_CHARSET','utf-8');

class Keyword {

    public $word;

    public static $conn = null;

    public function getDbConn(){
        if(self::$conn == null){
            self::$conn = mysql_connect(DATABASE_HOST,DATABASE_USER,DATABASE__PASSWORD);
            mysql_query("SET NAMES '".DATABASE_CHARSET."'",self::$conn);
            mysql_select_db("dict",self::$conn);
            return self::$conn;
        }
        return self::$conn;
    }


    public function save(){

        $sql = "insert into keywords(word) values ('$this->word')";
        return mysql_query($sql,$this->getDbConn());
    }

    public static function getWordsSource($cid,$limit=0,$offset=40){
        $sql = "SELECT * FROM keywords_$cid LIMIT $limit,$ffset";
        return DB::MakeArray($sql);
    }

    public static function getWordsCount($cid){
          $sql = "SELECT count(*) FROM keywords_$cid";
        return DB::QueryScalar($sql);

    }

}

DB類新增QueryScalar,用於算總量

<?php
#@author oShine
define('DATABASE_HOST','127.0.0.1');
define('DATABASE_USER','xiaoshuaishuai');
define('DATABASE__PASSWORD','xiaoshuaishuai');
define('DATABASE_CHARSET','utf-8');

class DB {

    public static $conn = null;

    public static function Connect(){
        if(self::$conn == null){
            self::$conn = mysql_connect(DATABASE_HOST,DATABASE_USER,DATABASE__PASSWORD);
            mysql_query("SET NAMES '".DATABASE_CHARSET."'",self::$conn);
            mysql_select_db("dict",self::$conn);
            return self::$conn;
        }
        return self::$conn;
    }

    public static function Query($sql){
       return mysql_query($sql,self::Connect());
    }

    public static function makeArray($sql){
        $rs = self::Query($sql);
        $result = array();
        while($data = mysql_fetch_assoc($rs)){
            $result[] = $data;
        }
        return $result;
    }

    public static function QueryScalar($sql){
         $rs = self::Query($sql);
         $data = mysql_fetch_array($rs);
         if($data == false || empty($data) || !isset($data[1])) return 0;
         return $data[1];
    }
} 

修改Selector的代碼,用於選詞:

<?php
#@Filename:selector/Selector.php
#@Author:oshine

require_once dirname(__FILE__) . '/SelectorItem.php';
require_once dirname(__FILE__) . '/charlist/CharList.php';
require_once dirname(__FILE__) . '/charlist/CharlistHandle.php';
require_once dirname(dirname(__FILE__)) . '/lib/Logger.php';

class Selector
{

    private static $charListHandle = array(
        "黑名單" => "BacklistCharListHandle",
        "近義詞" => "LinklistCharListHandle"
    );

    public static function select($num_iid)
    {
        $selectorItem = SelectorItem::createFromApi($num_iid);

        Logger::trace($selectorItem->props_name);

        $charlist = new CharList();

        foreach (self::$charListHandle as $matchKey => $className) {

            $handle = self::createCharListHandle($className, $charlist, $selectorItem);
            $handle->exec();

        }

        $selectWords = array();

        $wordsCount = Keyword::getWordsCount(selectorItem->cid);
        $offset = 40;
        $page =  ceil($wordsCount/$offset);
        for($i=0;$i<=$page;$i++){
            $limit = $i*$offset;
            $keywords = Keyword::getWordsSource(selectorItem->cid,$limit,$offset);
             foreach ($keywords as $val) {
                # code...
                $keywordEntity = SplitterApp::split($val["word"]);
                
                    # code...
                if(MacthExector::macth($keywordEntity,$charlist)){
                    $selectWords[] = $val["word"];
                }          

            }
        }

        return $selectWords;
    }

    public static function createCharListHandle($className, $charlist, $selectorItem)
    {
        if (class_exists($className)) {
            return new $className($charlist, $selectorItem);
        }
        throw new Exception("class not exists", 0);
    }
}

總結
      小帥帥又學到了新的知識點,這是要犒勞於老大的節奏嗎?你們是否也要犒勞下我呢,求贊哈!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved