免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234567
最近访问板块 发新帖
楼主: qingmedia
打印 上一主题 下一主题

[性能] ip查询用文本好还是数据库好? [复制链接]

论坛徽章:
62
2016科比退役纪念章
日期:2016-06-28 17:45:06奥兰多魔术
日期:2015-05-04 22:47:40菠菜神灯
日期:2015-05-04 22:35:07菠菜神灯
日期:2015-05-04 22:35:02NBA季后赛大富翁
日期:2015-05-04 22:33:34NBA常规赛纪念章
日期:2015-05-04 22:32:032015年亚洲杯纪念徽章
日期:2015-04-14 16:54:452015年亚洲杯之朝鲜
日期:2015-03-19 23:03:16明尼苏达森林狼
日期:2015-03-16 21:51:152015小元宵徽章
日期:2015-03-06 15:57:202015年迎新春徽章
日期:2015-03-04 09:55:282015年辞旧岁徽章
日期:2015-03-03 16:54:15
61 [报告]
发表于 2005-11-10 11:56 |只看该作者
原帖由 geel 于 2005-11-10 11:48 发表
Maildir是因为单条记录大所以用文件系统,这样能平衡
但是如果你认为对于查询ip来说,59.x.txt这种方法更有效率,那就去做吧


Maildir不是因为单条记录大。
数据库的设计原则只有一条,就是方便查询。
邮件系统的特点是每个人只能看到自己的数据,看不到其他人的,和论坛不一样
大家看一样的。
邮件不采用数据库,是因为
第一数据量太大查询困难,第二每个用户永远只select 有限的又互不相干的记录得不偿失

论坛徽章:
62
2016科比退役纪念章
日期:2016-06-28 17:45:06奥兰多魔术
日期:2015-05-04 22:47:40菠菜神灯
日期:2015-05-04 22:35:07菠菜神灯
日期:2015-05-04 22:35:02NBA季后赛大富翁
日期:2015-05-04 22:33:34NBA常规赛纪念章
日期:2015-05-04 22:32:032015年亚洲杯纪念徽章
日期:2015-04-14 16:54:452015年亚洲杯之朝鲜
日期:2015-03-19 23:03:16明尼苏达森林狼
日期:2015-03-16 21:51:152015小元宵徽章
日期:2015-03-06 15:57:202015年迎新春徽章
日期:2015-03-04 09:55:282015年辞旧岁徽章
日期:2015-03-03 16:54:15
62 [报告]
发表于 2005-11-10 12:00 |只看该作者
原帖由 wuruichang 于 2005-11-10 11:51 发表
你说的“59.3.txt也会有6w多条记录”难道不是理论数据?

就此中止吧,没必要一定分出胜负。。。



我说的不是理论是事实。
一个小城市的地方论坛,用户都是本地人,IP都是相似的很正常。
中国电信的IP段,也就那几个。

stop

论坛徽章:
0
63 [报告]
发表于 2005-11-10 12:03 |只看该作者
原帖由 wuruichang 于 2005-11-10 11:51 发表
你说的“59.3.txt也会有6w多条记录”难道不是理论数据?

就此中止吧,没必要一定分出胜负。。。



我不知道先查索引然后fseek之后读出几十个字节和打开文件全读入数组再查找哪个更快
你觉得呢

论坛徽章:
0
64 [报告]
发表于 2005-11-10 12:05 |只看该作者
原帖由 北京野狼 于 2005-11-10 11:56 发表


Maildir不是因为单条记录大。
数据库的设计原则只有一条,就是方便查询。
邮件系统的特点是每个人只能看到自己的数据,看不到其他人的,和论坛不一样
大家看一样的。
邮件不采用数据库,是因为
第一数据 ...


是的

论坛徽章:
0
65 [报告]
发表于 2005-11-10 13:29 |只看该作者
找到一个使用纯真版ip数据库的php程序,见http://www.phpx.com/happy/top94143.html
我把它装上了,看这里的测试结果,速度真是快:

  1. 218.000.000.000
  2. 浙江省宁波市电信
  3. 页面生成时间 0.001024 秒
复制代码


直接访问显示浏览器的IP:
http://www.dvhome.org/ip/ip.php

加ip=xxx.xxx.xxx.xxx显示查询的ip的地址,如:
http://www.dvhome.org/ip/ip.php?ip=218.000.000.000

补充一下,这个数据库是从网上下载的,资料:

  1. QQ IP数据库 纯真版1020

  2. IP数据记录:235084条
  3. 数据库大小:4.6M
复制代码

[ 本帖最后由 qingmedia 于 2005-11-10 13:31 编辑 ]

论坛徽章:
0
66 [报告]
发表于 2005-11-10 13:37 |只看该作者
付上上面测试页面的代码:


  1. <?php
  2. ob_start();
  3. $tstart = getmicrotime();

  4. define('QQWRY' , 'QQWry.dat' ) ;

  5. function getmicrotime(){
  6.    list($usec, $sec) = explode(" ",microtime());
  7.    return ((float)$usec + (float)$sec);
  8. }


  9. function IpToInt($Ip) {
  10.     $array=explode('.',$Ip);
  11.     $Int=($array[0] * 256*256*256) + ($array[1]*256*256) + ($array[2]*256) + $array[3];
  12.     return $Int;
  13. }

  14. function IntToIp($Int) {
  15.     $b1=($Int & 0xff000000)>>24;
  16.     if ($b1<0) $b1+=0x100;
  17.     $b2=($Int & 0x00ff0000)>>16;
  18.     if ($b2<0) $b2+=0x100;
  19.     $b3=($Int & 0x0000ff00)>>8;
  20.     if ($b3<0) $b3+=0x100;
  21.     $b4= $Int & 0x000000ff;
  22.     if ($b4<0) $b4+=0x100;
  23.     $Ip=$b1.'.'.$b2.'.'.$b3.'.'.$b4;
  24.     return $Ip;
  25. }

  26. class TQQwry
  27. {
  28.     var $StartIP = 0;
  29.     var $EndIP   = 0;
  30.     var $Country = '';
  31.     var $Local   = '';
  32.     var $CountryFlag = 0; // 标识 Country位置

  33.                           // 0x01,随后3字节为Country偏移,没有Local
  34.                           // 0x02,随后3字节为Country偏移,接着是Local
  35.                           // 其他,Country,Local,Local有类似的压缩。可能多重引用。
  36.     var $fp;
  37.     var $FirstStartIp = 0;
  38.     var $LastStartIp = 0;
  39.     var $EndIpOff = 0 ;

  40.     function getStartIp ( $RecNo ) {
  41.         $offset = $this->FirstStartIp + $RecNo * 7 ;
  42.         @fseek ( $this->fp , $offset , SEEK_SET ) ;
  43.         $buf = fread ( $this->fp , 7 ) ;
  44.         $this->EndIpOff = ord($buf[4]) + (ord($buf[5])*256) + (ord($buf[6])* 256*256);
  45.         $this->StartIp = ord($buf[0]) + (ord($buf[1])*256) + (ord($buf[2])*256*256) + (ord($buf[3])*256*256*256);
  46.         return $this->StartIp ;
  47.     }

  48.     function getEndIp ( ) {
  49.         @fseek ( $this->fp , $this->EndIpOff , SEEK_SET ) ;
  50.         $buf = fread ( $this->fp , 5 ) ;
  51.         $this->EndIp = ord($buf[0]) + (ord($buf[1])*256) + (ord($buf[2])*256*256) + (ord($buf[3])*256*256*256);
  52.         $this->CountryFlag = ord ( $buf[4] ) ;
  53.         return $this->EndIp ;
  54.     }

  55.     function getCountry ( ) {
  56.         switch ( $this->CountryFlag ) {
  57.             case 1:
  58.             case 2:
  59.                 $this->Country = $this->getFlagStr ( $this->EndIpOff+4) ;
  60.                 //echo sprintf('EndIpOffset=(%x)',$this->EndIpOff );
  61.                 $this->Local = ( 1 == $this->CountryFlag )? '' : $this->getFlagStr ( $this->EndIpOff+8);
  62.                 break ;
  63.             default :
  64.                 $this->Country = $this->getFlagStr ($this->EndIpOff+4) ;
  65.                 $this->Local =   $this->getFlagStr ( ftell ( $this->fp )) ;
  66.         }
  67.     }

  68.     function getFlagStr ( $offset )
  69.     {
  70.         $flag = 0 ;
  71.         while ( 1 ){
  72.             @fseek ( $this->fp , $offset , SEEK_SET ) ;
  73.             $flag = ord ( fgetc ( $this->fp ) ) ;
  74.             if ( $flag == 1 || $flag == 2 ) {
  75.                 $buf = fread ($this->fp , 3 ) ;
  76.                 if ($flag == 2 ){
  77.                     $this->CountryFlag = 2 ;
  78.                     $this->EndIpOff = $offset - 4 ;
  79.                 }
  80.                 $offset = ord($buf[0]) + (ord($buf[1])*256) + (ord($buf[2])* 256*256);
  81.             }else{
  82.                 break ;
  83.             }
  84.         }
  85.         if ( $offset < 12 )
  86.             return '';
  87.         @fseek($this->fp , $offset , SEEK_SET ) ;
  88.         return $this->getStr();
  89.     }

  90.     function getStr ( )
  91.     {
  92.         $str = '' ;
  93.         while ( 1 ) {
  94.             $c = fgetc ( $this->fp ) ;
  95.             if ( ord ( $c[0] ) == 0  )
  96.                break ;
  97.             $str .= $c ;
  98.         }
  99.         return $str ;
  100.     }

  101.     function qqwry ($dotip) {
  102.         $nRet=0;
  103.         $ip = IpToInt ( $dotip );
  104.         $this->fp= @fopen(QQWRY, "rb");
  105.         if ($this->fp == NULL) {
  106.               $szLocal= "OpenFileError";
  107.             return 1;
  108.           }
  109.           @fseek ( $this->fp , 0 , SEEK_SET ) ;
  110.         $buf = fread ( $this->fp , 8 ) ;
  111.         $this->FirstStartIp = ord($buf[0]) + (ord($buf[1])*256) + (ord($buf[2])*256*256) + (ord($buf[3])*256*256*256);
  112.         $this->LastStartIp  = ord($buf[4]) + (ord($buf[5])*256) + (ord($buf[6])*256*256) + (ord($buf[7])*256*256*256);
  113.         $RecordCount= floor( ( $this->LastStartIp - $this->FirstStartIp ) / 7);
  114.         if ($RecordCount <= 1){
  115.             $this->Country = "FileDataError";
  116.             fclose ( $this->fp ) ;
  117.             return 2 ;
  118.         }

  119.           $RangB= 0;
  120.         $RangE= $RecordCount;
  121.         // Match ...
  122.         while ($RangB < $RangE-1)
  123.         {
  124.           $RecNo= floor(($RangB + $RangE) / 2);
  125.           $this->getStartIp ( $RecNo ) ;

  126.             if ( $ip == $this->StartIp )
  127.             {
  128.                 $RangB = $RecNo ;
  129.                 break ;
  130.             }
  131.           if ( $ip > $this->StartIp)
  132.             $RangB= $RecNo;
  133.           else
  134.             $RangE= $RecNo;
  135.         }
  136.         $this->getStartIp ( $RangB ) ;
  137.         $this->getEndIp ( ) ;
  138.         if ( ( $this->StartIp  <= $ip ) && ( $this->EndIp >= $ip ) ){
  139.             $nRet = 0 ;
  140.             $this->getCountry ( ) ;
  141.             $this->Local = str_replace("(something to say)", "", $this->Local);
  142.        }else {
  143.             $nRet = 3 ;
  144.             $this->Country = '未知' ;
  145.             $this->Local = '' ;
  146.         }
  147.         fclose ($this->fp) ;
  148.         return $nRet ;
  149.     }
  150. }

  151. function ip2location ( $ip )
  152. {
  153.     $wry = new TQQwry;
  154.    $nRet = $wry->qqwry ($ip);
  155.    return $wry->Country.$wry->Local;
  156. }

  157. // Test Code.
  158. //$_SERVER['REMOTE_ADDR'];

  159. //  $ipa= $_SERVER['REMOTE_ADDR'] ;

  160. //  $ipa= "61.144.133.26";

  161. if (!isset($_GET['ip'])){
  162.         $_GET['ip']= $_SERVER['REMOTE_ADDR'];
  163. }

  164. $ipa = $_GET['ip'];
  165. ?>

  166. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional/EN">
  167. <html>
  168.   <head>
  169.     <title>Untitled</title>
  170.     <meta http-equiv="content-type" content="text/html; charset=gb2312">
  171.     <meta name="generator" content="syn">
  172.   </head>
  173.   <body>
  174. <?php

  175.   echo $ipa."<br />";
  176.   echo ip2location($ipa);

  177. //---------------------------------------------------------------------------
  178.         $tend = getmicrotime();
  179.         $totaltime = ($tend - $tstart);
  180.         ob_end_flush();
  181.         printf ("<br />页面生成时间 %f 秒", $totaltime);
  182. ?>
  183.   </body>
  184. </html>
复制代码

论坛徽章:
0
67 [报告]
发表于 2005-11-10 14:39 |只看该作者
是的
在 p4 2.8的机器上,用c写的可以达到每秒百万次查询
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP