我该使用什么类型在MySQL中存储IP地址?

12

我本来要使用varchar(20), 但我想知道是否应该使用INT并去掉小数点。哪种方式更好,为什么?


这取决于您将对数据执行哪些操作。 - zerkms
3
不能简单地去掉每个段落中的句点,否则您必须用零填充每个八位组,使它们都是三个字符长。否则,IP地址192.168.45.5和192.168.4.55将看起来相同。当人们建议使用一个int(32位)时,他们意味着您将每个八位组(每个8位)打包到单个int中。 - Sarel Botha
对于IPv4 + IPv6混合,VARBINARY(16) - hanshenrik
4个回答

20

我假定您只对IPv4地址感兴趣,而不是IPv6。

我会使用一个INT UNSIGNED列,然后使用INET_ATONINET_NTOA来在文本表示和整数值之间进行转换。

mysql> SELECT INET_ATON('192.168.10.50');
+----------------------------+
| INET_ATON('192.168.10.50') |
+----------------------------+
|                 3232238130 |
+----------------------------+
1 row in set (0.00 sec)

mysql> SELECT INET_NTOA(3232238130);
+-----------------------+
| INET_NTOA(3232238130) |
+-----------------------+
| 192.168.10.50         |
+-----------------------+
1 row in set (0.00 sec)

3

我经常看到很多将 IP 存储为整数的建议,但没有解释为什么要这样做。还有一个问题,你能解释一下为什么在这里 int 比 (var)char 更好吗? - zerkms
1
@zerkms - 简单的场景,我想记录用户活动,所以我们假设有一个包含1000万行数据的日志表(我知道这很小)。使用char会得到1000万 * 15个字节 = 光IP数据就要占用143MB。而使用int会得到1000万行 * 4个字节 = IP数据要占用38MB (相差了105MB)。因此,使用INT将会缓冲约四倍的值。在您的意见中,为什么使用char会更好呢? - Jon Black
@f00:因为我们不需要使用inet_ntoa()将其转换回来以进行显示。是的,大小是一个参数。虽然不是非常重要,但确实如此。 - zerkms
@zerkms - 我更希望在处理大量数据时,我的查询性能高效快速,而不是担心一个简单的数据转换问题,因为我会在我的演示层中进行处理。 - Jon Black
@f00:几乎所有通过int和char表示的IP地址的搜索都具有相同的性能。 - zerkms
显示剩余4条评论

0

如果你真的关心节省空间,你可以将它打包成一个4字节的整数。IPv4 IP地址的每个块可以有256个可能的值,这恰好是单个字节的范围。

-- 编辑 --> 正如f00在他的答案中链接的mysql函数所描述的那样,可以使用该方法实现。

然而,将其存储为字符串将节省一些编码时间。老实说,除非你在非常大的规模上进行此操作,否则从更密集的存储格式进行优化并不重要。


0

如果你已经从MySQL切换到MariaDB,或者像我一样研究如何在MariaDB中存储IP地址,那么请注意:

现在有一种新的数据类型称为INET6,它适用于IP版本。

文档可以在这里找到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接