[英]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.