如何在mySQL中存储IP

Ohi*_*ude 24 python mysql perl ip-address

本周我们在办公室里进行了一场健康的辩论.我们正在创建一个Db来存储代理信息,因为除了我们应该如何存储IP之外,我们大部分都已经制定了模式.一个阵营想要使用4个小点,一个用于每个八位位组,另一个想要使用一个大的int,INET_ATON.

这些表格将是巨大的,因此性能是关键.我在这里中间,因为我通常在我的世界中使用MS SQL和4个小的int.我对这种类型的卷存储IP没有足够的经验.

我们将使用perl和python脚本来访问数据库,以进一步将数据规范化为其他几个表,用于顶级谈话者,有趣的流量等.

我确信社区中有一些人已经做了类似于我们正在做的事情,我有兴趣听听他们的经历,哪条路线最好,1个大的int,或4个小的IP地址.

编辑 - 我们关注的一个问题是空间,这个数据库将像每天500,000,000条记录一样巨大.所以我们试图权衡空间问题和性能问题.

编辑2一些谈话已经转移到我们要存储的数据量......这不是我的问题.问题是哪个是存储IP地址的最佳方式以及原因.就像我在评论中所说的那样,我们为一家大型财富50强公司工作.我们的日志文件包含来自用户的使用数据.反过来,这些数据将用于安全上下文中,以驱动一些指标并驱动多个安全工具.

And*_*ler 24

我建议您查看将要运行的查询类型,以决定采用哪种格式.

只有当您需要拉出或比较单个八位字节时,您才需要考虑将它们分成单独的字段.

否则,将其存储为4字节整数.这也有允许您使用MySQL内置INET_ATON()INET_NTOA()功能的好处.

性能与空间

存储:

如果您只支持IPv4地址,那么MySQL中的数据类型可能UNSIGNED INT只使用4个字节的存储空间.

要存储单个八位字节,您只需要使用UNSIGNED TINYINT数据类型,而不是SMALLINTS每个存储使用1个字节.

对于某些开销,这两种方法都会使用类似的存储,对于单独的字

更多信息:

性能:

使用单个字段将产生更好的性能,它是单个比较而不是4.您提到您将仅针对整个IP地址运行查询,因此不需要将八位字节分开.使用INET_*MySQL 的函数将进行一次文本和整数表示之间的转换以进行比较.


Qua*_*noi 14

A BIGINT8字节数MySQL.

要存储IPv4地址,UNSINGED INT就足够了,我认为这是你应该使用的.

我无法想象一个场景,4八位位组比一个单位获得更多的性能INT,后者更方便.

另请注意,如果您要发出如下查询:

SELECT  *
FROM    ips
WHERE   ? BETWEEN start_ip AND end_ip
Run Code Online (Sandbox Code Playgroud)

,表中的列start_ipend_ip列,性能会很差.

这些查询用于查明给定IP是否在子网范围内(通常禁止它).

要使这些查询有效,您应该将整个范围存储为LineString带有SPATIAL索引的对象,并像这样查询:

SELECT  *
FROM    ips
WHERE   MBRContains(?, ip_range)
Run Code Online (Sandbox Code Playgroud)

有关如何执行此操作的详细信息,请参阅我的博客中的此条目:


Gre*_*ill 5

使用 PostgreSQL,有一个原生数据类型

更严重的是,我会落入“一个 32 位整数”阵营。仅当所有四个八位字节一起考虑时,IP 地址才有意义,因此没有理由将八位字节存储在数据库中的单独列中。您会使用三个(或更多)不同字段存储电话号码吗?

  • 更改 RDBMS 并不是一项简单的任务。我喜欢 pgsql,但是仅仅为了某种数据类型而选择 dbms 是不合理的。 (5认同)