我有以下用于存储IP的表结构(PostgreSQL
):
CREATE TABLE ips (
ip INET NOT NULL
);
INSERT INTO ips VALUES ('127.0.0.1');
INSERT INTO ips VALUES ('127.0.0.5');
INSERT INTO ips VALUES ('127.0.0.6');
如何找到127.0.0.2
,因为它是下一个免费的最低IP?
我有点坚持如何以优化的方式解决这个问题。
这似乎是这样做的,但是一种减慢子网大小/ 10(4M +记录)的方法:
SELECT sub.ip FROM
(SELECT set_masklen(((generate_series(1, (2 ^ (32 - masklen('127.0.0.0/10'::cidr)))::integer - 2) + '127.0.0.0/10'::cidr)::inet), 32) as ip) AS sub
WHERE sub.ip NOT IN
(SELECT ip from ips)
AND sub.ip > set_masklen('127.0.0.0/10', 32)
AND sub.ip < set_masklen(broadcast('127.0.0.0/10')::inet, 32)
ORDER BY ip ASC LIMIT 1;
答案 0 :(得分:1)
您可以使用inet
功能:
select ips.ip + 1
from ips
where not exists (select 1 from ips ips2 where ips2.ip = ips.ip + 1)
order by ips.ip
limit 1;
答案 1 :(得分:0)
如果使用9.3或更高版本,则可以利用横向连接。
SELECT (a.ip+1) as low, q.ip as high FROM ips a LEFT JOIN LATERAL
(SELECT * FROM ips b WHERE a.ip < b.ip ORDER BY b.ip ASC limit 1) AS q ON true
WHERE q.ip <> (a.ip + 1) LIMIT 1;
使用正确的过滤器和排序加入同一个表,然后使用ip + 1
生成每行的下一个数字并检查它是否匹配。将结果限制在第一个。