Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL存IP地址

浅谈MySQL中用什么数据类型存IP地址

作者:y_bccl27

MySQL中用什么数据类型存IP地址?在MySQL中,当存储IPv4地址时,应该使用32位的无符号整数来存储IP地址,而不是使用字符串,本文就介绍一下这几种情况,感兴趣的可以了解一下

提到IP地址(IPv4),我们脑子里肯定立马浮现类似于192.168.0.1127.0.0.1这种常见的IP地址,然后结合这个问题“MySQL中用什么数据类型存IP地址?”,于是乎脱口而出用char字符串类型存储。

然后再仔细想想发现,这个IP地址的长度是变化的,最短可以是0.0.0.0只需要 7 位,最长可以是255.255.255.255需要15位,于是自信地回答使用varchar(15)来存储 IP 地址,并为自己能够想到这一层而暗自窃喜。

人们经常使用varchar(15)列来存储 IP 地址,但事实上这并不是最优解。

IP地址的本质是32位无符号整数,类似于192.168.0.1这种点分十进制的字符串写法只是为了帮助人们理解和记忆,192.168.0.1对应的十进制表示是无符号整数3232235521。

所以说用字符串类型存IP 地址的,其实是潜意识中以为IP地址是字符串。实际存的是点分十进制的字符串,但正确的应该是存32位的无符号整数。

所谓有符号数其实就是将最高位作为符号位,比如32位的有符号int类型,最高位是符号位,剩下 31位才是真实的数值,所以有符号int类型的取值区间为:

[-2^31,2^3-1]

无符号int类型的取值区间为:

[0,2^32]

下表列出了MySQL中各个整数类型有符号和无符号的的取值范围,在定义表时,可以在数据类型后面添加关键字 UNSIGNED 来定义无符号整数,否则默认为有符号整数: 

特别说明:ASCII码中,1个汉字字符存储需要2个字节,1个英文字符存储需要1个字节。

结合上表,可以看出32位的无符号 int类型正好可以容纳 IPv4 地址,下面是 INT UNSIGNED 和 VARCHAR(15) 两种数据类型的对比:

MySQL非常贴心地提供了IPv4地址点分十进制和无符号整数的相互转换函数,inet_aton和 inet_ntoa(底层是二进制移位操作,速度很快)。

点分十进制 -> 十进制

SELECT INET_ATON('192.168.0.1');

十进制 -> 点分十进制

SELECT INET_NTOA('3232235521');

当然我们更应该在业务中去执行这些转换,减轻 MySQL 的压力:

public class Demo {
    public static void main(String[] args) {
        String ipStr = "192.168.0.1";
        long ip =ip2int(ipStr);
        System.out.println(ip);
    }
    public static long ip2int(String ip) {
        String[] items = ip.split("\\.");
        return Long.valueOf(items[0]) << 24 | Long.valueOf(items[1]) << 16 | Long.valueOf(items[2]) << 8 | Long.valueOf(items[3]);
    }
    public static String int2ip(long ipInt) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append((ipInt >> 24) & 0xFF).append(".");
        stringBuilder.append((ipInt >> 16) & 0xFF).append(".");
        stringBuilder.append((ipInt >> 8) & 0xFF).append(".");
        stringBuilder.append(ipInt & 0xFF);
        return stringBuilder.toString();
    }
}

 到此这篇关于浅谈MySQL中用什么数据类型存IP地址的文章就介绍到这了,更多相关MySQL存IP地址内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文