淺談MySQL中用什么數(shù)據(jù)類型存IP地址
提到IP地址(IPv4),我們腦子里肯定立馬浮現(xiàn)類似于192.168.0.1、127.0.0.1這種常見的IP地址,然后結(jié)合這個問題“MySQL中用什么數(shù)據(jù)類型存IP地址?”,于是乎脫口而出用char字符串類型存儲。
然后再仔細想想發(fā)現(xiàn),這個IP地址的長度是變化的,最短可以是0.0.0.0只需要 7 位,最長可以是255.255.255.255需要15位,于是自信地回答使用varchar(15)來存儲 IP 地址,并為自己能夠想到這一層而暗自竊喜。
人們經(jīng)常使用varchar(15)列來存儲 IP 地址,但事實上這并不是最優(yōu)解。
IP地址的本質(zhì)是32位無符號整數(shù),類似于192.168.0.1這種點分十進制的字符串寫法只是為了幫助人們理解和記憶,192.168.0.1對應的十進制表示是無符號整數(shù)3232235521。
所以說用字符串類型存IP 地址的,其實是潛意識中以為IP地址是字符串。實際存的是點分十進制的字符串,但正確的應該是存32位的無符號整數(shù)。
所謂有符號數(shù)其實就是將最高位作為符號位,比如32位的有符號int類型,最高位是符號位,剩下 31位才是真實的數(shù)值,所以有符號int類型的取值區(qū)間為:
[-2^31,2^3-1]
無符號int類型的取值區(qū)間為:
[0,2^32]
下表列出了MySQL中各個整數(shù)類型有符號和無符號的的取值范圍,在定義表時,可以在數(shù)據(jù)類型后面添加關(guān)鍵字 UNSIGNED 來定義無符號整數(shù),否則默認為有符號整數(shù):

特別說明:ASCII碼中,1個漢字字符存儲需要2個字節(jié),1個英文字符存儲需要1個字節(jié)。
結(jié)合上表,可以看出32位的無符號 int類型正好可以容納 IPv4 地址,下面是 INT UNSIGNED 和 VARCHAR(15) 兩種數(shù)據(jù)類型的對比:
- 存儲空間: 4 字節(jié)的int類型比15字節(jié)的varchar(15)更加節(jié)省存儲空間。另外varchar除了會保存需要的字符,還會另加一個字節(jié)來記錄長度(如果列聲明的長度超過255,則使用兩個字節(jié)記錄長度),所以varchar(15)其實要占用 16 個字節(jié)。
檢索速度:如果我們要在 IP 地址上建立索引,那么對于字符串索引來說,整數(shù)索引的檢索速度簡直就是降緯打擊了,因為字符串類型的比較是需要從第一位字符開始遍歷依次進行的,速度較慢。
MySQL非常貼心地提供了IPv4地址點分十進制和無符號整數(shù)的相互轉(zhuǎn)換函數(shù),inet_aton和 inet_ntoa(底層是二進制移位操作,速度很快)。
點分十進制 -> 十進制:
SELECT INET_ATON('192.168.0.1');
十進制 -> 點分十進制:
SELECT INET_NTOA('3232235521');
當然我們更應該在業(yè)務中去執(zhí)行這些轉(zhuǎn)換,減輕 MySQL 的壓力:
public class Demo {
public static void main(String[] args) {
String ipStr = "192.168.0.1";
long ip =ip2int(ipStr);
System.out.println(ip);
}
public static long ip2int(String ip) {
String[] items = ip.split("\\.");
return Long.valueOf(items[0]) << 24 | Long.valueOf(items[1]) << 16 | Long.valueOf(items[2]) << 8 | Long.valueOf(items[3]);
}
public static String int2ip(long ipInt) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append((ipInt >> 24) & 0xFF).append(".");
stringBuilder.append((ipInt >> 16) & 0xFF).append(".");
stringBuilder.append((ipInt >> 8) & 0xFF).append(".");
stringBuilder.append(ipInt & 0xFF);
return stringBuilder.toString();
}
}到此這篇關(guān)于淺談MySQL中用什么數(shù)據(jù)類型存IP地址的文章就介紹到這了,更多相關(guān)MySQL存IP地址內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL數(shù)據(jù)庫遠程訪問權(quán)限如何打開(兩種方法)
本文通過兩種方法給大家介紹MySQL數(shù)據(jù)庫遠程訪問權(quán)限的打開方法,非常不錯,實用性非常高,感興趣的朋友一起看看吧2016-05-05
Navicat導出MySQL數(shù)據(jù)庫表結(jié)構(gòu)到Excel過程
本文介紹了如何將數(shù)據(jù)庫中的表結(jié)構(gòu)導出到Excel文件中,包括使用SQL語句查詢表結(jié)構(gòu)并使用Navicat工具導出到Excel文件的步驟,總結(jié):將數(shù)據(jù)庫表結(jié)構(gòu)導出到Excel文件中,便于后續(xù)使用或存檔2026-01-01

