【问题标题】:Relational database for tracking IPv6/IPv4 addresses -- will my proposed schema work?用于跟踪 IPv6/IPv4 地址的关系数据库——我提出的架构可以工作吗?
【发布时间】:2019-01-25 20:47:33
【问题描述】:

背景

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

IPv6 可能会在巨大的可寻址空间中处理大量数字,但所讨论的范围本身并不构成大数据,因此我不愿意更改后端架构,除非我目前的方法存在一些实际的技术缺陷,这种方法可以更好地服务通过一个时髦的 NoSQL 解决方案,以牺牲关系和 ACIDity 为代价。

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

架构

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

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

接下来的八个字段 (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 来验证此架构的功能,但我担心此模型在生产环境中的任何潜在缺陷。

【问题讨论】:

  • 不需要“规范化”或类似的东西。只需将地址存储在 inet 类型的列中 - 这比字符串表示更有效

标签: sql database ipv6 ipv4


【解决方案1】:

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

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

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

在您的应用程序中,使用 inet_pton 等解析字符串以将它们转换为您需要的任何内容应该不会太难。

在这种情况下,我会避免非规范化。使用我上面描述的内容,您不需要单独的版本或八位字节列。它们只会减慢速度并增加不一致的可能性。

【讨论】:

  • 有趣的方法,我看到了逻辑,它肯定更干净,更容易使用。作为字符串,虽然这不会导致更大的索引和更慢的比较,还是数据库在优化它们方面做得更好?当我刚开始时,传统观念是对整数进行比较、排序和索引,并尽可能避免使用字符串。
  • 问题是大多数数据库不做 128 位整数。 PostgreSQL 的 inet/CIDR 字段是一个非常有用的例外。并且由多个较小整数组成的主键将破坏目的,使查询与您的字段不对齐的子网变得更加困难等。字符串并不理想,但如果您不处理数百万个字符串,它们是一个有用的折衷方案记录。如果你是,你应该优化一个特定的数据库。在这种情况下,我会选择 PostgreSQL。
【解决方案2】:

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

“IPv4 地址转换为 IPv6 并以 ... 为前缀”表明您不了解 IPV6 的意图和目的。

“IPv6 地址变得……小写。”表明您不了解值和值表示之间的区别(“小写”可能会影响值的表示,但它会从不影响值本身)。

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

“主键应该已经是它自己的唯一索引。”说明你不懂关系数据管理。

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

【讨论】:

  • 虽然我确实就您显然比我更熟悉的主题征求了批评意见,但基于您将 OSI 作为一个问题的事实,我认为您可能假设太多了。我不是在编写路由器固件或制作数据包,我正在编写一个键值存储的前端,其中每个键都是 IP 地址的抽象,以便可以通过其字符串表示或其底层值进行查询取决于查询类型。我理解其中的区别——抽象它实际上是这个应用程序的重点。
  • 问题是关于 IPAM 应用程序:IP 地址管理。这个问题在这种情况下非常有意义......
  • 如果您正在“编写一个为用户做一些事情的应用程序,并且这些事情与 IP 地址有关”,并且您需要有关您的设计的建议,那么您应该 (a) 花费很多更努力地解释业务问题(它决定了 语义 - 业务含义 - 您的数据需要承载)和 (b) 提供实际模式。你还没有完成其中任何一个。
猜你喜欢
  • 2015-04-01
  • 2016-09-10
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 2013-09-18
  • 2019-07-14
  • 2013-11-26
  • 2013-05-25
相关资源
最近更新 更多