Redis三种特殊类型

208 阅读4分钟

四、三种特殊类型数据

1、geospatial 地理位置

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

只有六个命令

geoadd 1678606711555.png

# geoadd 添加地理位置
# 规则:两级无法直接添加,一般我们会下载城市数据,直接通过java程序一次性导入!
# 有效的经度从-180到180度
# 有效的纬度从-85.051112878度到85.05112878度
# 当坐标位置超出上述范围时,该命令将返回一个错误
# 127.0.0.1:6379> geoadd chain:city 31.23 121.47 shanghang
# (error) ERR invalid longitude,latitude pair 31.230000,121.470000
# 参数 key 值(纬度 经度 名称)
127.0.0.1:6379> geoadd china:city 116.40 39.90 beijin
(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 chongqin 114.05 22.52 shengzheng
(integer) 2
127.0.0.1:6379> geoadd china:city 120.16 30.24 hangzhou 108.96 43.26 xian
(integer) 2

geopos

127.0.0.1:6379> geopos china:city shanghang #获取指定城市的经度和纬度
1) 1) "121.47000163793563843"
   2) "31.22999903975783553"
127.0.0.1:6379> geopos china:city xian hangzhou
1) 1) "108.96000176668167114"
   2) "43.26000111327904563"
2) 1) "120.1600000262260437"
   2) "30.2400003229490224"

geodist

两人之间的距离

单位 m 米 km千米 mi 英里 ft 英尺

127.0.0.1:6379> geodist china:city shanghang xian #上海到西安的直线距离
"1732960.9517"
127.0.0.1:6379> geodist china:city shanghang xian km
"1732.9610"

georadius 以给定的经纬度为中心,找出某一半径的元素

我附近的人!(获取所有附近的人的地址、定位)通过半径来查询

所有数据都需要录入china:city,才会让结果更加精确

127.0.0.1:6379> georadius china:city 110 30 500km #以110、30经纬度为中心,寻找方圆500km的城市
(error) ERR wrong number of arguments for 'georadius' command
127.0.0.1:6379> georadius china:city 110 30 500 km
1) "chongqin"
127.0.0.1:6379> georadius china:city 110 30 500 km withcoord #显示他人的定位信息
1) 1) "chongqin"
   2) 1) "106.49999767541885376"
      2) "29.52999957900659211"
127.0.0.1:6379> georadius china:city 100 30 1000 km withdist #显示到中间距离的位置
1) 1) "chongqin"
   2) "629.6756"
127.0.0.1:6379> georadius china:city 100 30 1000000 km withdist withcoord count 2 #筛选出指定的结果
1) 1) "chongqin"
   2) "629.6756"
   3) 1) "106.49999767541885376"
      2) "29.52999957900659211"
2) 1) "shengzheng"
   2) "1627.7179"
   3) 1) "114.04999762773513794"
      2) "22.5200000879503861"
127.0.0.1:6379> georadius china:city 100 30 1000000 km withdist withcoord count 1
1) 1) "chongqin"
   2) "629.6756"
   3) 1) "106.49999767541885376"
      2) "29.52999957900659211"

georadiusbymember

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

geohash 该命令将返回11个字符的Geohash字符串

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

geo 底层的实现原理其实时Zset,我们可以使用Zset来操作

127.0.0.1:6379> zrange china:city 0 -1
1) "chongqin"
2) "shengzheng"
3) "hangzhou"
4) "shanghai"
5) "beijin"
6) "xian"
127.0.0.1:6379> zrem china:city beijin
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1
1) "chongqin"
2) "shengzheng"
3) "hangzhou"
4) "shanghai"
5) "xian"

2、Hyperloglog

什么时基数?

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

基数:不重复的元素 = 5 可以接受误差

简介

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

Redis Hyperloglog基数统计的算法

**优点:**占用的内存是固定的 ,2^64不同的元素的技术,只需要12kb内存。从内存角度来说Hyperloglog是首选

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

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

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

0.81%错误率!统计UV任务,可以忽略不计

测试使用

127.0.0.1:6379> pfadd mykey q w e r t y u i #创建第一组元素 mykey
(integer) 1
127.0.0.1:6379> pfcount mykey #统计 mykey 元素基数数量
(integer) 8
127.0.0.1:6379> pfadd mykey2 z x v b n m
(integer) 1
127.0.0.1:6379> pfcount mykey2
(integer) 6
127.0.0.1:6379> pfmerge mykey mykey2
OK
127.0.0.1:6379> pfcount mykey
(integer) 14
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) 14

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

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

3、Bitmap

位存储 0 1 0 1 0 1

统计疫情感染人数疫情;统计用户信息、活跃、不活跃!登录、未登录!打卡,365打卡!两个状态都可以使用Bitmap位图,数据结构!都是操作二进制来进行记录,就只有0和1两个状态!

测试

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

周一:1;周二:0;周三:0;周四: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 0
(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

查看某一天是否有打卡!

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

统计操作,统计打卡的天数

127.0.0.1:6379> bitcount sign #统计这周的打卡记录,就可以看到是否有全勤
(integer) 2