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。可惜的是,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地址相关推荐
- mysql ip v4 v6_mysql IPv4 IPv6
w如何通过一个mysql方法,而不是借助脚本判断?INET6_ATON(expr) https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-func ...
- IPv4/IPv6地址范围与网络地址/子网掩码的转换,点分十进制与数字掩码的转换
private static final int IPV4BYTES = 4; // IPv4字节数为4 private static final int BYTEBITS = 8; // 每个字节的 ...
- windows下使用cmd命令设置静态IPv4 IPv6地址
cmd命令设置静态IPv4地址 netsh interface ip set address 网卡名称 static 静态IP 子网掩码 默认网关 1 例如: netsh interface ip s ...
- 组播MAC/IPv4/IPv6地址
IPV4组播地址 分类 地址范围 含义 永久组播地址 224.0.0.0–224.0.0.255 永久组播地址(为特定协议分配) 224.0.0.1 网段内所有主机和路由器(等效于广播地址) 224. ...
- Redis 根据IPv6地址查询全球国家、省、市位置信息方案
1. 浏览器下载ipv6地址库.https://lite.ip2location.com/download?id=13 2. 解压 [yeqiang@localhost Downloads]$ unz ...
- mysql ipv6 字段_MySQL中ipv6地址用什么类型存储?
ipv6逐渐普及了,我们的服务要支持用户通过ipv6和iPv4地址请求,存储用户来源IP势在必行. pgsql中有ip地址类型,mysql没有. mysql提供的方案是用二进制存储用函数做转换为人可读 ...
- mysql inet aton ipv6_在MySQL中存储IPv6地址
要存储的格式. 使用相当复杂的IPv6 IP地址查询示例INSERT. 示例SELECT查询您将能够echo将IPv6 IP地址返回给客户端. 排除故障以确保您没有错过任何遗留代码. 醇> 我将 ...
- mysql ipv6转整型_php实现ipv6地址转换成数字INT类型存储数据库中
Loading... IPV4的地址,我们可以通过ip2long将IP地址转换为INT类型,通过long2ip函数将INT转换为IP地址 $ip = $_SERVER['REMOTE_ADDR']; ...
- MySQL如何有效的存储IP地址
文章目录 序言 工具类实现转换 数据库函数实现转换 一.IP地址应该怎么存 二.整数存储 IP 地址的查询性能实验 1.测试范围查询: 2.IP精确查询: 3.整理一下结果发现: 总结 首先就来阐明一 ...
最新文章
- weblogic域,管理服务器,受管服务器,集群和机器的基本知识
- Nginx负载均衡之TCP端口高可用(二)
- 安利Mastodon:属于未来的社交网络
- 8. String to Integer
- 众望所归的《JAVASCRIPT凌厉开发--EXT详解与实践 》终于上市了!
- Access结合aspnetpager分页
- 推荐一本学习Groovy的书籍Groovy程序设计!
- 5年了...Capstone 终于升级到4.0!
- php常用函数及其用法,实例分析Fleaphp常见函数功能与用法
- 专家称摩尔定律将于2022年失效
- B站视频音频合并(FFmpeg)
- 关于一台电脑安装多个jdk后使用时如何切换
- 主梁弹性模量计算_各排立杆传至梁上荷载标准值、设计值是那一个数据
- socket编程到底是什么
- 【MOD】函数判别性别
- python-华三防火墙netconf编写移动策略
- 别再问什么是数据库分库分表了,看这里!
- python漫画爬虫:我不做人了,b站!爬取辉夜大小姐等漫画
- 罗丹明RB/四甲基罗丹明标记肌醇六磷酸/植酸,Phytic Acid, Rhodamine B/TRITC labeled;Rhodamine B/TRITC-Phytic Acid
- Matlab 2014a安装文件下载、安装教程及破解教程!!!