在MySQL如何存储IPv4地址?这个在秋招面试的过程中被问到过,没有答上来,今天猛地想起了这个问题,做一下复盘。
一个IPv4地址是由32位二进制来表示的,用点分十进制表示可以划分为4部分,每部分占8位,例如192.168.1.8
基本上有两种方案:
- 直接使用char来存储固定的字符串
- 将ip地址转换为整型
存储为整型
每个ip地址二进制表示都是唯一的且都是非负数,因此我们可以将一个ip地址转换为一个无符号整型。
为什么是无符号整型?
在MySQL中,一个int是32位,但是int是有符号的,因此表示完整一个ipv4地址。
而unsigned int是32位且没有负数,因此刚好可以完整表示一个ipv4地址。
而使用64位整型就造成了浪费。
以192.168.1.8
为例,说一下具体的思路:
在存入时,需要将ipv4转换为整数:
- 我们接受到的ipv4的参数肯定是一个字符串,我们按照点分割成四部分:
192
、168
、1
、8
。 - 对于第一部分
192
,我们左移24位,第二部分168
左移16位,第三部分1
左移8位,第四部分8
不动 - 将这四部分直接相加,就得到了最终要存储的值,然后将这个值传给MySQL进行存储就可以了
在取出时,需要将整数转换为ipv4的字符串:
- 对于这个整数,取后8位,就得到了
8
- 然后将整数右移8位,继续取后8位,就得到了
1
,以此类推
同理,左移取前8位也是可以的。
在MySQL中的支持
对于将ipv4转换为整数,以及将整数转换为ipv4,在MySQL中是有两个函数的,我们可以直接使用:
- INET_ATON() 函数将IPv4地址转换为一个无符号整数。它接受一个点分十进制的IPv4地址,返回对应的整数值。
- INET_NTOA() 函数则将整数形式的IPv4地址转换回点分十进制表示法
总结
ipv4直接存储为字符串
优点是:易读、灵活
缺点:占用更多的空间
ipv4转换为整数:
优点:节省空间、便于比较
缺点:不易读、需要额外的运算