我有一个MySQL表,我存储IP范围。它的设置方式是我将起始地址存储为long,以及结束地址(以及id和其他一些数据)。 现在我让用户通过输入开始和结束IP地址来添加范围,我想检查新范围是否已经(部分)在数据库中。
我知道我可以在查询之间进行,但这似乎不适用于2个不同的列,我也无法弄清楚如何传递范围来比较它。 在PHP循环中执行它是可能的,但是可以使用例如132.0.0.0-199.0.0.0是相当多的查询..
答案 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);
这应该会为您提供与新地址重叠的所有现有地址。