【问题标题】:IPv4 longest prefix match using Postgres使用 Postgres 的 IPv4 最长前缀匹配
【发布时间】:2014-06-10 08:26:40
【问题描述】:

给定一个 IP 地址 192.168.0.1,以及一个包含存储子网 IP 地址的 next_hop_subnet 列的表,您是否发现以下 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;

既然可以有多个同样好的匹配,我认为除了分两步之外别无他法。有什么建议吗?

【问题讨论】:

    标签: postgresql ipv4 longest-prefix


    【解决方案1】:

    我会使用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
     );
    

    这样您就可以从路由表中获得最长的匹配前缀。

    【讨论】:

    • 谢谢,经过编辑,现在它涵盖了多个等效匹配项。唯一的问题可能是最长前缀匹配的顺序应该是降序的,对吗?
    • 我对删除一些语法问题进行了小修改。我认为这个解决方案足够接近,可以进行类似于路由器在传递数据包时所做的查找。
    • 你认为我们可以通过选择 max(masklen(next_hop_subnet::inet)) 来消除 order by statement 吗?我只是想在一个巨大的表(300K)中改进查询时间
    • 我不确定在这种情况下 max 或 order by 是否更快。不过值得一试。在正确的列上建立索引可能最有帮助。
    猜你喜欢
    • 2013-06-03
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 1970-01-01
    • 1970-01-01
    • 2019-01-11
    • 2015-10-25
    相关资源
    最近更新 更多