【问题标题】:Best way to store single IPs, IP ranges, IP blocks and IP classes and search quickly through them存储单个 IP、IP 范围、IP 块和 IP 类别并快速搜索它们的最佳方式
【发布时间】:2013-11-01 00:11:55
【问题描述】:

在 MySQL 数据库中存储多种 IP 类型的最佳方法是:
- 单一 IP (123.123.123.123)
- IP 范围 (123.123.123.1 - 123.123.123.121)
- IP 块 (123.123.123.1/20 )
- IP 类别(123.123.123.* 或 123.123..

我正在考虑将所有范围/块/类转换为单个 IP,并使用 ip2long 存储它们以便更快地搜索到表中,但这将导致一个超过 100 万个数据库,我也需要不时减少/放大类或更改/删除 IP 块。

每次有人访问我的网站时都会访问此数据库(因此需要快速)。 有什么想法吗?

【问题讨论】:

  • 只要知道 ip!= 人,任何 ip 屏蔽都可以规避。
  • 您在此处描述的三种类型——范围、块和类——都是描述同一事物的不同方式。
  • @Dagon 我知道这一点,我不想用这个列表来阻止某些人。
  • @duskwuff 是的,你说得对,所有这些都可以很快在 IP 范围内进行翻译,但我收到了这种类型的 Ip,所以当有人向我发送修改时,很难扭转信息从IP范围到IP块然后修改/删除它并添加新信息。

标签: php mysql sql database ip


【解决方案1】:

本教程可以提供帮助:http://daipratt.co.uk/mysql-store-ip-address/

保存 IPv4 地址最有效的方法是使用 INT 字段(不是您可能期望的 VARCHAR)。您可以使用 PHP 的 ip2long 转换它们,然后使用 MySQL 的 INET_NTOA 函数或 PHP 的 longtoip。

来源:IP address storing in MySQL database using PHP

【讨论】:

  • 感谢您的回答。但我已经指定我将以数字形式转换 IP(使用 ip2long php 函数)。我所需要的只是将 IP 类/块/和单个 IP 放在一起并快速搜索/修改/删除它们的想法。
【解决方案2】:

类似:

CREATE TABLE ip_ranges (
  id         INT UNSIGNED AUTO_INCREMENT,
  ip_start   INT UNSIGNED NOT NULL,
  ip_end     INT UNSIGNED DEFAULT NULL,
  ip_subnet  TINYINT UNSIGNED DEFAULT NULL,
  ip_class   ENUM('A', 'B', 'C') DEFAULT NULL
)

其中ip_start是必填项,其他所有字段可以为NULL [单一IP规则],也可以设置另一个:

  • ip_end 是范围 [192.168.1.10 到 192.168.1.15] 规范的结尾部分
  • ip_subnet 是子网掩码 [192.168.1.0/22]
  • ip_class 是网络类,尽管这些在逻辑上可以存储为 /8、/16 或 /24 子网。

完全忽略ip_class...

SELECT *
FROM ip_ranges
WHERE
  $ipaddr BETWEEN ip_start AND ip_end
  OR
  $ipaddr BETWEEN
    (ip_start &~ (POW(2,32-ip_subnet)-1)) AND
    (ip_start |  (POW(2,32-ip_subnet)-1))

应选择适用于$ipaddr 的任何规则。 [但我没有测试过]

【讨论】:

  • 网络“类”的概念已经过时了 20 多年 - 定义 CIDR 的 RFC 1518 和 1519 于 1993 年发布。请忘记网络“类”曾经存在过。
  • @duskwuff 是的。我想一旦 CIDR 发生,人们都会说“哦,天哪,那些‘经典’的废话有多愚蠢?”
【解决方案3】:

您可以将所有类型的地址存储为 LineString(Point(-1, first_ip_iplong), Point(+1, last_ip_iplong)),为该字段添加索引并享受即时搜索(使用 MBRIntersects )几乎任何数据或记录计数。

更多信息可以找到here

请注意,这种做法会在 mysql 中紧密耦合您的代码。

【讨论】:

  • IP 地址不是空间坐标。使用 GIS 类型来索引它们是一个糟糕的主意。
  • 您知道任何其他方法可以通过 IP 范围进行即时搜索吗?
  • +1 IP 地址绝对是空间坐标(IP“地址空间”哈哈)...包含它们的框(子网)的大小始终是 2 的幂,并找到包含给定盒子“角落”的 IP 地址是 R-Trees 的绝妙用途,比您使用 B-Trees 可以完成的任何事情都要好得多……而且您会得到一个带有 MySQL 空间索引的 R-Tree。
  • 不,这仍然是个糟糕的主意。 IP 地址是线性的,而不是空间的。例如,地址 12.34.56.78 与 99.34.56.78 没有关系。
  • 好的,好的,线串上的点,这仍然是“空间”。当您查找 IP 地址时,您通常会查看地址范围的集合(低/高对、子网)。 R-Tree 是一种非常快速的找到它们的方法。如果您对子网或范围不感兴趣,那么这种方法当然毫无意义……但在您尝试之前不要敲门。
猜你喜欢
  • 1970-01-01
  • 2016-12-13
  • 2019-05-20
  • 2020-11-10
  • 1970-01-01
  • 1970-01-01
  • 2016-05-16
  • 2018-01-04
  • 2014-08-20
相关资源
最近更新 更多