如何在数据库中有效地存储一系列IP地址(保留和空闲)



我们有一个云系统,每个客户都有自己的虚拟网络。目前,我们在DB上有分配给每个客户的网络子网列表。

它们存储在具有以下列的网络表中:

| network      | ip_start | ip_end    | subnet_mask     |

新的,我们希望能够让客户请求个人IP(保留)。客户还可以在不再需要IP时释放其IP。

现在我可以考虑创建一个新表,存储所有已经保留的IP。

当请求新的IP时,我们需要扫描新的IP表,在相应的网络中找到一个可用的IP。

当一个IP被释放时,我们需要从新表中删除该IP记录。

但这看起来非常缓慢和繁琐,我想知道是否有更好的DB设计。

添加更多信息

假设我们保留了保留的IP表,我仍然想不出找到下一个免费IP的好方法。

由于将有免费IP位于连续范围的中间,要找到这些免费IP,需要查找每个IP和下一个IP以查找差距。

我必须从DB中检索整个IP范围,然后每次搜索间隙以获得免费IP吗?

此外,系统中必须支持IPV6。

我猜最好的设计是每个IP有一行。如果你使用的是IP-v4,那么最多有40亿种可能性——而你的公司并不拥有其中的大部分。这表明:

|     network      | ip | reserved_by     | reserved_date

当涉及到保留新地址时,让不可用ip对您的环境非常有帮助。这一点尤其正确,因为你可能有不连续的范围——如果不是现在,那么随着你变得更加成功,必须获得更多的IP地址。

您还可以维护一个表,正如您所描述的,使用触发器或存储过程来保持两者的同步。

这种解决方案对于IPv-6可能不可行,至少在最细的粒度级别上不可行。

我推荐您在问题中建议的设计,只是为了获得更好的性能,您可能希望以不同的方式存储IP。每个部分都可以用零填充,然后整个IP可以转换为BIGINT(使用IPv4)。这将允许使用大于和小于的比较来有效地使用索引,并且查找未使用的IP的"繁琐"过程可以实现为在该范围中已经使用的第一组连续IP中查找最大值,然后递增一。如果有一个函数可以转换为IP的整数表示形式或从IP的整数表达形式转换出来,那将是很有帮助的。

为了与IPv6兼容,您将无法转换为BIGINT,因此您可以将其保留为VARCHAR(或拆分为多个int)。在这一点上,将IP增加一将变得不那么琐碎,但仍然可行。

无论哪种方式,策略都是填充IP的各个部分,这样您就可以使用索引使流程尽可能高效。

最新更新