我也应该支持IPv6吗?如果是,那么IP地址的最大长度是多少?
#1 楼
不要存储为字符串。使用int unsigned
列,并分别使用INET_ATON()
和INET_NTOA()
存储/检索。 AFAIK mysql不支持ipv6的INET_ *。根据注释进行编辑
使用内置函数将IP转换为整数或从整数转换IP(因此将这些整数存储在数据库)具有自动验证这些IP的副作用。假设您将IP存储为VARCHAR(16),则必须确保不要通过一些自定义验证存储无效IP(例如999.999.999.999)。 INET_ *函数可以解决这个问题。
#2 楼
我建议迁移到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
评论
要获取网络中的IP,请选择*从测试位置地址<<'1.2.3.0/24'::inet;
– jkj
2011年3月14日10:17
#3 楼
现在可能是开始考虑IPv6的时候了。 MySQL没有将IPv6地址转换为二进制格式的方法。 40个字符串将处理任何普通的IPv6地址。有一种格式可能超过40个字符,我认为那些不太可能发生的做法。从中可以计算出大小,该信息最多将有8个四个字符组和7个分隔符。异常格式将后两个组替换为IPv4格式地址。不进行地址压缩时,它将用最多15个字符替换最后9个字符。
如果要存储块,则块大小指示可以使用4个字符,而不是IPv4所需的3个字符。 >
您应该确保所获得的格式一致,但是我见过的所有软件都为地址提供了一致的格式。
评论
我完全同意,IPv6即将到来,比起像Y2K那样等待它更好。
–杰夫
2011年3月13日下午4:09
不仅即将到来,而且已经在我的系统上。
–BillThor
2011年8月21日在8:01
#4 楼
这是在MySQL邮件列表之一中做出的最佳答案。读取“最佳字段类型”以存储IP地址。...简要地建议,我第二次使用INT(10)UNSIGNED。
它使用较少内存(仅4个字节)
最适合排序和搜索IP范围,尤其是在寻找访问者的原籍国的情况下。
因此,请使用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');
获取
3232238130
。或
在MySQL中,您可以直接使用
SELECT INET_NTOA(3232238130);
返回
192.168.10.50
。评论
令人印象深刻,为您+1 !!!每天使用4字节无符号肯定会胜过字符串操作。
– RolandoMySQLDBA
2011年3月14日15:27
-1,IP地址最大为128位,MySQL支持的最大整数类型为64位。
–亨德里克·布鲁默曼
2011-3-15在17:39
nhnb,IPv6是128位,但是对话是关于32位的IPv4。无需对坚持您所学的每个评论/答案发表评论。
–眼睛
2011-3-16在5:32
您的答案没有提到它仅处理旧的Internet协议,而最后一个问题明确提到了IPv6。鉴于最后一个市长互联网提供商(至少在我的国家)将在今年年底之前支持IPv6,因此设计一个无法处理IPv6的数据库结构是一个非常糟糕的主意。
–亨德里克·布鲁默曼
2011-3-17在22:12
#5 楼
从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
#6 楼
您最多可以存储15个字符。请不要使用VARCHAR(15),因为它是16个字节(第一个字节管理字符串长度,因此检索和存储速度较慢)。始终在IP地址之类的地方使用CHAR(15)。评论
IP地址的最大长度为45个字符。
–亨德里克·布鲁默曼
2011年3月13日晚上10:27
CHAR不会用空格填充它吗?
– Gaius
2011-3-14在6:57
#7 楼
抱歉,无法评论答案。关于stackoverflow有一个问题。我完全同意选择的答案:使用2xBIGINT可能是目前ipv6的最佳方法。我建议使用2 * BIGINT,但是
确保它们重新签名。在IPv6的/ 64
地址边界处有一个
自然拆分(因为/ 64
是最小的网络块大小),
可以很好地对齐。 br />
也可以在此bigints上存储ipv4-通过将其中之一标记为NULL或使用V4COMPAT格式
评论
-1,IP地址最大为128位,MySQL支持的最大整数类型为64位。
–亨德里克·布鲁默曼
2011年3月13日在10:24
IPv4是32位。 128位用于IPv6,正如他提到的那样,INET_ *东西不支持。
–理查德
2011年8月12日15:06
对于IPv6地址,请使用INET6_ATON()和INET6_NTOA()函数,请参见示例-rathishkumar.in/2017/08/how-to-store-ip-address-in-mysql.html
–爱尔兰语
17年8月25日在17:21