MySQL存儲(chǔ)IP地址的方法
為什么要問(wèn)如何存儲(chǔ)IP?
首先就來(lái)闡明一下部分人得反問(wèn):為什么要問(wèn)IP得怎樣存,直接varchar類(lèi)型不就得了嗎?
其實(shí)做任何程序設(shè)計(jì)都要在功能實(shí)現(xiàn)的基礎(chǔ)上最大限度的優(yōu)化性能。而數(shù)據(jù)庫(kù)設(shè)計(jì)是程序設(shè)計(jì)中不可忽略的一個(gè)重要部分,所以巧存IP地址可以一定程度獲得很大提升。
利用函數(shù)算法處理
在MySQL中沒(méi)有直接提供IP類(lèi)型字段,但如果有兩個(gè)函數(shù)可以把IP與最大長(zhǎng)度為10位數(shù)字類(lèi)型互轉(zhuǎn),所以使用int類(lèi)型存儲(chǔ)IP比varchar類(lèi)型存儲(chǔ)IP地址性能要提升很多,減少不少空間。因?yàn)関archar是可變長(zhǎng)形,需要多余的一個(gè)字節(jié)存儲(chǔ)長(zhǎng)度。另外int型在邏輯運(yùn)算上要比varchar速度快。
IP轉(zhuǎn)數(shù)字函數(shù)inet_aton()
我們轉(zhuǎn)換下幾個(gè)常用的IP地址
mysql> select inet_aton('255.255.255.255'); +------------------------------+ | inet_aton('255.255.255.255') | +------------------------------+ | 4294967295 | +------------------------------+ 1 row in set (0.00 sec) mysql> select inet_aton('192.168.1.1'); +--------------------------+ | inet_aton('192.168.1.1') | +--------------------------+ | 3232235777 | +--------------------------+ 1 row in set (0.00 sec) mysql> select inet_aton('10.10.10.10'); +--------------------------+ | inet_aton('10.10.10.10') | +--------------------------+ | 168430090 | +--------------------------+ 1 row in set (0.00 sec)
所以IP的表字段可以設(shè)置為INT(10)就好,如果IP獲取不到可以直接存0代表獲取不到IP的意思
數(shù)字轉(zhuǎn)IP函數(shù)inet_ntoa()
mysql> select inet_ntoa(4294967295); +-----------------------+ | inet_ntoa(4294967295) | +-----------------------+ | 255.255.255.255 | +-----------------------+ 1 row in set (0.00 sec) mysql> select inet_ntoa(3232235777); +-----------------------+ | inet_ntoa(3232235777) | +-----------------------+ | 192.168.1.1 | +-----------------------+ 1 row in set (0.00 sec) mysql> select inet_ntoa(168430090); +----------------------+ | inet_ntoa(168430090) | +----------------------+ | 10.10.10.10 | +----------------------+ 1 row in set (0.00 sec) mysql> select inet_ntoa(0); +--------------+ | inet_ntoa(0) | +--------------+ | 0.0.0.0 | +--------------+ 1 row in set (0.00 sec)
注意,0轉(zhuǎn)換為 0.0.0.0
整型字段的比較比字符串效率高很多,這也符合一項(xiàng)優(yōu)化原則:字段類(lèi)型定義使用最合適(最?。詈?jiǎn)單的數(shù)據(jù)類(lèi)型。
inet_aton()算法,其實(shí)借用了國(guó)際上對(duì)各國(guó)IP地址的區(qū)分中使用的ip number。
a.b.c.d 的ip number是:
a * 256的3次方 + b * 256的2次方 + c * 256的1次方 + d * 256的0次方。
mysql 存儲(chǔ)ip地址
mysql提供了兩個(gè)方法來(lái)處理ip地址:
inet_aton 把ip轉(zhuǎn)為無(wú)符號(hào)整型(4-8位)
inet_ntoa 把整型的ip轉(zhuǎn)為電地址
插入數(shù)據(jù)前,先用inet_aton把ip地址轉(zhuǎn)為整型,可以節(jié)省空間。
顯示數(shù)據(jù)時(shí),使用inet_ntoa把整型的ip地址轉(zhuǎn)為電地址顯示即可。為社么這樣存?,性能上的提示比直接存儲(chǔ)字符串的IP要高出很多。
示例:
CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(15) DEFAULT NULL COMMENT '用戶(hù)名', `ip` bigint(20) DEFAULT NULL COMMENT 'IP地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
插入幾條數(shù)據(jù):
INSERT INTO `t_user` ( `id`, `name`, `ip` ) VALUES ( 2, 'babala', inet_aton( '127.0.0.1' ) ), ( 3, 'maly', inet_aton( '192.168.1.1' ) ), ( 4, 'kaven', inet_aton( '111.175.7.143' ) );
查詢(xún)顯示地址:
select id,name,inet_ntoa(ip) as ip from `t_user`;
如果需要找出在某個(gè)網(wǎng)段的用戶(hù)(例如:192.168.1.1 ~ 192.168.1.100),可以利用php的ip2long方法,把ip地址轉(zhuǎn)為整型,再進(jìn)行比較。
$ip_start = '192.168.1.1'; $ip_end = '192.168.1.100'; echo sprintf('%u',ip2long($ip_start)).PHP_EOL; // 3232235777 echo sprintf('%u',ip2long($ip_end)).PHP_EOL; // 3232235876
總結(jié)
1.保存ip地址到數(shù)據(jù)庫(kù),使用unsigned int格式,插入時(shí)使用inet_aton方法把ip先轉(zhuǎn)為無(wú)符號(hào)整型,可以節(jié)省存儲(chǔ)空間。
2.顯示時(shí)使用inet_ntoa把整型ip地址轉(zhuǎn)為電地址。
3.php 使用 ip2long轉(zhuǎn)ip為整型時(shí),需要注意出現(xiàn)負(fù)數(shù)的問(wèn)題(如果出現(xiàn)負(fù)數(shù):參照之前我寫(xiě)的這篇)
以上講解的就是MySQL存儲(chǔ)IP地址的方法,希望能夠?qū)Υ蠹业膶W(xué)習(xí)有所幫助。
相關(guān)文章
MySQL數(shù)據(jù)庫(kù)實(shí)驗(yàn)之?觸發(fā)器和存儲(chǔ)過(guò)程
這篇文章主要介紹了MySQL數(shù)據(jù)庫(kù)實(shí)驗(yàn)之?觸發(fā)器和存儲(chǔ)過(guò)程,通過(guò)掌握某主流DBMS支持的SQL編程語(yǔ)言和編程規(guī)范,規(guī)范設(shè)計(jì)存儲(chǔ)過(guò)程展開(kāi)詳細(xì)介紹,感興趣的朋友可以參考一下2022-06-06MySQL中ON DUPLICATE key update的使用
本文主要介紹了MySQL中ON DUPLICATE key update的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05

MySQL與PHP的基礎(chǔ)與應(yīng)用專(zhuān)題之創(chuàng)建數(shù)據(jù)庫(kù)表

mysql too many open connections問(wèn)題解決方法

windows下安裝mysql8.0.18的教程(社區(qū)版)