在数据库的实际使用场景中,IP地址的存储和查询是常见需求,直接将IP地址存为字符串会占用更多存储空间,且查询效率较低,因此通常会将IP地址转换为整数存储。MySQL内置的INET_ATON和INET_NTOA函数就是专门用来处理IP地址和整数互转的工具,使用起来简单高效。

INET_ATON函数:IP地址转数字
INET_ATON函数的作用是将一个IPv4地址转换为对应的无符号整数,转换逻辑是将IP地址的四个段分别作为32位整数的四个字节,按高位到低位组合计算。
函数语法
INET_ATON(ip_address),其中ip_address是符合IPv4格式的字符串,比如192.168.1.1,函数返回对应的无符号整数,如果输入格式不合法会返回NULL。
使用示例
下面是具体的转换示例,将常见的IP地址转换为数字:
-- 将IP地址192.168.1.1转换为数字
SELECT INET_ATON('192.168.1.1') AS ip_num;
-- 结果返回3232235777
-- 将IP地址10.0.0.1转换为数字
SELECT INET_ATON('10.0.0.1') AS ip_num;
-- 结果返回167772161
-- 输入不合法的IP地址返回NULL
SELECT INET_ATON('256.0.0.1') AS ip_num;
-- 结果返回NULL
INET_NTOA函数:数字转IP地址
INET_NTOA函数是INET_ATON的逆操作,作用是将一个无符号整数转换为对应的IPv4地址字符串。
函数语法
INET_NTOA(num),其中num是INET_ATON转换得到的无符号整数,函数返回对应的IPv4地址字符串,如果输入的数字超出IPv4的范围会返回NULL。
使用示例
下面是数字转IP地址的具体示例:
-- 将数字3232235777转换为IP地址 SELECT INET_NTOA(3232235777) AS ip_address; -- 结果返回192.168.1.1 -- 将数字167772161转换为IP地址 SELECT INET_NTOA(167772161) AS ip_address; -- 结果返回10.0.0.1 -- 输入超出范围的数字返回NULL SELECT INET_NTOA(4294967296) AS ip_address; -- 结果返回NULL
实际应用场景
这两个函数在实际开发中有很多实用场景,常见的有以下几种:
- IP地址存储优化:将IP地址转换为整数存储,只需要4字节,而字符串存储通常需要7到15字节,能节省存储空间,同时整数类型的查询效率也更高。
- IP段范围查询:将IP地址转换为数字后,可以通过数字的大小比较快速查询某个IP段内的所有记录,比如查询192.168.1.0到192.168.1.255之间的所有IP对应的数据。
- IP地址合法性校验:如果INET_ATON返回NULL,说明输入的IP地址格式不合法,可以用来快速校验用户输入的IP地址是否有效。
使用注意事项
在使用这两个函数时需要注意以下几点:
- 这两个函数仅支持IPv4地址,不支持IPv6地址,如果需要处理IPv6地址,可以使用INET6_ATON和INET6_NTOA函数。
- INET_ATON返回的是无符号整数,存储时建议使用INT UNSIGNED类型,避免符号问题导致转换错误。
- 如果IP地址字符串中包含前导零,比如
192.168.001.001,INET_ATON也能正确识别并转换,不需要提前处理前导零。
场景示例:查询指定IP段内的用户
假设有一张用户访问记录表user_access,其中ip_num字段存储的是转换后的IP整数,现在需要查询所有来自192.168.1.0/24网段的访问记录,对应的SQL语句如下:
-- 计算192.168.1.0和192.168.1.255对应的数字
SELECT INET_ATON('192.168.1.0') AS start_ip, INET_ATON('192.168.1.255') AS end_ip;
-- 结果start_ip为3232235776,end_ip为3232236031
-- 查询该IP段内的所有记录
SELECT * FROM user_access
WHERE ip_num >= 3232235776 AND ip_num <= 3232236031;
通过上述方式就可以快速完成IP段的查询,比直接对字符串格式的IP地址做模糊匹配效率要高很多。