我有很多不同提供商的IP范围。例如
P1: 192.168.1.10 - 192.168.1.50, 192.168.2.16 - 192.168.2.49, P2: 17.36.15.34 - 17.36.15.255, P3: ...
我将此IP转换为int32:
P1: 3232235786 - 3232235826, 3232236048 - 3232236081, etc
我的任务: 通过用户IP地址查找提供者名称(例如192.168.2.20(3232236052))
在MySQL中很简单:
select name from ip_ranges where l_ip <= user_ip and user_ip <= r_ip
Redis怎么做?
这取决于您是否认为您的IP范围可以重叠。如果不是,则解决方案非常简单:
例:
这是我的提供者。他们每个人都有一个ID标识。请注意,我可以为每个提供程序添加更多属性:
> hmset providers:1 name P1 min 3232235786 max 3232235826 OK > hmset providers:2 name P3 min 1232235786 max 1232235826 OK > hmset providers:3 name P3 min 2232235786 max 2232235826 OK > hmset providers:4 name P4 min 4232235786 max 4232235826 OK
每次在系统中添加提供程序时,都必须维护索引(手动:这是Redis,而不是关系数据库)。分数是最大值,成员是范围的ID。
> zadd providers:index 3232235826 1 1232235826 2 2232235826 3 4232235826 4 (integer) 4 > zrange providers:index 0 -1 1) "2" 2) "3" 3) "1" 4) "4"
现在要查询与IP地址相对应的唯一范围,您需要2次往返:
> zrangebyscore providers:index 3232235787 +inf LIMIT 0 1 1) "1" > hgetall providers:1 1) "name" 2) "P1" 3) "min" 4) "3232235786" 5) "max" 6) "3232235826"
然后,客户端程序只需检查您的IP大于或等于返回范围的最小地址即可。
现在,如果您认为范围可以重叠,则解决方案要复杂得多,并且已经在此处进行了说明。