【发布时间】:2020-01-03 04:48:06
【问题描述】:
我正在尝试确定下一个可用的 IP 地址被赋予一个子网(基本上是一个起始 IPv4 地址和一个结束 IPv4 地址)和一个包含已分配 IPv4 地址的 addresses 表。
表格的简化架构:
CREATE TABLE addresses (
address INET NOT NULL,
-- OTHER INFORMATION ASSOCIATED WITH IP ADDRESSES --
);
当前实现在子网内生成所有可能的 IP 地址,并返回那些不在 addresses 表中的 IP 地址。
例如,给定一个子网,其起始 IP 为“192.0.0.0”,结束 IP 为“192.0.0.255”,查询将如下所示:
SELECT *
FROM (
SELECT i + '0.0.0.0' :: inet as generated_address
from generate_series('192.0.0.0' :: inet - '0.0.0.0' :: inet,
'192.0.0.255' :: inet - '0.0.0.0' :: inet) as i) as iprange
WHERE generated_address NOT IN (SELECT address FROM addresses);
这可以正常工作,但问题是对于 /12 和更低的子网掩码它开始变慢,并且对于 /8 的子网掩码根本没有完成。
我正在尝试确定查找下一个可用 IP 地址的替代方法。
此外,如果我可以返回可用 IP 地址列表或范围列表(表示可用 IP 地址与不可用 IP 地址之间的差距),那将是理想的。
在post 上似乎有一些与此问题相关的好答案,但我发现很难理解该帖子中的答案并将它们翻译成我在 postgres 中的情况(因为我对它相当陌生)。
数据
我不完全确定数据会是什么样子,但地址表填充方式的 3 种情况如下:
- 稀疏(分配的 IP 地址很少)
- 不稳定(子网的一半已填满,但之间有很多间隙)
- 密集(占用大多数 IP 地址)
最坏的情况可能是情况 3,因为它需要查看所有记录。
我提供了一个简单的DB Fiddle 来演示该场景。
【问题讨论】:
-
您是否考虑过保留一个包含免费 IP 范围列表的表格?这可能会变得非常碎片化,但如果您不分配最低可用地址,但可能不会那么多,而是分配最小可用范围的第一个地址。您可以索引大小。
-
这是我可以考虑的一种可能的替代解决方案,但现在我更喜欢不包括创建另一个表的解决方案。
-
我的意思是把这张桌子作为唯一的桌子。无论如何,如果您的解决方案对您来说足够高效,那很好。
-
好吧,在问题中我简化了架构,但我将编辑问题以包括它们与
addresses表的每一行相关联的信息这一事实。为混乱道歉
标签: sql postgresql ip subnet