【问题标题】:Checking if IP is in a range in MYSQL检查IP是否在MYSQL中的范围内
【发布时间】:2018-08-29 14:45:43
【问题描述】:

我有一个简单的表,其中包含这样的 IP 范围(它们保存为 varchar,但如果需要我可以更改):

1.0.0.0/24
1.0.1.0/24
1.0.2.0/23
1.0.4.0/22
...etc

如何选择给定 IP 地址在该范围内的行?

类似:

SELECT range FROM ipranges WHERE '195.124.199.201' IN range

编辑:建议的重复答案MySQL check if an IP-address is in range? 对我不起作用,因为它假定范围被指定为两个 IP 地址,但我的符号使用斜杠,我不知道如何在它们之间进行转换。

【问题讨论】:

标签: mysql ip-address cidr


【解决方案1】:

您需要使用INET_ATON() 将 IPv4 地址格式转换为等效的无符号整数。

首先根据CIDR notation计算起始地址和结束地址。

mysql> SELECT INET_ATON(SUBSTRING_INDEX(range, '/', 1)) AS start_address, 
  POWER(2, 32-SUBSTRING_INDEX(range, '/', -1))-1 AS num_addresses
  FROM ipranges;
+---------------+---------------+
| start_address | num_addresses |
+---------------+---------------+
|      16777216 |           255 |
+---------------+---------------+

该结果是我针对'1.0.0.0/24' 测试此查询时得出的结果。

然后你可以检查你感兴趣的IP地址的INET_ATON()是否在这个范围内,因为它只是一个整数范围。

SELECT range FROM (
    SELECT range, 
      INET_ATON(SUBSTRING_INDEX(range, '/', 1)) AS start_address, 
      POWER(2, 32-SUBSTRING_INDEX(range, '/', -1))-1 AS num_addresses
    FROM ipranges) AS t
WHERE INET_ATON('195.124.199.201') BETWEEN start_address AND start_address+num_addresses;

恐怕对于所有这些表达式,SQL 查询不可能使用索引进行优化。如果您需要对大量 IP 范围的数据集以高性能运行它,您需要考虑一种以不同方式存储数据的方法,以便您可以对其进行索引。

但如果您只有少量 IP 范围,即使是不可索引的查询也可能足够快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-14
    • 2017-05-21
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    • 2017-05-28
    • 1970-01-01
    • 2011-01-09
    相关资源
    最近更新 更多