Соответствие самого длинного префикса IPv4 с использованием Postgres
При наличии IP-адреса 192.168.0.1 и таблицы со столбцом next_hop_subnet, в которой хранятся IP-адреса подсетей, возникают ли какие-либо проблемы со следующей логикой PostGRESQL с точки зрения точности или производительности:
minDif := select min(abs(inet '192.168.0.1' - next_hop_subnet::inet))
from routing_table
where next_hop_subnet::inet >>= inet '192.168.0.1';
select *
from routing_table
where next_hop_subnet::inet >>= inet '192.168.0.1'
AND abs(inet '192.168.0.1' - next_hop_subnet::inet) = minDif;
Поскольку может быть несколько одинаково хороших матчей, я думаю, что нет другого пути, кроме как сделать это в два этапа. Какие-либо предложения?
2 ответа
Решение
Я бы использовал masklen(inet)
функция для заказа ответов, как:
SELECT * FROM routing_table
WHERE next_hop_subnet::inet >>= inet '192.168.0.1'
AND masklen(next_hop_subnet::inet) = (
SELECT masklen(next_hop_subnet::inet) FROM routing_table
WHERE next_hop_subnet::inet >>= inet '192.168.0.1')
ORDER BY masklen(next_hop_subnet::inet) DESC
LIMIT 1
);
Таким образом, вы получите самый длинный соответствующий префикс из таблицы маршрутизации.
почему не это?
select * from routing_table where next_hop_subnet::inet >>= '192.168.0.1'::inet order by masklen(next_hop_subnet::inet) desc limit 1