博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redis范围查询应用 数据库 数据库学习 Redis redis范围查询的方法
阅读量:5265 次
发布时间:2019-06-14

本文共 2761 字,大约阅读时间需要 9 分钟。

redis范围查询应用。

需求

根据IP找到对应的城市

原来的解决方案

oracle表(ip_country):

查询IP对应的城市:

1.把a.b.c.d这样格式的IP转为一个数字,例如为把210.21.224.34转为3524648994

2. select city from ip_country where ipstartdigital <= 3524648994 and 3524648994 <=ipenddigital

redis解决方案

我们先把上面的表简化一下:

id city min max

1 P1 0 100
2 P2 101 200
3 P3 201 300
4 P4 301 400

(注意:min/max组成的range之间不能有重叠)

主要思路就是用hmset存储表的每一行,并为每一行建立一个id(作为key)

然后把ip_end按顺序从小到大存储在sorted set当中,score对应该行的id

查询时,利用redis sorted set的范围查询特性,从sorted set中查询到id,再根据id去hmget

实验

//存储表的每一行

127.0.0.1:6379> hmset {ip}:1 city P1 min 0 max 100
OK
127.0.0.1:6379> hmset {ip}:2 city P2 min 101 max 200
OK
127.0.0.1:6379> hmset {ip}:3 city P3 min 201 max 300
OK
127.0.0.1:6379> hmset {ip}:4 city P4 min 301 max 400
OK
//建立sorted set(member-score)
127.0.0.1:6379> zadd {ip}:end.asc 100 1 200 2 300 3 400 4
(integer) 4
127.0.0.1:6379> zrange {ip}:end.asc 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
//查询对应的区间(score)
127.0.0.1:6379> zrangebyscore {ip}:end.asc 90 +inf LIMIT 0 1
1) "1"
127.0.0.1:6379> zrangebyscore {ip}:end.asc 123 +inf LIMIT 0 1
1) "2"
127.0.0.1:6379> zrangebyscore {ip}:end.asc 100 +inf LIMIT 0 1
1) "1"
//解释:
//zrangebyscore {ip}:end.asc 90 +inf LIMIT 0 1
//表示查找大于等于90的第一个值。(+inf在Redis中表示正无穷大)
//该语句返回值score=1,与hmset当中的id对应,因此可以通过hmget查找城市了:
//查找城市
127.0.0.1:6379> hmget {ip}:1 city
1) "P1"

注意在设计redis key时,采用了统一的前缀:{ip}

这是为了使得这些IP相关的数据都落在同一台redis server中(我们的redis以集群形式部署且采取一致性哈希),往后数据迁移什么的会更方便

实操

从数据库中导出的得到的文本是这样的(选取几行为例子):

ipcountry_tab_orderby_end_asc.txt:

"IPSTART" "IPSTARTDIGITAL" "IPEND" "IPENDDIGITAL" "COUNTRY" "CITY" "TYPE" "REGISTRY" "ADRESS" "PROVINCE"

"1.184.0.0" 28835840 "1.184.127.255" 28868607 "中国" "广州市" "" "" "" "广东省"
"1.184.128.0" 28868608 "1.184.255.255" 28901375 "中国" "广州市" "" "" "" "广东省"
"1.185.0.0" 28901376 "1.185.95.255" 28925951 "中国" "南宁市" "" "" "" "广西省"

1.生成批量的hmset命令及zadd命令

写个小程序来生成:

import java.io.File;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
public class IpCountryRedisImport {
public static void main(String[] args) throws IOException {
File file = new File("E:/doc/ipcountry_tab_orderby_end_asc.txt");
File hmsetFile = new File("E:/doc/ip_country_redis_cmd.txt");
File zaddFile = new File("E:/doc/ip_country_redis_zadd.txt");
List lines = FileUtils.readLines(file);
int i = 0;
StringBuilder rows = new StringBuilder();
StringBuilder ends = new StringBuilder();
for (String str : lines) {
if (StringUtils.isEmpty(str)) {
continue;
}
//skip first line
if (i == 0) {
i++;
continue;
}
i++;
//"IPSTART" "IPSTARTDIGITAL" "IPEND" "IPENDDIGITAL" "COUNTRY" "CITY" "TYPE" "REGISTRY" "ADRESS" "PROVINCE"

转载于:https://www.cnblogs.com/2881064178dinfeng/p/7091009.html

你可能感兴趣的文章
VI 摘要
查看>>
【转载】腾讯云安全组如何开放3306端口让Mysql可访问
查看>>
MySQL性能优化的最佳20+条经验
查看>>
vue学习之router
查看>>
SharePoint2010 skill
查看>>
Eclipse+minGW+Msys 调试 ffmpeg(转)
查看>>
Codeforces Round #155 (Div. 2)
查看>>
HDU 2852 KiKi's K-Number(离线+树状数组)
查看>>
Bicolorings - codeforce
查看>>
脚本和脚本包有什么区别?
查看>>
使用virtualbox 配置 linux host-only虚拟主机连接外网(转载)
查看>>
关于用 random 生成伪随机数的一个手笔
查看>>
bootstrap 菜单之手风琴效果
查看>>
Function-JS
查看>>
常用的SQL 语句
查看>>
Storm安装部署
查看>>
在PHP中读取二进制文件
查看>>
Linux CentOS6系统安装最新版本Node.js环境及相关文件配置
查看>>
编程常识科普
查看>>
线段树模板
查看>>