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