我有一个MySQL表,我存储IP范围。它的设置方式是我将起始地址存储为一个长整数,并且结束地址(以及一个id和一些其他数据)。 现在我有用户通过输入开始和结束IP地址来添加范围,并且我想检查新范围是否已经(部分)在数据库中。比较ip地址与MySQL中的开始和结束ip地址的范围
我知道我可以做一个查询,但似乎并不适用于2个不同的列,我也无法弄清楚如何通过一个范围来比较它。 在PHP中进行循环操作是一种可能性,但可以使用一系列132.0.0.0-199.0.0.0是相当大的量查询..
我有一个MySQL表,我存储IP范围。它的设置方式是我将起始地址存储为一个长整数,并且结束地址(以及一个id和一些其他数据)。 现在我有用户通过输入开始和结束IP地址来添加范围,并且我想检查新范围是否已经(部分)在数据库中。比较ip地址与MySQL中的开始和结束ip地址的范围
我知道我可以做一个查询,但似乎并不适用于2个不同的列,我也无法弄清楚如何通过一个范围来比较它。 在PHP中进行循环操作是一种可能性,但可以使用一系列132.0.0.0-199.0.0.0是相当大的量查询..
当你说你有存储为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))
即新的范围不会重叠,条件是它老范在它之后开始,或者在它之前结束。
约像什么:
SELECT * FROM addresses WHERE
(start < $new_start AND end > $new_start) OR
(start > $new_end AND end < $new_end);
这应该给你的所有,这将重叠的新地址的现有地址。
如果有什么新的范围完全包围老范?例如,如果旧范围是(start = 99,end = 100),新范围是($ new_start = 1,$ new_end = 200)?我不认为你的查询会返回这个结果:-( – psmears 2010-06-15 13:35:20
那么这是一个简单的附加子句: 'OR(start> = $ new_start AND end <= $ new_end)' – 2010-06-15 16:24:38
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中范围的超集。这是第三次检查的结果。
应该返回你所有的相交输入范围范围...
你实际上并不需要三种情况 - 更容易检查范围*不重叠的情况(即,新的范围要么低于现有的范围,要么完全高于此范围),然后使用'NOT'来反转结果:-) – psmears 2010-06-15 13:25:37
如何将IP地址范围存储为十进制数,您可以使用BETWEEN进行简单检查。
4294967295 - 4294967040 - > FFFFFF00 - FFFFFFFF - > 255.255.255.0 - 255.255.255.255
重叠逻辑看起来有点超过我的头,现在对我有意义,谢谢寻求帮助。在PHP中已经想到了一个不错的循环,但效率并不是很低,但这仍然快得多 – Maarten 2010-06-15 14:11:38