欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談MySQL中用什么數(shù)據(jù)類型存IP地址

 更新時(shí)間:2023年08月14日 12:07:54   作者:y_bccl27  
MySQL中用什么數(shù)據(jù)類型存IP地址?在MySQL中,當(dāng)存儲IPv4地址時(shí),應(yīng)該使用32位的無符號整數(shù)來存儲IP地址,而不是使用字符串,本文就介紹一下這幾種情況,感興趣的可以了解一下

提到IP地址(IPv4),我們腦子里肯定立馬浮現(xiàn)類似于192.168.0.1、127.0.0.1這種常見的IP地址,然后結(jié)合這個(gè)問題“MySQL中用什么數(shù)據(jù)類型存IP地址?”,于是乎脫口而出用char字符串類型存儲。

然后再仔細(xì)想想發(fā)現(xiàn),這個(gè)IP地址的長度是變化的,最短可以是0.0.0.0只需要 7 位,最長可以是255.255.255.255需要15位,于是自信地回答使用varchar(15)來存儲 IP 地址,并為自己能夠想到這一層而暗自竊喜。

人們經(jīng)常使用varchar(15)列來存儲 IP 地址,但事實(shí)上這并不是最優(yōu)解。

IP地址的本質(zhì)是32位無符號整數(shù),類似于192.168.0.1這種點(diǎn)分十進(jìn)制的字符串寫法只是為了幫助人們理解和記憶,192.168.0.1對應(yīng)的十進(jìn)制表示是無符號整數(shù)3232235521。

所以說用字符串類型存IP 地址的,其實(shí)是潛意識中以為IP地址是字符串。實(shí)際存的是點(diǎn)分十進(jìn)制的字符串,但正確的應(yīng)該是存32位的無符號整數(shù)。

所謂有符號數(shù)其實(shí)就是將最高位作為符號位,比如32位的有符號int類型,最高位是符號位,剩下 31位才是真實(shí)的數(shù)值,所以有符號int類型的取值區(qū)間為:

[-2^31,2^3-1]

無符號int類型的取值區(qū)間為:

[0,2^32]

下表列出了MySQL中各個(gè)整數(shù)類型有符號和無符號的的取值范圍,在定義表時(shí),可以在數(shù)據(jù)類型后面添加關(guān)鍵字 UNSIGNED 來定義無符號整數(shù),否則默認(rèn)為有符號整數(shù): 

特別說明:ASCII碼中,1個(gè)漢字字符存儲需要2個(gè)字節(jié),1個(gè)英文字符存儲需要1個(gè)字節(jié)。

結(jié)合上表,可以看出32位的無符號 int類型正好可以容納 IPv4 地址,下面是 INT UNSIGNED 和 VARCHAR(15) 兩種數(shù)據(jù)類型的對比:

  • 存儲空間: 4 字節(jié)的int類型比15字節(jié)的varchar(15)更加節(jié)省存儲空間。另外varchar除了會保存需要的字符,還會另加一個(gè)字節(jié)來記錄長度(如果列聲明的長度超過255,則使用兩個(gè)字節(jié)記錄長度),所以varchar(15)其實(shí)要占用 16 個(gè)字節(jié)。
  • 檢索速度:如果我們要在 IP 地址上建立索引,那么對于字符串索引來說,整數(shù)索引的檢索速度簡直就是降緯打擊了,因?yàn)樽址愋偷谋容^是需要從第一位字符開始遍歷依次進(jìn)行的,速度較慢。

MySQL非常貼心地提供了IPv4地址點(diǎn)分十進(jìn)制和無符號整數(shù)的相互轉(zhuǎn)換函數(shù),inet_aton和 inet_ntoa(底層是二進(jìn)制移位操作,速度很快)。

點(diǎn)分十進(jìn)制 -> 十進(jìn)制

SELECT INET_ATON('192.168.0.1');

十進(jìn)制 -> 點(diǎn)分十進(jìn)制

SELECT INET_NTOA('3232235521');

當(dāng)然我們更應(yīng)該在業(yè)務(wù)中去執(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)文章

最新評論