四、三种特殊类型数据
1、geospatial 地理位置
朋友的定位,附近的人,打车距离计算
只有六个命令
geoadd
# 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