储存IP位址


25

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

我也应该支持IPv6吗?如果是,那么IP地址的最大长度是多少?

Answers:


27

不要存储为字符串。使用int unsigned列,INET_ATON()INET_NTOA()分别使用和存储/检索。AFAIK mysql不支持ipv6的INET_ *。

根据评论编辑

使用内置函数将IP与整数进行IP转换(以及将这些整数存储在数据库中)具有自动验证这些IP的副作用。假设您将IP存储为VARCHAR(16),则必须确保不要通过一些自定义验证存储无效IP(例如999.999.999.999)。INET_ *函数负责这一点。


1
-1,IP地址最大为128位,MySQL支持的最大整数类型为64位。
Hendrik Brummermann 2011年

3
IPv4是32位。128位用于IPv6,正如他提到的那样,INET_ *内容不支持。
理查德

1
对于IPv6地址,请使用INET6_ATON()和INET6_NTOA()函数,请参见示例-rathishkumar.in/2017/08/how-to-store-ip-address-in-mysql.html
rathishDBA

6

现在可能是开始考虑IPv6的时候了。MySQL没有将IPv6地址转换为二进制格式的方法。40个字符串将处理任何普通的IPv6地址。有可能超过40个字符的格式,我认为那些不太可能发生的做法。

从中可以计算出大小,该信息最多将有8个四个字符组和7个分隔符。异常格式将后两个组替换为IPv4格式地址。在不进行地址压缩的情况下,它将最后的9个字符替换为最多15个字符。

如果要存储块,则块大小指示可以使用4个字符,而不是IPv4所需的3个字符。

您应该确保所获得的格式一致,但是我所见过的所有软件都为地址提供了一致的格式。


2
我完全同意,IPv6即将到来,比起像Y2K那样等待它要好得多:D
Jeff

不仅即将到来,而且已经在我的系统上。
BillThor

6

我建议迁移到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年

4

这是在MySQL邮件列表之一中做出的最佳答案。读最好的字段类型来存储IP地址...

简要地说,我建议使用INT(10)UNSIGNED。

  1. 它使用较少的内存(仅4个字节)
  2. 最适合对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'); get 3232238130

要么

192 +(168 * 2 ^ 8)+(10 * 2 ^ 16)+(50 * 2 ^ 24)= 839559360(向后显示50.10.168.192)

在MySQL中,你可以直接使用 SELECT INET_NTOA(3232238130); 获得 192.168.10.50回来。


令人印象深刻,为您+1 !!!每天使用4个字节的无符号肯定会胜过字符串操作。
RolandoMySQLDBA 2011年

-1,IP地址最大为128位,MySQL支持的最大整数类型为64位。
Hendrik Brummermann 2011年

3
nhnb,IPv6是128位,但谈话是大约的IPv4其中IS 32位。无需对坚持您所学知识的每个评论/答案发表评论。
眼睛

您的答案没有提到它只处理旧的Internet协议,而最后一个问题明确提到了IPv6。鉴于最后一个市长互联网提供商(至少在我的国家)将在今年年底之前支持IPv6,因此设计一个无法处理IPv6的数据库结构是一个非常糟糕的主意。
Hendrik Brummermann 2011年


1

您最多可以存储15个字符。请不要使用VARCHAR(15),因为这是16个字节(第一个字节管理字符串长度,因此检索和存储速度较慢)。始终在IP地址之类的地址上使用CHAR(15)。


IP地址的最大长度为45个字符。
Hendrik Brummermann

CHAR不会用空格填充它吗?
盖乌斯

0

抱歉,无法评论答案。关于stackoverflow 有一个问题。我完全同意选择的答案:使用2xBIGINT可能是目前ipv6的最佳方法。

我建议使用2 * BIGINT,但请确保未签名。在IPv6的/ 64地址边界处存在一种自然分裂(因为/ 64是最小的网络块大小),因此可以很好地对齐。

也可以在bigints上存储ipv4-通过将其中之一标记为NULL或使用V4COMPAT格式

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.