将IP存储在数据库中的最佳方法?
Posted
技术标签:
【中文标题】将IP存储在数据库中的最佳方法?【英文标题】:Best way to store IP in database? 【发布时间】:2011-06-26 08:16:23 【问题描述】:在 mysql 数据库中存储 IP 地址的最佳字段类型和长度是多少?
IPv6 怎么样?
【问题讨论】:
在这里查看讨论:***.com/questions/444966/… 【参考方案1】:将 ip 存储为 INT(11) UNSIGNED
,然后使用 INET_ATON
和 INET_NTOA
函数存储/检索 ip 地址。
示例代码:
INSERT table(ip) VALUES (INET_ATON('192.168.0.1')); /*ip = 3232235521*/
SELECT INET_NTOA(ip) As IPAddress FROM table; /*IPAddress = 192.168.0.1*/
【讨论】:
在 php 端你可以尝试ip2long
和long2ip
函数。
我认为这不会支持 IPv6。
是的,OP 显然没有考虑 IPv6。但他应该是。
为什么要处理 INET 函数。基本上,您正在记录从网络堆栈传递给您的 IP 地址。只需将其存储为给您的(希望作为字符串)。这样一来,当 IPv8 到来时,您就不必更改数据库架构。
不需要(11)
。这只是向 mysql 提示您希望显示多少位数。在内部,它总是一个完整的 32 位整数。【参考方案2】:
这取决于你想用它做什么,但可能最简单的方法是将它表示为一个字符串。 this question 涵盖了处理它需要多少个字符。 (45 岁)。
【讨论】:
是的 (+1) 就对了。目前我们有两种形式的 IP 地址(IPv4 和 IPv6)。谁知道未来20年会出现什么样的新形式。只需将其存储为 vchar 即可,不用担心。 感谢理查德的支持。我认为我们不需要担心 IPv6 之外的问题,但除了 IPv4 之外还必须支持 IPv6。 @RichardSchneider,IPv6 的设计寿命超过 200 年【参考方案3】:如果您希望同时支持 IPv6 和 IPv4,请将其存储为 BINARY(16)
并在将其插入数据库之前转换 IP 地址。例如,在 PHP(MySQL 常用语言)中,您可以使用 inet_pton()
函数来完成此操作。
【讨论】:
【参考方案4】:IPv6 地址是 128 位(16 字节),因此您需要一个足够大的字段来存储它。此外,您可能需要一个字段来指示 IP 是 IPv4 还是 IPv6(IPv6 中的::192.168.4.10 在数字上与 IPv4 中的 192.168.4.10 相同,但根据您的应用程序,您可能需要区分两者) .
如果您需要存储子网,您可能需要存储子网的第一个地址、CIDR 掩码和计算的上位地址(广播地址)。这将有助于搜索,因此您可以进行这样的查询
SELECT * FROM networks WHERE lowerBound<=MYIP AND upperBound>=MYIP
如果您使用子网,您还应该自己计算下限,而不仅仅是依靠用户正确执行(伪代码):
lowerBound = AND(networkAddress, subnetMask)
upperBound = OR(lowerBound, complement(subnetMask))
这适用于 IPv4 和 IPv6。
【讨论】:
【参考方案5】:如果您打算按 IP 地址搜索数据库,那么查询 INT 会快得多。如果您只是为了显示而存储(例如,在日志输出中),那么字符串会更好,因为您不需要来回转换它。
【讨论】:
【参考方案6】:我完全同意 Scrum Meister 的观点,即最佳方法是在 INET 函数中使用带有存储/检索功能的 INT(11) UNSIGNED
,但有时如果您不打算通过子网查询,您可能选择VARCHAR(45)
【讨论】:
为什么要处理 INET 函数。基本上,您正在记录从网络堆栈传递给您的 IP 地址。只需将其存储为给您的(希望作为字符串)。这样一来,当 IPv8 到来时,您就不必更改数据库架构。 我同意 - 网络实践中的“最佳”方式是使用 INET 函数,这样您就可以通过 subnet 进行查询...如果您不需要这种功能,您最好的选择是存储为足够大以容纳 IPv6 的字符串。以上是关于将IP存储在数据库中的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章
当 API 调用需要以纯文本形式发送密码时,将密码存储在数据库中的最佳方法是啥?