Redis的三种特殊数据类型

一、Geospatial 地理位置

朋友的定位,附近的人,打车距离计算。

可以查询一些测试数据:https://jingweidu.51240.com/

只有6个相关的命令

image-20201014121614547

1、Geoadd

# Geoadd 添加地理位置
# 规则:两极无法直接添加,我们一般会下载城市数据,通过java程序导入
# 参数 key 值(经度、纬度、名称)
# 有效的经度从-180度到180度。
# 有效的纬度从-85.05112878度到85.05112878度。
# 当坐标位置超出上述指定范围时,该命令将会返回一个错误。
127.0.0.1:6379> GEOADD china:city 116.40 39.90 beijing
(integer) 1
127.0.0.1:6379> GEOADD china:city 112.98 28.25 changsha
(integer) 1
127.0.0.1:6379> keys *
1) "china:city"
127.0.0.1:6379> GEOADD china:city 106.54 29.40 chongqing
(integer) 1

2、Geopos 获得当前的定位,一定是一个坐标值!

127.0.0.1:6379> GEOPOS china:city changsha beijing # 获取指定的城市的经度和纬度
1) 1) "112.9800000786781311"
   2) "28.25000087963665152"
2) 1) "116.39999896287918091"
   2) "39.90000009167092543"

3、Geodist

两个坐标之间的距离

单位如下:

  • m 表示单位为米。
  • km 表示单位为千米。
  • mi 表示单位为英里。
  • ft 表示单位为英尺。
127.0.0.1:6379> GEODIST china:city beijing changsha m # 北京到长沙的直线距离,单位米
"1333235.2339"
127.0.0.1:6379> GEODIST china:city beijing changsha km # 北京到长沙的直线距离,单位千米
"1333.2352"
127.0.0.1:6379> GEODIST china:city changsha chongqing km
"640.3536"

4、Georadius 以给定的经纬度为中心, 找出某一半径内的元素

找我附近的人?(获得所有附近的人的地址,定位!)通过半径来查询!

127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km # 以这个坐标为半径查找方圆1000km key里面存在的城市
1) "chongqing"
2) "changsha"
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withcoord withdist # 后面的参数1:查直线距离、 参数2:坐标
1) 1) "chongqing"
   2) "340.8679"
   3) 1) "106.54000014066696167"
      2) "29.39999880018641676"
2) 1) "changsha"
   2) "348.8645"
   3) 1) "112.9800000786781311"
      2) "28.25000087963665152"
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withcoord withdist count 1 # 参数3:指定查几个
1) 1) "chongqing"
   2) "340.8679"
   3) 1) "106.54000014066696167"
      2) "29.39999880018641676"

5、Georadiusbymember 找出位于指定范围内的元素,中心点是由给定的位置元素决定

127.0.0.1:6379> GEORADIUSBYMEMBER china:city changsha 1000 km withcoord withdist # 查出长沙附近1000km的城市的直线距离和坐标
1) 1) "changsha"
   2) "0.0000"
   3) 1) "112.9800000786781311"
      2) "28.25000087963665152"
2) 1) "chongqing"
   2) "640.3536"
   3) 1) "106.54000014066696167"
      2) "29.39999880018641676"

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

127.0.0.1:6379> ZRANGE china:city 0 -1 # 查看地图中全部的元素
1) "chongqing"
2) "changsha"
3) "beijing"
127.0.0.1:6379> ZREM china:city beijing # 移除指定的元素
(integer) 1
127.0.0.1:6379> ZRANGE china:city 0 -1
1) "chongqing"
2) "changsha"

二、Hyperloglog 基数统计

什么是基数?

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

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

基数(一个集合内不重复的元素的个数),所有A集合基数为5。

简介

Redis2.8.9版本就更新了Hyperloglog数据结构!

Redis Hyperloglog基数统计算法!

优点:占用的内存是固定的,2^64 不同的元素的基数,只需要占用12kb的内存!

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

传统的方式,set保存用户的id,然后就可以统计set中的元素数量作为标准判断!

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

操作

127.0.0.1:6379> PFADD mykey a b c d e f g # 创建第一组元素mykey
(integer) 1
127.0.0.1:6379> PFCOUNT mykey # 统计mykey中的基数
(integer) 7
127.0.0.1:6379> PFADD mykey2 a a b d c e f e
(integer) 1
127.0.0.1:6379> PFCOUNT mykey2
(integer) 6
127.0.0.1:6379> PFMERGE mykey3 mykey mykey2 # 合并两组mykey mykey2 到 mykey3
OK
127.0.0.1:6379> PFCOUNT mykey3 # 查看并集的数量!
(integer) 7

三、Bitmap

位存储

统计疫情感染人数:0 1 0 0 0 1 0 1 0 0 0

统计用户信息,活跃和不活跃,登录、未登录;打卡。。。两个状态的都可以使用Bitmap!

Bitmap位图,也是一种数据结构。都是操作二进制位来进行记录,就只有0和1 两个状态。

测试

image-20201017135104853

使用bitmaps来记录周一到周日的打卡,0为未打卡,1为打卡

image-20201017135201740

查看某一天是否有打卡。

127.0.0.1:6379> GETBIT sign 3
(integer) 0
127.0.0.1:6379> GETBIT sign 6
(integer) 1

统计打卡的天数。

127.0.0.1:6379> BITCOUNT sign 
(integer) 5

Q.E.D.


理想三旬浓烟下,奔赴山海与荒野