如何在关系数据库中存储与IPv6兼容的地址

aze*_*ole 34 mysql ipv6

我怎么做?

现在,IPv6将不会被使用,但我需要设计应用程序以使其为IPv6做好准备.有必要在MySQL数据库中存储IP地址和CIDR块(也是BGP NLRI,但这是另一个故事).我总是使用INT for IPv4 +一个TINYINT用于masklen,但IPv6是128位.

最适合的方法是什么?2xBIGINTCHAR(16)用于二进制存储?CHAR(39)用于文本存储?8xSMALLINT在专门的桌子?

你会推荐什么?

Aln*_*tak 21

我不确定哪个是MySQL 的正确答案,因为它本身还不支持IPv6地址格式(尽管" WL#798:MySQL IPv6支持 "表明它将在MySQL v6.0中出现,目前文档不支持这一点).

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

  • 实际上 - 如果我这样做,我会将_first_ bigint保留为IPv4的NULL,或者使用单独的字段.这样,IPv4部分出现在最不重要的单词中. (9认同)
  • 如果我这样做,我会将IPv4地址存储在IPv6地址的V4COMPAT格式中,即在::/96范围内. (8认同)
  • 做出最终决定:如果第二个bigint为NULL,则为2xBIGINT,则表示IPv4 (5认同)
  • 你不能只使用两个BIGINT,你必须使用两个BIGINT UNSIGNED.如果你采用FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF例如,将它分成两半并将每一边转换为它的整数表示将解析为两个值18,446,744,073,709,551,615.这是无符号64位整数的最大值. (5认同)

ʞɔı*_*ɔıu 6

如果你倾向于char(16),那么肯定使用二进制(16).binary(n)没有归类或字符集的概念(或者更确切地说,它是具有'binary'的charset/collat​​ion的char(n).mysql中char的默认值是latin1_swedish_ci,这意味着它将尝试对latin1中有效代码点的字节值进行不区分大小写的排序和比较,这将导致各种意外问题.

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


Ste*_*e-o 6

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