当前位置: 首页 > 后端技术 > Java

面试官:如果要保存IP地址,哪种数据类型比较好?

时间:2023-04-01 14:12:18 Java

在查看高性能MySQL版本3(第4.1.7节)时,作者建议在存储IPv4地址时,应该使用32位无符号整数(UNSIGNEDINT)来存储IP地址而不是字符串。但没有给出具体原因。为了查明原因,查了一些资料记录一下。与字符串存储相比,使用无符号整数存储有以下优点:节省空间,无论是数据存储空间还是索引存储空间,使用范围查询(BETWEEN...AND)都方便,效率更高。一般在保存IPv4地址时,一个IPv4要求最少7个字符,最多15个字符,所以使用VARCHAR(15)即可。MySQL在保存变长字符串时,需要额外的一个字节来保存字符串的长度。而如果使用无符号整数来存储,只需要4个字节。另外也可以用4个字段分别存储IPv4的每一部分,但通常这样在存储空间和查询效率上应该不会很高(可能有一些场景适合这种方式存储)。另外,MySQL系列面试题和答案都整理好了。微信搜索Java技术栈,后台发送:面试,网上可以看。关于使用字符串和无符号整数存储IP的具体性能分析和基准测试,可以阅读这篇文章。https://bafford.com/2009/03/0...使用无符号整数存储也有缺点:不易读取,需要手动转换。对于转换,MySQL提供了相应的函数将IP转换成字符串格式的IntegerINET_ATON,以及INET_NTOA将整数格式的IP转换成字符串。如下:mysql>selectinet_aton('192.168.0.1');+------------------------+|inet_aton('192.168.0.1')|+------------------------+|3232235521|+----------------------+1行在集合中(0.00秒)mysql>选择inet_ntoa(3232235521);+---------------------+|inet_ntoa(3232235521)|+--------------------+|192.168.0.1|+----------------------+1rowinset(0.00sec)对于IPv6,使用VARBINARY也可以获得相同的好处,并且MySQL也提供了相应的转换函数,即INET6_ATON和INET6_NTOA。对于字符串IPv4和数值类型的转换,可以放在应用层。下面是使用java代码将两者进行转换:packagecom.mikan;/***@authorMikan*/publicclassIpLongUtils{/***把字符转换成字符串IP为long**@paramipStr字符串IP*@returnlong对应IP的值*/publicstaticlongip2Long(StringipStr){String[]ip=ipStr.split("\\.");返回(Long.valueOf(ip[0])<<24)+(Long.valueOf(ip[1])<<16)+(Long.valueOf(ip[2])<<8)+Long.valueOf(ip[3]);}/***将IP的long值转成字符串**@paramipLongIP的long值*@returnlong值对应的字符串*/publicstaticStringlong2Ip(longipLong){StringBuilderip=newStringBuilder();ip.append(ipLong>>>24).append(".");ip.append((ipLong>>>16)&0xFF).append(".");ip.append((ipLong>>>8)&0xFF).append(".");ip.append(ipLong&0xFF);返回ip.toString();}publicstaticvoidmain(String[]args){System.out。println(ip2Long("192.168.0.1"));System.out.println(long2Ip(3232235521L));System.out.println(ip2Long("10.0.0.1"));}}输出结果为:3232235521192.168.0.1167772161最后关注公众号Java技术栈,后台回复:面试,可以拿到我整理的Java系列面试题及答案,很全