Соответствие самого длинного префикса 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
Другие вопросы по тегам