【发布时间】:2019-01-25 20:47:33
【问题描述】:
背景
我正在构建一个 IPAM 应用来跟踪和存储各个 IPv4 和 IPv6 地址的元数据。后端旨在成为一个无聊的、与供应商无关的关系数据库。
IPv6 可能会在巨大的可寻址空间中处理大量数字,但所讨论的范围本身并不构成大数据,因此我不愿意更改后端架构,除非我目前的方法存在一些实际的技术缺陷,这种方法可以更好地服务通过一个时髦的 NoSQL 解决方案,以牺牲关系和 ACIDity 为代价。
(我不想记录整个地址空间,只记录任意客户使用的实时地址。)
架构
规范化给定 IP 地址的字符串表示形式并将其用作主键。 IPv4 地址转换为 IPv6 并以 ffff 为前缀。 IPv6 地址被压缩和小写。
第二个字段指示相关记录是哪个协议版本——4 或 6。这里的想法是,如果用户在 IPv4 子网中搜索记录,我可以快速排除 IPv6 空间,反之亦然。
接下来的八个字段 (ugh) 都是地址中每个八位字节的整数表示(octet_1、octet_2 等)。
索引
主键应该已经是它自己的唯一索引了。
在(version, octet_1, ..., octet_8) 上创建一个附加索引。
查询
为了搜索任一版本的特定 IP,我可以简单地将 IP 字符串以与上述相同的方式标准化并搜索主键。
对于按子网搜索,应用程序计算范围的开始/结束地址,将两者都转换为 IPv6,将两者都转换为八元组,并对所有八元组之间的记录发出查询。
使用这种方法可能会遇到什么问题?改进建议?
从ipv4s casted as ipv6 are not the same thing 到your index will explode / write performance will suck 的任何内容都是公平的游戏。
我构建了一个测试 POC 来验证此架构的功能,但我担心此模型在生产环境中的任何潜在缺陷。
【问题讨论】:
-
不需要“规范化”或类似的东西。只需将地址存储在 inet 类型的列中 - 这比字符串表示更有效