将MySQL地址范围与MySQL中的开始和结束IP地址进行比较

时间:2010-06-15 13:12:00

标签: php mysql ip-address

我有一个MySQL表,我存储IP范围。它的设置方式是我将起始地址存储为long,以及结束地址(以及id和其他一些数据)。 现在我让用户通过输入开始和结束IP地址来添加范围,我想检查新范围是否已经(部分)在数据库中。

我知道我可以在查询之间进行,但这似乎不适用于2个不同的列,我也无法弄清楚如何传递范围来比较它。 在PHP循环中执行它是可能的,但是可以使用例如132.0.0.0-199.0.0.0是相当多的查询..

4 个答案:

答案 0 :(得分:2)

当你说你将地址存储为long时,我假设你的意思是你已经将它们存储起来,以便(比方说)10.1.2.3将存储为0x0a010203。在这种情况下,要查找地址是否已存在,您可以执行以下操作:

SELECT ...
FROM ipranges
WHERE (<NEWADDR> >= startaddr)
    AND (<NEWADDR> <= endaddr)

然后如果你得到任何行,那么地址已经在表格中了。 (当然,用新地址替换<NEWADDR>!)

至于检查重叠的行,这只是稍微复杂一些:

SELECT ...
FROM ipranges
WHERE NOT ((<NEWENDADDR> < startaddr) OR (<NEWSTARTADDR> > endaddr))

即。如果新范围在它之后开始或在它之前结束,则新范围不会与旧范围重叠。

答案 1 :(得分:1)

start_address和end_address都是long?那么为什么不直接将你想要的IP转换为WHERE start_address <= $myip AND end_address >= $myip

对于范围,只需在where子句

中执行三次
WHERE (start_address <= $startAddress AND end_address >= $startAddress) 
   OR (start_address <= $endAddress AND end_address >= $endAddress) 
   OR (start_address >= $startAddress AND end_address <= $endAddress)

第一个分组查找包含起始地址的范围。第二个查找包含结束地址的范围。这意味着输入的范围仍然可能是db中范围的超集。这就是第三个检查的内容。

这应该返回与输入范围相交的所有范围......

答案 2 :(得分:1)

如何将IP地址范围存储为十进制,以便您可以使用BETWEEN进行简单检查。

4294967295 - 4294967040 - &gt; FFFFFF00 - FFFFFFFF - &gt; 255.255.255.0 - 255.255.255.255

答案 3 :(得分:0)

如下:

SELECT * FROM addresses WHERE
    (start < $new_start AND end > $new_start) OR
    (start > $new_end AND end < $new_end);

这应该会为您提供与新地址重叠的所有现有地址。