我必须将所有注册用户的IP地址存储在数据库中。我想知道,我应该为该列声明多少个字符?

我也应该支持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_ *函数可以解决这个问题。

评论


-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

#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_ATONINET6_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格式