要为IP地址使用哪种MySQL数据类型?
要为IP地址使用哪种MySQL数据类型?
可能是重复问题:
我想从$_SERVER['REMOTE_ADDR']
和其他一些$_SERVER
变量中获取IP地址,哪种数据类型是正确的?
是VARCHAR(n)
吗?
在MySQL中,为IP地址选择哪种数据类型?
在MySQL中,有两种选择(对于IPv4地址):
1. 使用varchar(15)数据类型,将IP地址作为字符串存储。例如:192.128.0.15。
2. 使用integer数据类型(4个字节),将IP地址转换为整数。例如:3229614095。
第二种解决方案在数据库中占用的空间更小,可能是更好的选择,即使在存储和检索数据时需要进行一些操作(从/到字符串的转换)。
关于这些操作,在PHP端可以使用ip2long()和long2ip()函数,或者在MySQL端可以使用inet_aton()和inet_ntoa()函数。
但是我听说$_SERVER['REMOTE_ADDR']中的IP地址也可以是IPv6地址。那么如何将类似xxx.xx.xx.xxx的IP地址转换为你所说的4字节整数?
对于IPv6地址,你将需要超过4个字节。根据secure.wikimedia.org/wikipedia/en/wiki/IPv6的说法,IPv6地址使用128位,因此需要16个字节。在PHP中,可以使用inet-pton()函数。
那么对于16个字节,应该选择哪种数据类型?
考虑到整数数据类型中没有超过8个字节的类型(参见dev.mysql.com/doc/refman/5.0/en/numeric-types.html),我认为你将不得不回退到某种基于字符的类型。
或者其他人可能会遇到这个问题:192*256*256*256 + 128*256*256 + 15 = 3229614095。
可以使用BINARY(128)来存储IPv6地址。
在MySQL中,存储IP地址可以使用VARCHAR数据类型将其存储为字符串,也可以考虑将其存储为长整数INT(11) UNSIGNED。可以使用MySQL的INET_ATON()函数将IP地址转换为整数表示形式。这样做的好处是可以方便地进行比较操作,例如BETWEEN查询。
解决方法:
1. 使用VARCHAR数据类型存储IP地址作为字符串。
2. 使用INT(11) UNSIGNED数据类型存储IP地址作为长整数。
3. 使用MySQL的INET_ATON()函数将IP地址转换为整数表示形式。
使用INET_ATON()函数的示例代码如下:
SELECT INET_ATON('192.168.0.1');
以上是解决在MySQL中选择何种数据类型存储IP地址的方法。
在MySQL中,存储IP地址的数据类型取决于IP地址的类型。对于IPv4地址,其长度为4个字节,可以使用4个字节的INT UNSIGNED类型来存储。同时,可以使用INET_ATON和INET_NTOA函数来进行IPv4地址的转换。
示例代码如下所示:
`ipv4` INT UNSIGNED INSERT INTO `table` (`ipv4`) VALUES (INET_ATON("127.0.0.1")); SELECT INET_NTOA(`ipv4`) FROM `table`;
对于IPv6地址,可以使用BINARY(16)类型来存储。同时,可以使用PHP中的inet_pton和inet_ntop函数进行IPv6地址的转换。
示例代码如下所示:
`ipv6` BINARY(16) 'INSERT INTO `table` (`ipv6`) VALUES ("'.mysqli_real_escape_string(inet_pton('2001:4860:a005::68')).'")' 'SELECT `ipv6` FROM `table`' $ipv6 = inet_pton($row['ipv6']);
需要注意的是,MySQL 5.1的语法是INT UNSIGNED,而不是UNSIGNED INT。
如果想要查找具有相同子网的地址,可以使用下面的方法:Check if IP is in subnet
如果IP地址既可以是IPv4地址也可以是IPv6地址,可以使用INET6_ATON和INET6_NTOA函数进行转换。
在以二进制格式存储IPv6地址时,可以使用HEX()和UNHEX()函数来提高可读性。同时,如果基于IP地址进行查询,需要在该列上使用索引,并确保查询实际上使用了该索引。
更多相关信息可以参考rathishkumar.in/2017/08/how-to-store-ip-address-in-mysql.html。