在看到高性能MySQL第3版(4.1.7节)时,创作者推荐当存储IPv4地址时,应当运用32位的无符号整数(UNSIGNEDINT)来存储IP地址,而非采用字符串。但没提供原因有哪些。为了能弄清楚这些原因,查了相关的资料,整理出来。
MySQL如何存储ip地址字段?

比较字符串存储,应用无符号整数来存储主要有以下的优点:

节省空间,无论是数据存储空间,或是索引存储空间
有利于使用范围查询(BETWEEN…AND),且更有效率

一般来说,在保存IPv4地址时,一个IPv4最少需要7个字符,最大要15个字符,所以,使用VARCHAR(15)即可。MySQL在保存变长的字符串时,还需要额外的一个字节来保存此字符串长度。而如果使用无符号整数来存储,只需要4个字节就可以了。

同时还可以用4个字段分别存储IPv4中的各部分,但是一般而言这不管是存储空间和查询效率应该都不是很高(可能有些场景适合应用这种方法存储)。

使用无符号整数来存储也是有缺点:

不方便阅读
必须手动转化

对于转换来说,MySQL给予了相应的函数来将字符串格式的IP转变成整数INET_ATON,以及把整数格式的IP转换成字符串的INET_NTOA。如下所示:

MySQL>selectinet_aton('192.168.0.1');
+--------------------------+
|inet_aton('192.168.0.1')|
+--------------------------+
|3232235521|
+--------------------------+
1rowinset(0.00sec)
MySQL>selectinet_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@returnIP对应的long值/ publicstaticlongip2Long(StringipStr){ String[]ip=ipStr.split("\."); return(Long.valueOf(ip[0]) +(Long.valueOf(ip[2]) } /把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);
returnip.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"));
}
}

输出结果为:

3232235521
192.168.0.1
167772161

以上就是MySQL如何存储ip地址字段的介绍,希望对大家有帮助。

本文由《MySql教程网》原创,转载请注明出处!https://mysql360.com