国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 語(yǔ)言 > PHP > 正文

純真ip數(shù)據(jù)庫(kù)查詢的php實(shí)現(xiàn)(補(bǔ)充分組查詢)

2024-09-04 11:50:11
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

原文發(fā)表于鳳凰花論壇:http://www.fenghuanghua.com/bbs/viewthread.php?tid=34&extra=page%3D1 有興趣的朋友可以在那里討論。 純真數(shù)據(jù)庫(kù)是國(guó)內(nèi)用的最多的ip-地理信息數(shù)據(jù)庫(kù),雖然不怎么專業(yè),但是數(shù)據(jù)蠻全的,數(shù)據(jù)結(jié)構(gòu)也比較合理。

關(guān)于純真數(shù)據(jù)庫(kù)的數(shù)據(jù)結(jié)構(gòu),可以看一下lumaqq的文檔,里面有一點(diǎn)說(shuō)的不太清楚,就是里面的ip和地理信息不是一對(duì)一,是多對(duì)一,所以ip一般是ip段。查詢的時(shí)候是查詢ip地址落在哪個(gè)段。

純真數(shù)據(jù)庫(kù)的查詢算法也已經(jīng)有人實(shí)現(xiàn)了:http://www.survivalescaperooms.com/article/2008/4055.shtml

用的是線性表的二分查詢。

純真數(shù)據(jù)庫(kù)比較大,大約有60萬(wàn)的記錄,上面的算法基本上可以接受了,平均查詢效率在2ms左右,對(duì)于單機(jī)程序,完全可以忽略,但是對(duì)于并發(fā)比較大的系統(tǒng),比如統(tǒng)計(jì)系統(tǒng),這樣的效率還不夠。

既然數(shù)據(jù)是線性存儲(chǔ)的,那么就可以采用分段查詢,預(yù)先將數(shù)據(jù)隔成段,查詢時(shí),先找到相應(yīng)的段,然后進(jìn)行二分查詢。

二分查詢的平均查找長(zhǎng)度是:lg(n+1)-1
那么分塊詢找+二分查詢的平均查找長(zhǎng)度就是:(設(shè)塊數(shù)為N)分塊也進(jìn)行二分查找,所以查找塊的平均長(zhǎng)度是lg(N+1)-1,每塊長(zhǎng)度是n/N ,所以最終長(zhǎng)度是:lg(N+1)-1 + lg(n/N+1)-1

根據(jù)上面的公式,代入n可以算出一個(gè)最佳塊數(shù)N,也就是最佳查詢時(shí)間了。數(shù)據(jù)量越大,查詢速度越快,數(shù)據(jù)量比較小的表就沒(méi)必要分塊了。

我高數(shù)學(xué)得不好,不知道對(duì)不對(duì)。請(qǐng)大蝦指正,另外幫忙算一下6249322條數(shù)據(jù)的最佳塊數(shù)。

修改后的代碼如下:(function separate($count)是我添加的分塊函數(shù),if($separator){}所在部分是二分查找塊)

<?php
/**
* IP 地理位置查詢類
* 增加分塊查詢算法
*
* @author 馬秉堯
* @version 1.5
* @copyright 2005 CoolCode.CN
* @modified by david  blog:blog.iyi.cn bbs:www.fenghuanghua.com
*/
class IpLocation {
    /**
     * QQWry.Dat文件指針
     *
     * @var resource
     */
    var $fp;

    /**
     * 第一條IP記錄的偏移地址
     *
     * @var int
     */
    var $firstip;

    /**
     * 最后一條IP記錄的偏移地址
     *
     * @var int
     */
    var $lastip;

    /**
     * IP記錄的總條數(shù)(不包含版本信息記錄)
     *
     * @var int
     */
    var $totalip;

    /**
     * 返回讀取的長(zhǎng)整型數(shù)
     *
     * @access private
     * @return int
     */
    function getlong() {
        //將讀取的little-endian編碼的4個(gè)字節(jié)轉(zhuǎn)化為長(zhǎng)整型數(shù)
        $result = unpack('Vlong', fread($this->fp, 4));
        return $result['long'];
    }

    /**
     * 返回讀取的3個(gè)字節(jié)的長(zhǎng)整型數(shù)
     *
     * @access private
     * @return int
     */
    function getlong3() {
        //將讀取的little-endian編碼的3個(gè)字節(jié)轉(zhuǎn)化為長(zhǎng)整型數(shù)
        $result = unpack('Vlong', fread($this->fp, 3).chr(0));
        return $result['long'];
    }

    /**
     * 返回壓縮后可進(jìn)行比較的IP地址
     *
     * @access private
     * @param string $ip
     * @return string
     */
    function packip($ip) {
        // 將IP地址轉(zhuǎn)化為長(zhǎng)整型數(shù),如果在PHP5中,IP地址錯(cuò)誤,則返回False,
        // 這時(shí)intval將Flase轉(zhuǎn)化為整數(shù)-1,之后壓縮成big-endian編碼的字符串
        return pack('N', intval($ip));
    }

    /**
     * 返回讀取的字符串
     *
     * @access private
     * @param string $data
     * @return string
     */
    function getstring($data = "") {
        while (ord($char = fread($this->fp, 1)) > 0) {        // 字符串按照C格式保存,以 主站蜘蛛池模板: 沁源县| 威信县| 白山市| 菏泽市| 仙居县| 青川县| 大关县| 揭东县| 黔南| 庆城县| 沧州市| 普宁市| 岳池县| 宁陕县| 昌平区| 鸡泽县| 沽源县| 张家港市| 金塔县| 手游| 昌都县| 禹城市| 柳林县| 京山县| 麦盖提县| 西和县| 阳东县| 清河县| 本溪市| 海阳市| 洱源县| 涞水县| 温宿县| 柏乡县| 怀柔区| 南丰县| 抚宁县| 米泉市| 公主岭市| 尼木县| 浪卡子县|