• redis范围查询应用 数据库 数据库学习 Redis redis范围查询的方法


    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"

  • 相关阅读:
    后端结对编程报告(2018.6.6)
    Burn Down Chart(2018.6.4~2018.6.10)
    C#多线程List的非线程安全性
    C#泛型参数多线程与复杂参数多线程
    Java学习之App开发公司手机端设想
    Java学习之SpringBoot整合SSM Demo
    Java学习之Mysql结构优化
    Java学习之Dubbo+ZooKeeper分布式服务Demo
    C# 面向切面编程--监控日志记录方案
    C# 通用类型转换方法
  • 原文地址:https://www.cnblogs.com/2881064178dinfeng/p/7091009.html
Copyright © 2020-2023  润新知