首頁 > 學院 > 綜合知識 > 正文

IP地址定位區間的問題解析

2022-07-27 22:23:23
字體:
來源:轉載
供稿:網友
           以前寫過一篇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) 有了這些鋪墊,結合索引信息,實現這個需求問題 不大。

(編輯:錯新網)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
金玫玫床戏