首页 > 课堂 > 基础知识 > 正文

IP地址定位区间的问题解析

2024-09-12 20:29:55
字体:
来源:转载
供稿:网友
           以前写过一篇Oracle中关于IP地址定位的问题分析,最后引申出了一系列的问题。当时问题紧急严峻,抓取了10053事件定位源头,想出了一个解决妙法,还自鸣得意了下,结果忙活完之后看看行业里的解决方案都大体如此,我的心凉了半截。
 
          我总是希望找到一些与众不同的点来解读这一类问题,结果在偶然的一天从MySQL这里找到了一些思路。
 
          我先来分析下之前问题和一些收获。
 
   问题就交代到这里,我今天想再次讨论这个问题是想从几个基础的问题开始来聊聊MySQL在这方面的优势,没错,是相比于Oracle的优势的地方。
 
    首先我们来说说表结构的设计,如果在Oracle里面,当时设计的地址信息如下:
 
COLUMN_ID COLUMN_NAME                    DATA_TYPE       DATA_LENGTH NULLABLE  
---------- ------------------------------ --------------- ----------- ----------
         1 IP_ID                          NUMBER(10,0)             22 N
         2 IP_LEFT_LINE                   VARCHAR2(15)             15 N
         3 IP_RIGHT_LINE                  VARCHAR2(15)             15 N
         4 IP2NUM_LEFT_LINE               NUMBER(10,0)             22 N
         5 IP2NUM_RIGHT_LINE              NUMBER(10,0)             22 N
         6 COUNTRY                        VARCHAR2(20)             20 Y
         7 PROVINCE                       VARCHAR2(20)             20 Y
         8 CAPITAL                        VARCHAR2(20)             20 Y
 
  里面对IP地址和IP地址转换后的数字都做了持久化,查询的逻辑相对就比较别扭了。
 
比如下面:B1是传入的IP地址,即一个字符串,会先转换为数字,然后做Range Scan。
 
SELECT IP_ID,COUNTRY,PROVINCE,CAPITAL
FROM SWD_IP2COUNTY
WHERE STRIPTOINT(:B1 ) BETWEEN IP2NUM_LEFT_LINE AND IP2NUM_RIGHT_LINE
 
   那么问题来了,数值型数据类型其实是很丰富的,这一点和Oracle大大不同,Oracle里面很多开发,DBA都懒了,或者说Oracle内部已经做好了这种适配,数值精度也不需要更多考虑了,长度也不需要区别对待了,直接一个number类型,想调精度,就直接在这个基础上改,比如number(10,3),可以定义长度和精度。MySQL在这方面就分得比较轻,有支持0-128以内的tiny int,32767的smallint等,每一个数据类型都抠的很细。
 
   所以在Oracle里面的豪气在这里就是粗放了,一定需要认真区别对待。
 
   因为我们打算使用数值类型,最后我们选择了int(11),没有留出很富余的值是因为我们从设计的角度来考虑尽可能按需分配。
 
> create table ip_range(ip int(11) );
Query OK, 0 rows affected (0.01 sec)
 
我们插入两行值:
 
> insert into ip_range values(inet_aton('127.0.0.1')),(inet_aton('192.168.1.1'));
ERROR 1264 (22003): Out of range value for column 'ip' at row 2结果发现竟然溢出了,SQL_Mode是严格模式。
 
> insert into ip_range values(inet_aton('192.168.1.1'));
Query OK, 1 row affected (0.00 sec)这里需要提一下,就是对于IP地址的转换,MySQL已经提供了这个转换的方法,可以互相转换。分别是inet_ntoa(数值转为IP),inete_aton(IP转为数值)
 
> select (inet_ntoa(ip)) from ip_range;
+-----------------+
| (inet_ntoa(ip)) |
+-----------------+
| 127.0.0.1       |
| 192.168.1.1     |
+-----------------+
2 rows in set (0.00 sec) 有了这些铺垫,结合索引信息,实现这个需求问题 不大。

(编辑:武林网)

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表