面试中关于MySQL的知识非常多,而如何储存IP地址又是经常被问到的一个。
避免“直接varchar类型不就得了”这样的零分回答。在这里手把手教你如何回答。
其实做任何程序设计都要在功能实现的基础上最大限度的优化性能。而数据库设计是程序设计中不可忽略的一个重要部分,所以巧存IP地址可以一定程度获得很大提升。
刚刚好,MySQL是有专门的字段和函数来存取用户的IP地址的,那就是 int unsigned
。你没有看错,就是无符号int型。
inet_aton 把ip转为无符号整型(最大10位)
inet_ntoa 把整型的ip转回地址
ip地址存取前类型:string点隔ip(如’192.168.0.1’)
数据库中存储类型:int(10) unsigned
插入几条数据
INSERT INTO `user` ( `name`, `ip` )
VALUES
( 'a', inet_aton( '127.0.0.1' ) ),
( 'b', inet_aton( '192.168.1.1' ) ),
( 'c', inet_aton( '255.255.255.1' ) );
查询显示地址
select id,name,inet_ntoa(ip) as ip from `user`;
使用int类型存储IP比varchar
类型存储IP地址性能要提升很多,减少不少空间。因为varchar
是可变长形,需要多余的一个字节存储长度。另外int型在逻辑运算上要比varchar
速度快。这也符合一项优化原则:字段类型定义使用最合适(最小),最简单的数据类型。
如果需要找出在某个网段的用户(例如:192.168.1.1 ~ 192.168.1.100),可以利用php的long2ip()
方法,把ip地址转为整型,再进行where区间比较。也提供了long2ip()
的方法转回IP。
使用long2ip()
需要注意出现负数的情况,IP转换成的整型值太大超出了整型的范围,所以变成负数。
//输出时用%u来格式化为无符号整型。
$ip = '192.168.101.100';
$ip_long = sprintf('%u',ip2long($ip));
echo $ip_long.PHP_EOL; // 3232261476
echo long2ip($ip_long); // 192.168.101.100