【发布时间】:2021-10-20 11:07:44
【问题描述】:
我基本上有一个 2 列的表,其中一个 IP 子网作为键/索引,一个描述作为值。例如:
10.20.30.0/30 "Subnet 1"
我需要编写一个 REST 服务,该服务将返回包含给定 IP 地址的子网描述,或者如果 IP 地址匹配多个,则返回子网列表。
起初,我以为我会简单地使用后端数据库 (Postgres) 并扩展所有子网,因为我没有处理大量数据。所以上面的例子会扩展为:
10.20.30.0 "Subnet 1"
10.20.30.1 "Subnet 1"
10.20.30.2 "Subnet 1"
10.20.30.3 "Subnet 1"
这在存储方面效率低下,尤其是当子网变大时。但是,它既快速又简单,并且现有数据库具有非常有效的方法来查找 IP 地址作为索引,所以这是我的第一个想法。我最关心的是查找效率,因为我的数据库中将有大约 100 万个条目。
但是,我发现我对 IPv6 也有要求,而且涉及的子网非常庞大。这意味着我不再有扩展所有子网的选项。
在开始编写自定义 REST API 之前,我想知道使用子网作为索引检查 IP 地址的 POSTGRES 查询是否有效。检查不是微不足道的,我不知道如何在内部进行以保持效率。
有人知道 POSTGRES 如何检查子网索引表中的 IP 地址吗?
编辑:这是我正在谈论的在 POSTGRES 中查找 IP 地址的示例(使用在线 https://extendsclass.com/postgresql-online.html)
drop table ipdesc;
create table ipdesc (addr inet, category varchar(20));
insert into ipdesc (addr, category) values ('10.10.10.0/24', 'tens');
insert into ipdesc (addr, category) values ('20.20.20.0/24', 'twenties');
insert into ipdesc (addr, category) values ('50.50.50.0/24', 'fifties');
insert into ipdesc (addr, category) values ('50.50.50.0/30', 'sub-fifty');
select * from ipdesc where inet '50.50.50.1' << addr;
结果:
addr category
---- --------
50.50.50.0/24 fifties
50.50.50.0/30 sub-fifty
谢谢!
【问题讨论】:
-
在网络中,不仅需要地址,还需要掩码或掩码长度来将地址分解为网络和主机部分。简单地拥有像
10.20.30.0这样的地址并不能告诉您网络是什么,您需要类似上面的地址(10.20.30.0/30),它的掩码长度告诉您地址的前 30 位是网络。几乎所有 IPv6 网络都将是/64,因为其他网络规模会破坏 IPv6 功能。 -
确定地址是否在网络中的正确方法是对带有网络掩码的地址执行按位
AND,以查看它是否与网络地址匹配。 This two-part answer` 解释了如何做到这一点。 -
谢谢@RonMaupin,但我认为你过度简化了我的问题。我知道如何检查 IP 地址是否在子网中。但是,通过子网索引的数据库有效地做到这一点并非易事。由于 Postgres 支持 IP 子网作为原始类型,并且您可以使用 SQL 查询进行检查,我想知道它的效率如何。 Postgres 在后台做一些魔术吗?或者它是在进行简单的搜索并将 IP 与每个子网进行匹配?我不知道,希望在这里得到答案。
-
那你可能想问dba.stackexchange.com
标签: postgresql ipv6 ipv4