繁体   English   中英

存储单个IP,IP范围,IP块和IP类的最佳方式,并快速搜索它们

[英]Best way to store single IPs, IP ranges, IP blocks and IP classes and search quickly through them

在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块。

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

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

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

来源: 使用PHP存储在MySQL数据库中的IP地址

就像是:

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任何规则。 [但我没有测试过]

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

更多信息可以在这里找到

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM