日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql如何高效存储IPv4、IPv6地址

發布時間:2024/3/13 数据库 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql如何高效存储IPv4、IPv6地址 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 一、IPv4簡介 + 高效存儲
  • 二、 IPv6簡介 + 高效存儲(兼容IPv4)
  • 三、引用:

一、IPv4簡介 + 高效存儲

IPv4百度百科,簡單地來說IPv4地址是一個4字節的無符號整數。為了方便人類閱讀和分析,IPv4通常被寫作點分十進制的形式,即四個字節被分開用十進制寫出,中間用點分隔。所以如何存儲IPv4,在腦海中想到的第一個答案是用varchar也是很自然的事情。但是使用varchar要使用的字節數是3*4+3+1 = 16,其中1指的是varchar需要一個字節保存長度(varchar的長度小于等于255時,需要一個字節保存長度)。使用int是4個字節,使用varcahr是16個字節。在《高性能MySQL 第三版》中,關于字段的設計原則有:在夠用的前提下,字節能省則省。所以用無符號的int存儲IPv4是最好的選擇。
如何使用int類型存取IPv4?
登錄日志表 login_log(MySQL5.6+):

CREATE TABLE `login_log` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵id',`user_id` bigint(20) NOT NULL COMMENT '用戶id',`times` tinyint(3) unsigned NOT NULL COMMENT '登錄次數',`login_time` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000' ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '登錄時間,精確到微秒',`update_time` datetime(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000' ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '數據更新日期,精確到微秒,數據庫自動維護',`ipv4` int(10) unsigned DEFAULT NULL COMMENT 'ipv4地址 int類型',`ipv4_string` varchar(16) DEFAULT NULL COMMENT 'ipv4地址 varchar類型',`ip` varbinary(16) DEFAULT NULL COMMENT 'ip地址,兼容ipv4和ipv6',PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

插入一條記錄:

INSERT INTO login_log(user_id, times, ipv4, ipv4_string) VALUES(1, 1 ,INET_ATON("192.168.1.5"), "192.168.1.5");

查詢記錄:

SELECT *, INET_NTOA(ipv4) FROM login_log ; +----+---------+-------+----------------------------+----------------------------+------------+-------------+------+-----------------+ | id | user_id | times | login_time | update_time | ipv4 | ipv4_string | ip | INET_NTOA(ipv4) | +----+---------+-------+----------------------------+----------------------------+------------+-------------+------+-----------------+ | 1 | 1 | 1 | 0000-00-00 00:00:00.000000 | 0000-00-00 00:00:00.000000 | 3232235781 | 192.168.1.5 | NULL | 192.168.1.5 | +----+---------+-------+----------------------------+----------------------------+------------+-------------+------+-----------------+

INET_ATON() 將IPv4的字符串地址轉換成數值,
INET_NTOA() 將IPv4的數值轉換成字符串地址。

二、 IPv6簡介 + 高效存儲(兼容IPv4)

至此,我們高效地存儲了IPv4。但是,不幸的是IPv4地址(約43億個)已經用完了。所以,現在很多網址使用IPv6(百度百科)。簡單地來說,IPv6是一個16字節的整數。如何高效存儲IPv6這個16字節的整數?當然,我們可以套用上面存儲IPv4的思路,使用16字節的整數存儲IPv6??上У氖?#xff0c;MySQL不支持16字節的整數(最大為8字節的bigint類型),所以無法使用整數存儲IPv6。那么,這時候varchar似乎又成了首選答案,但真的應該使用varchar嗎?不妨讓我們先看看IPv6的三種常見的表示方式。
一、冒分十六進制表示法
格式為X:X:X:X:X:X:X:X,其中每個X表示地址中的16b,以十六進制表示,例如:ABCD:EF01:2345:6789:ABCD:EF01:2345:6789這種表示法中,每個X的前導0是可以省略的,例如:
2001:0DB8:0000:0023:0008:0800:200C:417A→2001:DB8:0:23:8:800:200C:417A
二、0位壓縮表示法
在某些情況下,一個IPv6地址中間可能包含很長的一段0,可以把連續的一段0壓縮為“::”。但為保證地址解析的唯一性,地址中”::”只能出現一次,例如:FF01:0:0:0:0:0:0:1101 → FF01::1101,0:0:0:0:0:0:0:1 → ::1,0:0:0:0:0:0:0:0 → ::
三、內嵌IPv4地址表示法
為了實現IPv4-IPv6互通,IPv4地址會嵌入IPv6地址中,此時地址常表示為:X:X:X:X:X:X:d.d.d.d,前96b采用冒分十六進制表示,而最后32b地址則使用IPv4的點分十進制表示,例如::192.168.0.1與::FFFF:192.168.0.1就是兩個典型的例子,注意在前96b中,壓縮0位的方法依舊適用。
如果使用varchar類型保存IPv6的話,那么在存儲以冒分十六進制表示的IPv6時,就需要39 + 1 = 40 個字節。可IPv6本質上一個16字節的數字,難道真的沒有其它辦法了嗎?在《高性能MySQL 第三版》中有句話“與CHAR和VARCHAR類似的類型還有BINARY和VARBINARY,它們存儲的是二進制字符串。二進制字符串和常規字符串非常相似,但是二進制字符串存儲的是字節碼而不是字符。”同時,要注意到VARBINARY(m),其中m表示字節數。這樣我們可以使用VARBINARY(16)存儲IPv6地址,并且兼容存儲IPv4地址。
插入用三種不同方式表示IPv6地址的記錄:

INSERT INTO login_log(user_id, times, ip) VALUES(1, 2, inet6_aton("2001:db8:85a3:8d3:1319:8a2e:370:7348")); INSERT INTO login_log(user_id, times, ip) VALUES(1, 3, inet6_aton("fe80::3579:5807:93af:a2ce")); INSERT INTO login_log(user_id, times, ip) VALUES(1, 4, inet6_aton("::192.168.0.1"));

查詢記錄:

SELECT *, INET6_NTOA(ip) FROM login_log ;


INET6_ATON() 將IPv6的字符串地址轉換成數值(MySQL5.6+),
INET6_NTOA() 將IPv6的數值轉換成字符串地址(MySQL5.6+)。

三、引用:

  • MySQL官網
  • StackOverflow
  • IPv6百度百科
  • 《高性能MySQL 第三版》

總結

以上是生活随笔為你收集整理的mysql如何高效存储IPv4、IPv6地址的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。