我怎么做?

目前,不会使用 IPv6,但我需要设计应用程序以使其支持 IPv6。有必要将 IP 地址和 CIDR 块(也是 BGP NLRI,但这是另一个故事)存储在 MySQL 数据库中。我一直使用 INT 表示 IPv4 + TINYINT 表示 masklen,但 IPv6 是 128 位。

什么方法最适合这个? 2xBIGINT? CHAR(16) 用于二进制存储? CHAR(39) 用于文本存储? 8xSMALLINT 在专用表中?

你会推荐什么?

有帮助吗?

解决方案

我不确定MySQL的正确答案是什么,因为它本身还不支持IPv6地址格式(尽管“ WL#798:MySQL IPv6支持”表明它将在MySQL v6.0中,当前的文档没有'那个回来了。)

然而,你建议的那些我建议去2 * BIGINT,但要确保它们是UNSIGNED。 IPv6中的/ 64地址边界有一种自然的分裂(因为a / 64是最小的网络块大小),它可以很好地与之对齐。

其他提示

请注意,IPv6地址的最大长度(包括范围标识符)是标准C标头中INET6_ADDRSTRLEN定义的46字节。对于Internet使用,您应该可以忽略区域标识符(%10,# eth0等),但是当 getaddrinfo 返回比预期更长的结果时,请注意。

如果您倾向于 char(16),请务必使用 binary(16)。binary(n) 没有排序规则或字符集的概念(或者更确切地说,它是具有“binary”字符集/排序规则的 char(n))。mysql 中 char 的默认值是 latin1_swedish_ci,这意味着它将尝试对 latin1 中有效代码点的字节值进行不区分大小写的排序和比较,这将导致各种意想不到的问题。

另一种选择是使用无符号十进制 (39, 0) 零填充,效率不如两个 bigint(十进制在当前版本的 mysql 中每九位数字使用 4 个字节),但允许您将其全部保留在一列中并打印很好。

我会选择完整的39个字符“标准”。印刷格式: -

"2001:0db8:85a3:0000:0000:8a2e:0370:7334"

40,使用空终止符。

这是* nix命令行工具使用的格式,IPV6地址的格式是正常(?)报告的。

程序使用的IP地址是否有意义?或者你最好存储文本表示?此外,使用IPv6,您不太可能一般使用该地址,更可能使用主机名。这是否相关取决于应用程序,部分原因。 CHAR(16)将是一个糟糕的选择; char用于字符数据,不喜欢在IPv6地址中普遍存在的大字零字节流。 2 x BIGINT会不舒服 - 两个字段真的是一个(加上存储大端或小端的值?)。我使用了固定大小的BINARY类型,或者如果不可用,则使用blob类型。

我正在使用最长前缀匹配的项目,因此我将地址分成4个整数用于IPv4地址。它运作良好。我将其扩展到IPv6地址。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top