我该怎么做?
目前,IPv6不会被使用,但我需要设计应用程序以使其为IPv6做好准备。有必要在MySQL数据库中存储IP地址和CIDR块(也是BGP NLRI,但这是另一个故事)。我总是使用INT for IPv4 +一个TINYINT用于masklen,但IPv6是128位。
最适合的方法是什么? 2xBIGINT
? CHAR(16)
用于二进制存储? CHAR(39)
用于文本存储? 8xSMALLINT
在专门的表格中?
你会推荐什么?
答案 0 :(得分:19)
我不确定MySQL的正确的答案是什么,因为它本身还不支持IPv6地址格式(虽然“WL#798: MySQL IPv6 support”表明它会去在MySQL v6.0中,当前的文档不支持它。)
然而,你建议的那些我建议去2 * BIGINT,但要确保它们是UNSIGNED。 IPv6中的/ 64地址边界有一种自然的分裂(因为a / 64是最小的网络块大小),它可以很好地与之对齐。
答案 1 :(得分:6)
如果你倾向于char(16),肯定会使用二进制(16)。 binary(n)没有归类或字符集的概念(或者更确切地说,它是具有'binary'的charset / collation的char(n)。 mysql中char的默认值是latin1_swedish_ci,这意味着它将尝试对latin1中有效代码点的字节值进行不区分大小写的排序和比较,这将导致各种意外问题。
另一种选择是使用十进制(39,0)无符号的zerofill,效率不如两个bigint(十进制将在当前版本的mysql中每九个数字使用4个字节),但是允许你将它全部保存在一个专栏并打印出来。
答案 2 :(得分:6)
请注意,IPv6地址的最大长度(包括范围标识符)是标准C标头中INET6_ADDRSTRLEN定义的46字节。对于Internet使用,您应该可以忽略zone identifier(%10,#eth0等),但只要知道getaddrinfo返回的结果比预期的更长。
答案 3 :(得分:4)
我会选择完整的39个字符“标准”打印格式: -
"2001:0db8:85a3:0000:0000:8a2e:0370:7334"
40,使用空终止符。
这是* nix命令行工具使用的格式,IPV6地址的格式是正常(?)报告的。
答案 4 :(得分:1)
程序使用的IP地址是否有意义?或者你最好存储一个文本表示?此外,使用IPv6,您不太可能一般使用该地址,更可能使用主机名。这是否相关取决于应用程序,部分原因。 CHAR(16)将是一个糟糕的选择; char用于字符数据,不喜欢在IPv6地址中普遍存在的大字零字节流。 2 x BIGINT会不舒服 - 两个字段真的是一个(加上存储大端或小端的值?)。我使用了固定大小的BINARY类型,或者如果不可用,则使用blob类型。
答案 5 :(得分:1)
我正在使用最长前缀匹配的项目,因此我将地址分成4个整数用于IPv4地址。它运作良好。我将其扩展到IPv6地址。