用于跟踪IPv6 / IPv4地址的关系数据库-我提出的模式可以工作吗?

时间:2019-01-25 20:47:34

标签: sql database ipv6 ipv4

背景

我正在构建一个IPAM应用程序,以跟踪和存储各个IPv4和IPv6地址的元数据。后端旨在成为无聊的,与供应商无关的关系数据库。

IPv6可能在广阔的可寻址空间中处理大量数据,但是所讨论的范围并不是天生就构成大数据的,因此我不愿意更改后端体系结构,而不会遇到我目前使用的方法更好的实际技术缺陷。通过时髦的NoSQL解决方案以关系和ACIDity为代价。

(我不是要记录整个地址空间,而只是要记录任意客户使用的实时地址。)

架构

标准化给定IP地址的字符串表示形式,并将其用作主键。 IPv4地址将转换为IPv6,并以ffff为前缀。 IPv6地址被压缩并小写。

第二个字段指示该记录是哪个协议版本-4或6。这里的想法是,如果用户在IPv4子网中搜索记录,我可以快速排除IPv6空间,反之亦然。 / p>

接下来的八个字段(ugh)是地址(octet_1octet_2等)中每个八位位组的整数表示。

索引

主键应该已经是它自己的唯一索引。

(version, octet_1, ..., octet_8)上创建一个附加索引。

查询

要搜索任一版本的特定IP,我可以像上面一样简单地对IP字符串进行规范化并搜索主键。

对于通过子网进行搜索,应用程序将计算范围的开始/结束地址,将两者都转换为IPv6,将它们都转换为八进制,并对所有记录之间的八进制发出查询。

此方法可能会遇到什么问题?有改进建议吗?

ipv4s casted as ipv6 are not the same thingyour index will explode / write performance will suck的任何事物都是公平的游戏。

我构建了一个测试POC,用于验证该模式的功能,但是我担心该模型在生产环境中的任何潜在缺陷。

2 个答案:

答案 0 :(得分:3)

如果您可以选择数据库后端,则选择PostgreSQL。它具有IP地址的内置类型,因此具有出色的性能和功能。

但是您说过您想成为数据库不可知的,所以让我们专注于此。在那种情况下,我只使用前缀为:: ffff:的IPv4地址进行字符串表示,然后仅使用小写的十六进制表示法并且不进行压缩。因此IPv4地址10.11.12.13将变为0000:0000:0000:0000:0000:0000:ffff:0a0b:0c0d。

几乎所有数据库在字符串上都具有良好的索引,并且使用这种表示法,您可以轻松地进行子网和范围查询。如果要所有IPv4地址,只需查询LIKE'0000:0000:0000:0000:0000:ffff:%'。因为它是从一开始就锚定的,所以标准btree索引应该可以正常工作。您可以使用<和>运算符对范围进行更复杂的查询,这又可以从标准索引中受益。这应该为您提供大多数子网查询。

在您的应用程序中,使用inet_pton等解析字符串以将其转换为所需的字符串应该不难。

在这种情况下,我会避免非正规化。通过以上所述,您不需要单独的版本或八位字节列。它们只会减慢速度,增加不一致的机会。

答案 1 :(得分:0)

在“架构”下,您没有给出实际的架构。

“ IPv4地址已转换为IPv6并以...开头”,这表明您不了解IPV6的意图和目的。

“ IPv6地址...小写。”背叛您不了解值与值表示之间的区别(“小写”可能会影响值的 表示 ,但会 从不 影响 值本身 )。

“如果用户在IPv4子网中搜索记录”,则表明您不了解OSI 7层模型的构思者在构思其网络通信模型时所考虑的关注点分离。 “搜索记录”与IP(v4 / v6)不在同一层。

“主键应该已经是它自己的唯一索引。”背叛您不了解关系数据管理。

您可能会觉得这不是您问题的答案,但实际上是。