mysql中inet_aton()仅支持ipv4,将“192.168.1.1”转为无符号整数3232235777,非法输入(如ipv6或超范围值)静默返回0;inet_ntoa()仅接受0–4294967295整数,超限返回null;存储必须用int unsigned,ipv6需改用inet6_aton/inet6_ntoa配合varbinary(16)。

MySQL里用INET_ATON()转IP为整数,但要注意IPv4限制
INET_ATON()只支持IPv4地址,把类似"192.168.1.1"转成无符号整型(如3232235777)。它内部按大端字节序拼接:每个点分段转成1字节,再组合成4字节整数。如果传入IPv6或非法格式(比如"192.168.1.256"),函数直接返回0——不是报错,这点容易误判为“转换成功”。
- 合法输入:
INET_ATON("10.0.0.1")→167772161 - 非法输入:
INET_ATON("2001:db8::1")→0(无声失败) - 边界注意:
INET_ATON("255.255.255.255")→4294967295,刚好是UNSIGNED INT最大值
用INET_NTOA()还原整数到IPv4,别对IPv6或超范围数硬试
INET_NTOA()是INET_ATON()的逆操作,但只接受0–4294967295之间的整数。超出范围(比如负数、大于4294967295)会返回NULL;传入NULL也返回NULL。它不验证数值是否对应真实IPv4结构——INET_NTOA(1)结果是"0.0.0.1",逻辑上成立,但可能不符合业务语义。
- 典型还原:
INET_NTOA(2130706433)→"127.0.0.1" - 超限情况:
INET_NTOA(4294967296)→NULL - 隐式类型转换风险:若字段是
SIGNED INT,存3232235777会溢出变负数,再用INET_NTOA()就失效
存储时必须用INT UNSIGNED,否则高位丢数据
IPv4地址转整数后最大值是4294967295,而MySQL默认INT是有符号的,上限仅2147483647。如果建表时写ip_int INT,存"192.168.1.1"(即3232235777)会自动截断或报错(取决于SQL mode),查出来就是错的。
- 正确声明:
ip_int INT UNSIGNED - 错误示例:
ip_int INT→ 存INET_ATON("192.168.1.1")可能得-1062731519(补码解释) - 迁移旧表时,先确认现有数据是否全在有符号范围内,否则
ALTER TABLE ... MODIFY ip_int INT UNSIGNED会失败
IPv6得绕开内置函数,改用INET6_ATON()和INET6_NTOA()
MySQL 5.6.3+才支持IPv6,对应函数是INET6_ATON()和INET6_NTOA(),返回的是VARBINARY(16)而非整数。想存IPv6又想用整型字段?不行——128位没法塞进BIGINT(仅64位)。常见做法是拆成两个BIGINT UNSIGNED,或直接用VARBINARY(16)存二进制值,查询时用INET6_NTOA()转回可读格式。
-
INET6_ATON("::1")→0x00000000000000000000000000000001(16字节) -
INET6_NTOA(0x00000000000000000000000000000001)→"::1" - 别试图用
CAST(INET6_ATON(...) AS UNSIGNED)——只取前8字节,丢一半地址
INET_ATON()/INET_NTOA()够用,但得盯紧字段类型和输入校验;IPv6一上来就得换思路,内置函数不提供整数映射路径。











