目录

  • 一、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地址相关推荐

  1. mysql ip v4 v6_mysql IPv4 IPv6

    w如何通过一个mysql方法,而不是借助脚本判断?INET6_ATON(expr) https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-func ...

  2. IPv4/IPv6地址范围与网络地址/子网掩码的转换,点分十进制与数字掩码的转换

    private static final int IPV4BYTES = 4; // IPv4字节数为4 private static final int BYTEBITS = 8; // 每个字节的 ...

  3. windows下使用cmd命令设置静态IPv4 IPv6地址

    cmd命令设置静态IPv4地址 netsh interface ip set address 网卡名称 static 静态IP 子网掩码 默认网关 1 例如: netsh interface ip s ...

  4. 组播MAC/IPv4/IPv6地址

    IPV4组播地址 分类 地址范围 含义 永久组播地址 224.0.0.0–224.0.0.255 永久组播地址(为特定协议分配) 224.0.0.1 网段内所有主机和路由器(等效于广播地址) 224. ...

  5. Redis 根据IPv6地址查询全球国家、省、市位置信息方案

    1. 浏览器下载ipv6地址库.https://lite.ip2location.com/download?id=13 2. 解压 [yeqiang@localhost Downloads]$ unz ...

  6. mysql ipv6 字段_MySQL中ipv6地址用什么类型存储?

    ipv6逐渐普及了,我们的服务要支持用户通过ipv6和iPv4地址请求,存储用户来源IP势在必行. pgsql中有ip地址类型,mysql没有. mysql提供的方案是用二进制存储用函数做转换为人可读 ...

  7. mysql inet aton ipv6_在MySQL中存储IPv6地址

    要存储的格式. 使用相当复杂的IPv6 IP地址查询示例INSERT. 示例SELECT查询您将能够echo将IPv6 IP地址返回给客户端. 排除故障以确保您没有错过任何遗留代码. 醇> 我将 ...

  8. mysql ipv6转整型_php实现ipv6地址转换成数字INT类型存储数据库中

    Loading... IPV4的地址,我们可以通过ip2long将IP地址转换为INT类型,通过long2ip函数将INT转换为IP地址 $ip = $_SERVER['REMOTE_ADDR']; ...

  9. MySQL如何有效的存储IP地址

    文章目录 序言 工具类实现转换 数据库函数实现转换 一.IP地址应该怎么存 二.整数存储 IP 地址的查询性能实验 1.测试范围查询: 2.IP精确查询: 3.整理一下结果发现: 总结 首先就来阐明一 ...

最新文章

  1. weblogic域,管理服务器,受管服务器,集群和机器的基本知识
  2. Nginx负载均衡之TCP端口高可用(二)
  3. 安利Mastodon:属于未来的社交网络
  4. 8. String to Integer
  5. 众望所归的《JAVASCRIPT凌厉开发--EXT详解与实践 》终于上市了!
  6. Access结合aspnetpager分页
  7. 推荐一本学习Groovy的书籍Groovy程序设计!
  8. 5年了...Capstone 终于升级到4.0!
  9. php常用函数及其用法,实例分析Fleaphp常见函数功能与用法
  10. 专家称摩尔定律将于2022年失效
  11. B站视频音频合并(FFmpeg)
  12. 关于一台电脑安装多个jdk后使用时如何切换
  13. 主梁弹性模量计算_各排立杆传至梁上荷载标准值、设计值是那一个数据
  14. socket编程到底是什么
  15. 【MOD】函数判别性别
  16. python-华三防火墙netconf编写移动策略
  17. 别再问什么是数据库分库分表了,看这里!
  18. python漫画爬虫:我不做人了,b站!爬取辉夜大小姐等漫画
  19. 罗丹明RB/四甲基罗丹明标记肌醇六磷酸/植酸,Phytic Acid, Rhodamine B/TRITC labeled;Rhodamine B/TRITC-Phytic Acid
  20. Matlab 2014a安装文件下载、安装教程及破解教程!!!

热门文章

  1. 编程基础——鱼龙混杂来两波
  2. Gitee如何上传整个项目文件夹
  3. jacob为word和excel加水印
  4. github上实用、常用的插件和库
  5. 视频超分修复,让重温经典影片有了新的可能
  6. scrapy使用用Xpath提取深层标签
  7. 20P83 pr预设模板5000种视频转场过渡视觉特效豪华预设包 v2
  8. 启动virtualbox虚拟机显示Attempted to kill the idle task错误
  9. Android仿ios微信左划条目删除、置顶的实现,代码简洁,更容易理解使用
  10. 机器学习和深度学习的区别