Redis学习(三) -- 三种特殊数据类型geospatial、hyperloglog、bitmaps

Redis学习 -- 三种特殊数据类型geospatial、hyperloglog、bitmaps

  • 一、Geospatial类型
    • 1、添加地理位置
    • 2、获取指定位置的地理坐标
    • 3、获取另个指定位置之间的距离
    • 4、获取指定位置附近的位置
    • 5、将二维经纬度转为一维字符串
    • 6、删除一个位置元素
  • 二、Hyperloglog类型
    • 1、什么是hyperloglog?
    • 2、具体使用
  • 三、Bitmaps

一、Geospatial类型

这种类型指的就是地理位置,可以用来存储地理位置。
也可以推算地理位置的信息,两地之间的距离,方圆几里的人
详情可以参照官方文档

1、添加地理位置

将指定的地理空间位置(纬度、经度、名称)添加到指定的key中。该命令以采用标准格式的参数x,y,所以经度必须在纬度之前。
有效的经度从-180度到180度。
有效的纬度从-85.05112878度到85.05112878度。

127.0.0.1:6379> geoadd china:city 116.405289 39.904987 beijing 121.472641 31.231707 shanghai # 添加一个key为china:city 的 地理位置数据,里面包含名称为 beijing(经度:116.405289,纬度:39.904987) 以及名称为 shanghai(经度:121.472641,纬度:31.231707) 两个地理位置数据
(integer) 2
127.0.0.1:6379> geoadd china:city 120.619583 31.299379 suzhou # 添加一个key为china:city的地理位置数据,里面包含名称为 suzhou(经度:120.619583,纬度:31.299379)的地理位置数据
(integer) 1

在这里插入图片描述

2、获取指定位置的地理坐标

127.0.0.1:6379> geopos china:city beijing # 获取key为china:city 的一个位置名为beijing的地理坐标,返回的是经纬度
1) 1) "116.40528827905654907"
   2) "39.90498588819134085"
127.0.0.1:6379> geopos china:city shanghai suzhou # 获取key为china:city 的一个位置名为shanghai以及另一个位置名为suzhou的地理坐标,返回的是经纬度
1) 1) "121.47264093160629272"
   2) "31.23170744181923197"
2) 1) "120.61958044767379761"
   2) "31.29937942733126022"

3、获取另个指定位置之间的距离

此命令的时间复杂度为:O(log(N))
如果两个位置之间的其中一个不存在, 那么命令返回空值。
指定单位的参数 unit 必须是以下单位的其中一个:
m 表示单位为米。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。

如果用户没有显式地指定单位参数, 那么 GEODIST 默认使用米作为单位。
GEODIST 命令在计算距离时会假设地球为完美的球形, 在极限情况下, 这一假设最大会造成 0.5% 的误差。

# 获取key为china:city中的beijing位置和shanghai位置之间的距离,这里返回的数据单位是米
127.0.0.1:6379> geodist china:city beijing shanghai
"1067597.0432"
# 获取key为china:city中的beijing位置和shanghai位置之间的距离,这里返回的数据单位是千米
127.0.0.1:6379> geodist china:city beijing shanghai km
"1067.5970"

Redis学习(三) -- 三种特殊数据类型geospatial、hyperloglog、bitmaps_第1张图片

4、获取指定位置附近的位置

以给定的经纬度为中心,找出某一半径内的元素。可以用来找附近的人呀啥的
在给定以下可选项时, 命令会返回额外的信息:

  • WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。
  • WITHCOORD: 将位置元素的经度和维度也一并返回。
  • WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。
    这个选项主要用于底层应用或者调试, 实际中的作用并不大。

命令默认返回未排序的位置元素。 通过以下两个参数, 用户可以指定被返回位置元素的排序方式:

  • ASC: 根据中心的位置, 按照从近到远的方式返回位置元素。
  • DESC: 根据中心的位置, 按照从远到近的方式返回位置元素。
    Redis学习(三) -- 三种特殊数据类型geospatial、hyperloglog、bitmaps_第2张图片Redis学习(三) -- 三种特殊数据类型geospatial、hyperloglog、bitmaps_第3张图片
127.0.0.1:6379> georadius china:city 120 31 100 km
1) "suzhou"
127.0.0.1:6379> georadius china:city 120 31 300 km
1) "suzhou"
2) "shanghai"
127.0.0.1:6379> georadius china:city 120 31 100 km withdist
1) 1) "suzhou"
   2) "67.7285"
127.0.0.1:6379> georadius china:city 120 31 100 km withcoord
1) 1) "suzhou"
   2) 1) "120.61958044767379761"
      2) "31.29937942733126022"
127.0.0.1:6379> georadius china:city 120 31 300 km withdist desc
1) 1) "shanghai"
   2) "142.5774"
2) 1) "suzhou"
   2) "67.7285"
127.0.0.1:6379> georadius china:city 120 31 300 km withdist
1) 1) "suzhou"
   2) "67.7285"
2) 1) "shanghai"
   2) "142.5774"
127.0.0.1:6379> georadius china:city 120 31 300 km withdist count 1
1) 1) "suzhou"
   2) "67.7285"

现在我们思考下,上面的都是要给出具体的经纬度,然后以经纬度为中心,指定的半径内查找所有的元素,那么如果我们想根据存在redis里某个key的位置元素为中心,来查找呢,可以吗?可以的:
Redis学习(三) -- 三种特殊数据类型geospatial、hyperloglog、bitmaps_第4张图片

127.0.0.1:6379> georadiusbymember china:city suzhou 300 km
1) "suzhou"
2) "shanghai"
127.0.0.1:6379> georadiusbymember china:city suzhou 300 km withcoord
1) 1) "suzhou"
   2) 1) "120.61958044767379761"
      2) "31.29937942733126022"
2) 1) "shanghai"
   2) 1) "121.47264093160629272"
      2) "31.23170744181923197"

5、将二维经纬度转为一维字符串

Redis学习(三) -- 三种特殊数据类型geospatial、hyperloglog、bitmaps_第5张图片

127.0.0.1:6379> geohash china:city suzhou
1) "wttf0cbkpg0"
127.0.0.1:6379> geohash china:city suzhou shanghai
1) "wttf0cbkpg0"
2) "wtw3sjt9vs0"

6、删除一个位置元素

我们在官方文档中没有发现,这个类型有删除的命令,那么我们想删除一个位置元素要怎么办呢?其实这个类型底层是依据Zset类型的,所以我们试试看可否使用Zset类型的命令来操作:

127.0.0.1:6379> zrange china:city 0 -1
1) "suzhou"
2) "shanghai"
3) "beijing"
127.0.0.1:6379> zrem china:city beijing
(integer) 1
127.0.0.1:6379> geopos china:city beijing
1) (nil)

我们发现,zrem的命令真的把 beijing这个位置元素删了,符合预期!

二、Hyperloglog类型

1、什么是hyperloglog?

其实就是基数技术,那什么是基数呢?就是指一个集合中不同元素的个数。
redis hyperloglog 就是基数统计的算法。
可以想到的应用场景:
例如统计一个网页或者网站的访问量(同一个人的多次访问,还算一次访问)。

传统的方式,可以用Set集合来保存用户的id,但是如果用户量太大,就比较占用内存了。

hyperloglog的优点:占用的内存是固定的,2^64个不同元素的基数,只需要占用12kb内存。
但是会有0.81%的错误率,可以忽略不计。

2、具体使用

Redis学习(三) -- 三种特殊数据类型geospatial、hyperloglog、bitmaps_第6张图片

127.0.0.1:6379> pfadd mykey a b c d e f g h i j
(integer) 1
127.0.0.1:6379> pfcount mykey
(integer) 10
127.0.0.1:6379> pfadd mykey i j k l m n
(integer) 1
127.0.0.1:6379> pfcount mykey
(integer) 14
127.0.0.1:6379> pfadd mykey2 a b o p q
(integer) 1
127.0.0.1:6379> pfcount mykey2
(integer) 5
127.0.0.1:6379> pfmerge mykey3 mykey mykey2
OK
127.0.0.1:6379> pfcount mykey3
(integer) 17

三、Bitmaps

位存储
Bitmaps:位图,是一种数据结构,都是操作二级制位来记录。
这里我们使用打卡这个场景来作为一个例子,展示Redis中bitmaps的运用:
比如这里我们从周一到周日,分别用0-6来表示,然后打卡用1,没有打卡用0来表示:
Redis学习(三) -- 三种特殊数据类型geospatial、hyperloglog、bitmaps_第7张图片

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

上面的命令可以解释为:

  • 周一:打卡;
  • 周二:没打卡;
  • 周三:打卡;
  • 周四:打卡;
  • 周五:打卡;
  • 周六:没打卡;
  • 周日:打卡

现在我们查看某一天是否有打卡:

127.0.0.1:6379> getbit mykey 0
(integer) 1

在这里插入图片描述
这里是查看周一是否有打卡,返回的结果是1,表示打卡。

那现在我们要统计下,有几天打卡:
在这里插入图片描述

127.0.0.1:6379> bitcount mykey
(integer) 5

这里我们返回的就是mykey这个key中,有几位的结果是1,在这个场景下,就是周一到周日,有几天打卡了,显示的结果是5天。

由此,我们可以发现,Bitmaps这个类型可以用来存储那些只有两个状态的数据。

你可能感兴趣的:(redis,springboot,redis,java)