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

在MySQL数据库中存储IP地址的最佳字段types和长度是多less?

那么IPv6呢?

将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*/ 

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

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

IPv6地址是128位(16字节),所以你需要一个足够大的字段来存储它。 此外,您可能需要一个字段来指示IP是IPv4还是IPv6(在IPv6中:: 192.168.4.10与IPv4中的192.168.4.10在数字上相同,但取决于您的应用程序,您可能需要区分这两者) 。

如果需要存储子网,则可能需要存储第一个地址,CIDR掩码和计算出的子网广播地址(广播地址)。 这将有助于search,所以你可以做这样的查询

 SELECT * FROM networks WHERE lowerBound<=MYIP AND upperBound>=MYIP 

如果您使用的是子网,您还应该自己计算下限,而不是仅仅依靠用户正确执行(伪代码):

 lowerBound = AND(networkAddress, subnetMask) upperBound = OR(lowerBound, complement(subnetMask)) 

这适用于IPv4和IPv6。

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

我完全同意Scrum Meister 最好的方法是在INET函数中使用INT(11) UNSIGNED和存储/检索,但有时如果你不打算通过子网查询,你可能会selectVARCHAR(45)