Answers:
不要存储为字符串。使用int unsigned
列,INET_ATON()
并INET_NTOA()
分别使用和存储/检索。AFAIK mysql不支持ipv6的INET_ *。
根据评论编辑
使用内置函数将IP与整数进行IP转换(以及将这些整数存储在数据库中)具有自动验证这些IP的副作用。假设您将IP存储为VARCHAR(16),则必须确保不要通过一些自定义验证存储无效IP(例如999.999.999.999)。INET_ *函数负责这一点。
现在可能是开始考虑IPv6的时候了。MySQL没有将IPv6地址转换为二进制格式的方法。40个字符串将处理任何普通的IPv6地址。有可能超过40个字符的格式,我认为那些不太可能发生的做法。
从中可以计算出大小,该信息最多将有8个四个字符组和7个分隔符。异常格式将后两个组替换为IPv4格式地址。在不进行地址压缩的情况下,它将最后的9个字符替换为最多15个字符。
如果要存储块,则块大小指示可以使用4个字符,而不是IPv4所需的3个字符。
您应该确保所获得的格式一致,但是我所见过的所有软件都为地址提供了一致的格式。
我建议迁移到PostgreSQL并使用INET或CIDR数据类型。
CREATE TABLE test ( test_id serial PRIMARY KEY, address inet );
INSERT INTO test ( address ) VALUES ( '1.2.3.4'::inet );
INSERT INTO test ( address ) VALUES ( 'a:b::c:d'::inet );
SELECT * FROM test;
test_id | address
---------+----------
1 | 1.2.3.4
2 | a:b::c:d
这是在MySQL邮件列表之一中做出的最佳答案。读最好的字段类型来存储IP地址...。
简要地说,我建议使用INT(10)UNSIGNED。
因此,使用192.168.10.50:
(192 * 2 ^ 24)+(168 * 2 ^ 16)+(10 * 2 ^ 8)+ 50 = 3232238130(结果192.168.10.50)
在MySQL中,您可以直接使用
SELECT INET_ATON('192.168.10.50');
get3232238130
。
要么
192 +(168 * 2 ^ 8)+(10 * 2 ^ 16)+(50 * 2 ^ 24)= 839559360(向后显示50.10.168.192)
在MySQL中,你可以直接使用
SELECT INET_NTOA(3232238130);
获得192.168.10.50
回来。
从MySQL v5.6.3开始,他们添加了对的支持INET6_ATON
,INET6_NOTA
该支持将处理IPv4和IPv6地址。但是他们不再将其存储为整数。IPv6返回varbinary(16)
,并且IPv4返回varbinary(4)
。
http://dev.mysql.com/doc/refman/5.6/en/miscellaneous-functions.html#function_inet6-aton
您最多可以存储15个字符。请不要使用VARCHAR(15),因为这是16个字节(第一个字节管理字符串长度,因此检索和存储速度较慢)。始终在IP地址之类的地址上使用CHAR(15)。