zoukankan      html  css  js  c++  java
  • Redis:三种特殊数据类型

    Geospatal 地理位置

    Reids的 Geo 在 Redis3.2 版本就推出了!这个功能可以推算地理位置的信息,两地之间的距离,方圆几里的人!

    可以查询一些测试数据(城市的纬度和经度):http://www.jsons.cn/lngcodeinfo/0706D99C19A781A3/

     

    官方文档:https://www.redis.net.cn/order/3685.html

    只有六个命令:

    1、geoadd:添加地理位置

    • 格式:geoadd key longitude latitude member [longitude latitude member....]:添加城市的经纬度信息

      • longitude:纬度

      • latidude:经度

      • member:成员/元素

    # geoadd添加地理位置,使用5个数据进行测试
    127.0.0.1:6379> geoadd china:city 116.40 39.90 beijing
    (integer) 1 
    127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai 
    (integer) 1 
    127.0.0.1:6379> geoadd china:city 106.50 29.53 chongqing 114.05 22.52 shenzhen 
    (integer) 2
    127.0.0.1:6379> geoadd china:city 120.16 30.24 hangzhou 108.96 34.26 xian 
    (integer) 2

    规则:两级无法直接添加,我们一般会下载城市数据,直接通过java程序一次性导入!

    有效的经度从-180度到180度。

    有效的纬度从-85.05112878度到85.05112878度

    如果纬度和经度超过范围会报错!

    2、geopos:获取当前定位

    • 格式:geopos key member [member...]:查询一个或多个城市的经纬度

    是一个坐标值,纬度和经度!

    127.0.0.1:6379> geopos china:city beijing    # 获取指定的城市的纬度和经度
    1) 1) "116.39999896287918091"
       2) "39.90000009167092543"
    127.0.0.1:6379> geopos china:city hangzhou
    1) 1) "120.1600000262260437"
       2) "30.2400003229490224"

    3、geodist:计算两人之间的距离

    • 格式:geodist key member1 member2 [unit]:计算两个城市/人h之间的举例

      • unit表示单位

    单位:

    • m 表示单位为米。
    • km 表示单位为千米。
    • mi 表示单位为英里。
    • ft 表示单位为英尺。
    127.0.0.1:6379> geodist china:city beijing shanghai km    # 查看北京到上海的直线距离
    "1067.3788"
    127.0.0.1:6379> geodist china:city beijing hangzhou km    # 查看北京到杭州的直线距离
    "1127.3378"

    4、georadius:以经纬度为中心查找半径以内的元素

    1. 指定半径:可以做到比如:找附近的人,通过半径来搜寻;

    2. 设置查询数量:如果找到了几万人,那么显示不下,肯定会只显示几个。

    • 格式:georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash]

    # 以110,30这个经纬度未中心,寻找附近1000km的城市
    127.0.0.1:6379> georadius china:city 110 30 1000 km
    1) "chongqing"
    2) "xian"
    3) "shenzhen"
    4) "hangzhou"
    # 以110,30这个经纬度未中心,寻找附近500km的城市
    127.0.0.1:6379> georadius china:city 110 30 500 km
    1) "chongqing"
    2) "xian"
    
    # 以110,30这个经纬度未中心,寻找附近500km的城市,显示到本身的直线距离
    127.0.0.1:6379> georadius china:city 110 30 500 km withdist
    1) 1) "chongqing"
       2) "341.9374"
    2) 1) "xian"
       2) "483.8340"
       
    # 显示到本身的直线距离,显示该城市的经纬度信息
    127.0.0.1:6379> georadius china:city 110 30 500 km withdist withcoord
    1) 1) "chongqing"
       2) "341.9374"
       3) 1) "106.49999767541885376"
          2) "29.52999957900659211"
    2) 1) "xian"
       2) "483.8340"
       3) 1) "108.96000176668167114"
          2) "34.25999964418929977"
    
    # 指定寻找的数量
    127.0.0.1:6379> georadius china:city 110 30 500 km withdist withcoord count 1
    1) 1) "chongqing"
       2) "341.9374"
       3) 1) "106.49999767541885376"
          2) "29.52999957900659211"
    127.0.0.1:6379> georadius china:city 110 30 500 km withdist withcoord count 2
    1) 1) "chongqing"
       2) "341.9374"
       3) 1) "106.49999767541885376"
          2) "29.52999957900659211"
    2) 1) "xian"
       2) "483.8340"
       3) 1) "108.96000176668167114"
          2) "34.25999964418929977"

    5、georadiusbymember:以元素为中心查找半径以内的元素

    # 找出位于指定元素周围的其他元素!
    127.0.0.1:6379> georadiusbymember china:city beijing 1000 km
    1) "beijing"
    2) "xian"
    127.0.0.1:6379> georadiusbymember china:city shanghai 400 km
    1) "hangzhou"
    2) "shanghai"

    6、geohash:以字符串表示返回的经纬度

    # 将二维的经纬度转换为一维的字符串,如果两个字符串越接近,那么则距离越近!
    127.0.0.1:6379> geohash china:city beijing chongqing
    1) "wx4fbxxfke0"
    2) "wm5xzrybty0"

    底层

    • geo底层的实现原理其实就是Zset!我们可以使用Zset命令来操作geo!

    127.0.0.1:6379> zrange china:city 0 -1    # 利用zset查看地图中全部的元素
    1) "chongqing"
    2) "xian"
    3) "shenzhen"
    4) "hangzhou"
    5) "shanghai"
    6) "beijing"
    127.0.0.1:6379> zrem china:city xian    # 移除指定的元素,比如说你不想开定位了,那么就会删除你的位置信息
    (integer) 1
    127.0.0.1:6379> zrange china:city 0 -1
    1) "chongqing"
    2) "shenzhen"
    3) "hangzhou"
    4) "shanghai"
    5) "beijing"

    Hyperloglog 计数

    简介

    Redis 2.8.9 版本就更新了 Hyperloglog 数据结构!

    Redis Hyperloglog 基数统计的算法!

    什么是基数?

    两个集合,保留不重复的元素,

    A {1,3,5,7,8,7}

    B{1,3,5,7,8}

    基数(保留不重复的元素) = 5 = {1,3,5,7,8},可以接受误差!

     

    网页的 UV (一个人访问一个网站多次,但是还是算作一个人!)

    • 传统方式

    传统的方式,set保存用户的id,因为set集合是不重复的,相同的会覆盖,然后就可以统计set中的元素数量来做标准判断!

    这个方式如果保存大量的用户id,就会比较麻烦、占用内存!我们的目的就是为了计数,而不是保存用户id。

    Hyperloglog它的优点:占用的内存是固定,2^64 不同的元素的基数,只需要花费 12KB内存!如果要从内存角度比较的话 Hyperloglog 首选!

    官方说会有 0.81% 错误率! 统计UV任务,可以忽略不计的!

    测试

    • pfadd key element [element...]

    • pfcount key

    • pfmerge destkey sourcekey [sourcekey....]

    127.0.0.1:6379> pfadd keys a a a b v v c    # 创建第一组带有重复数据的元素
    (integer) 1
    127.0.0.1:6379> pfcount keys
    (integer) 4
    127.0.0.1:6379> pfadd mykey a b c e f g h i j # 创建第一组元素 mykey
    (integer) 1
    127.0.0.1:6379> pfcount mykey    # 统计 mykey 元素的基数数量
    (integer) 9
    127.0.0.1:6379> pfadd mykey2 i j z x c v b n m
    (integer) 1
    127.0.0.1:6379> pfcount mykey2
    (integer) 9
    127.0.0.1:6379> pfmerge mykey3 mykey mykey2    # 合并两组 mykey mykey2 => mykey3 并集
    OK
    127.0.0.1:6379> pfcount mykey3    # 看并集的数量
    (integer) 14

    如果允许容错,那么一定可以使用 Hyperloglog

    如果不允许容错,就使用 set 或者 自己的 数据类型即可

    Bitmap

    位存储

    比如:中国疫情,要统计全国的疫情感染人数,我们只需用 14亿个 0去存储,然后感染的一个就将一个 0 改为 1

    14亿个0很大吗?不大只需要1000MB就可以存放83亿个bit位,一个字节 = 8 bit,每个bit位可以存放一个0.

    所以,Bitmap位图,根据位存储的数据结构算法,可以发现只有 0 和 1两个状态!

    那么就可以应用:

    • 网站用户的活跃、不活跃

    • 员工 365 天的打卡情况!

    • ...

    测试

    • 使用Bitmap 来记录 周一到周日的打卡!

    1、使用0和1表示打卡和未打卡:周一:1 周二:0 周三:0 周四:1 ......

    • setbit key offset value

      • offset表示偏移量,位存储,第0位,第1位...依次存储

    127.0.0.1:6379> setbit sign 0 1
    (integer) 0
    127.0.0.1:6379> setbit sign 1 0
    (integer) 0
    127.0.0.1:6379> setbit sign 2 0
    (integer) 0
    127.0.0.1:6379> setbit sign 3 1
    (integer) 0
    127.0.0.1:6379> setbit sign 4 1
    (integer) 0
    127.0.0.1:6379> setbit sign 5 0
    (integer) 0
    127.0.0.1:6379> setbit sign 6 0
    (integer) 0

    2、查看某一天是否打卡

    • 格式:getbit key offset

    127.0.0.1:6379> getbit sign 3
    (integer) 1
    127.0.0.1:6379> getbit sign 2
    (integer) 0

    3、统计操作,统计打卡的天数!

    • 统计这周的打卡记录,就可以看到是否是全勤,在做一些对应的处理!

    • 格式:bitcount key

    127.0.0.1:6379> bitcount sign
    (integer) 3
    致力于记录学习过程中的笔记,希望大家有所帮助(*^▽^*)!
  • 相关阅读:
    python requests 上传excel数据流
    No module named 'requests_toolbelt'
    code
    pytest 打印调试信息
    python3 获取日期时间
    Java单元测试之JUnit篇
    The import junit cannot be resolved解决问题
    什么是索引
    python3 ini文件读写
    js 测试题
  • 原文地址:https://www.cnblogs.com/zxhbk/p/13054485.html
Copyright © 2011-2022 走看看