代码之家  ›  专栏  ›  技术社区  ›  Andres SK

显示我的国家基于我的IP,MySQL优化

  •  1
  • Andres SK  · 技术社区  · 15 年前

    我已经从下载了wipmania的worldip表 http://www.wipmania.com/en/base/ --该表有3个字段,约79K行:

    • StartIP//示例:3363110912
    • endip//示例:3363112063
    • 国家/示例:AR(阿根廷)

    那么,假设我在阿根廷,我的IP地址是:200.117.248.17

    1) 我使用此函数将我的IP转换为long

    function ip_address_to_number($ip) {
        if(!$ip) {
            return false;
        } else {
            $ip = split('\.',$ip);
            return($ip[0]*16777216 + $ip[1]*65536 + $ip[2]*256 + $ip[3]);
        }
    }
    

    2) 我通过匹配长时间转换的IP来搜索正确的国家/地区代码:

    $sql = 'SELECT * FROM worldip WHERE '.ip_address_to_number($_SERVER['REMOTE_ADDR']).' BETWEEN startip AND endip';
    

    相当于: 从worldip中选择国家,其中startip和endip之间为3363174417 (基准:显示0-0行(共1行,查询耗时0.2109秒)

    现在来了 真实的 问题 .

    如果另一帮阿根廷佬也打开了网站,他们都有这些IP地址呢:

    • 200 .117248
    • 200 .11723 3.10
    • 200 .117241.88
    • 200 .117159

    因为我正在缓存所有的SQL查询;而不是匹配数据库中的每个IP查询,那么通过修改这样的函数来匹配IP的前两个部分会更好吗?

    function ip_address_to_number($ip) {
        if(!$ip) {
            return false;
        } else {
            $ip = split('\.',$ip);
            return($ip[0]*16777216 + $ip[1]*65536);
        }
    }
    

    (请注意,已删除IP的第3和第4个拆分值)。

    这样就不用查询这4个值:

    • 三十三亿六千三百一十七万四千四百一十七
    • 三十三亿六千三百一十七万零五百七十
    • 三十三亿六千三百一十七万二千六百九十六
    • 三十三亿六千三百一十五万一千六百四十

    ……我要问的是:3363110912(200.117)。 转换为long)。

    这是对的吗?还有其他优化这个过程的想法吗?

    2 回复  |  直到 14 年前
        1
  •  1
  •   Maurice Kherlakian    15 年前

    你一定要用wipmania吗?如果没有,MaxMind提供了一个开源解决方案: http://www.maxmind.com/app/geolitecountry . 其优点是它是一个二进制文件,并且有一个PHP扩展名(您必须编译它并安装它)。在几个项目中使用它,查找速度非常快。您可以在这里获得PCL扩展名: http://pecl.php.net/package/geoip

        2
  •  2
  •   Artefacto    15 年前

    不。

    193.150.1.1 -俄罗斯IP 193.150.230.1 瑞典IP

    你可以把它截为前三个八分位数,但是…你不会有那么多缓存命中。而且很有可能是一些/24网络被分成了两个部分。有时,会给出小于/24的块。

    推荐文章