繁体   English   中英

PHP / MySQL IP到“国家/地区”统计页面

[英]PHP/MySQL IP to country for Stats page

我目前正在为其他人转换脚本,在他们的旧代码中,他们有一个CSV文件,其中列出了所有IP及其所在的国家/地区。 该文件的格式如下:

16777216    17367039    AU  AUS AUSTRALIA
17367040    17432575    MY  MYS MALAYSIA
17432576    17498111    AU  AUS AUSTRALIA
17498112    17563647    KR  KOR REPUBLIC OF KOREA
17563648    17825791    CN  CHN CHINA

很好,这就是他们所做的,我将其导入了新的MySQL数据库。 但是问题是他们这里有111K记录!

要进行比较并找到国家/地区的IP,大约需要40秒。 当前,他们选择所有记录并与下一个字段进行比较。

$datafile = file("iplist.csv");
    $countries = array();
    foreach($datafile as $data) {
        $data = explode(",", $data);
        foreach($iplist as $ipan => $ip) {
            if($ip > $data[0] && $ip < $data[1]) {
                $countries[$ip] = array($data[2], $data[4]);
            }
        }
    }

我当然知道这是一种可怕的方式,太可怕了! 当我在MySQL中执行操作时,这甚至很糟糕,我的意思是就坐在那里的111K条记录。

我整天都在动脑筋,再也想不到这样做了。 IP以标准格式存储在DB中。 我以为我只会从MySQL中进行选择,而在where语句中则执行大于和小于。 但是对于我的一生,我可以想到。 考虑到这是他们制作IP列表的方式:

foreach($log as $row) {
        $iplist[$row[2]] = $row[2];

        if($last != "") {
            $dif = $last-$row[5];
            $avgtime += $dif;
        }
        $last = $row[5];
    }

我想对每条记录进行一次调用,但是如果每个统计页上正常出现120条记录,那么该记录就消失了,因为那将是对mysql的最少120次调用。

谁能给我一种更好,更有效的方式进行比较?

我当时在考虑使用外部服务,但是请求太多了,我认为该站点将被列入黑名单。

为什么不试试这个:

SELECT * FROM table WHERE ip_min >= $your_value and ip_max <= $your_value

其中ip_min是数据的第一列,而ip_max是第二列。 $your_value显然是您所知道的ip值。

此外,关于geoIP位置,为什么不使用MaxMind这样的标准数据库之一。 我个人喜欢使用带有MaxMind数据库的mod_geoip模块在Web服务器上处理国家/地区ip geoLocation。 然后,您可以每月更新一次此数据库,而不必担心尝试在应用程序中保留最新的IP数据库。 mod_geoip只是向$_SERVER超全局变量公开了一些其他值,您可以读取这些值以获得国家/地区代码或国家/地区名称(甚至是城市名称)。

您应该在mysql查询中使用join:

SELECT s.*, g.country_code, g.country_name FROM stats s LEFT JOIN geoip g ON ( g.ip_min <= s.ip AND g.ip_max >= s.ip ) 

然后,您将在一个查询中拥有它。

使用INNER JOIN而不是LEFT JOIN更快,但是它不会选择ip超出范围的记录

无论如何,我认为最好先找到该位置,然后再插入统计信息表,并为国家/地区ID分配统计信息记录-您也必须加入它,但它的工作速度更快

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM