在数据库中存储IP的最佳方法是什么?

问题描述:

在MySQL数据库中存储IP地址的最佳字段类型和长度是多少?在数据库中存储IP的最佳方法是什么?

那么IPv6呢?

+0

请参阅这里的讨论:http://stackoverflow.com/questions/444966/working-with-ipv6-addresses-in-php – 2011-02-13 07:54:49

+0

谢谢,这很好 – Mike 2011-02-13 09:19:02

将ip存储为INT(11) UNSIGNED,然后使用INET_ATONINET_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*/ 
+6

在PHP方面,你可以尝试`ip2long`和`long2ip`功能。 – Thai 2011-02-13 06:00:23

+0

我正在使用$ _SERVER ['REMOTE_ADDR']。所以我会做“INSERT表(IP)VALUES(INET_ATON($ _ SERVER ['REMOTE_ADDR']));” ? – Mike 2011-02-13 06:02:15

这取决于你想用它做什么,但可能是最简单的方法是将其表示为一个字符串。并且this question涵盖了需要多少个字符来处理它。 (这是45)。

我完全Scrum的梅斯特同意最好方法是在INET功能使用INT(11) UNSIGNED具有存储/检索,但有时如果你不打算通过子网中查询您可以选择VARCHAR(45)

如果您计划通过IP地址搜索数据库,那么INT将更快地进行查询。如果你只是存储显示(例如在日志输出中),那么字符串会更好,因为你不需要来回转换它。

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。

如果您希望支持IPv6和IPv4,请将其存储为BINARY(16),然后在将IP地址插入数据库之前转换IP地址。例如,在PHP(通常用于MySQL的语言)中,您可以使用inet_pton()函数执行此操作。