Day149.三种特殊数据类型 -Redis

三种特殊数据类型

-geospatial
-hyperloglog
-bitmap

一、geospatial地理位置

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

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

可以查询一些测试的数据:http://www.toolzl.com/tools/gps.html

Day149.三种特殊数据类型   -Redis

1、GEOADD

#geoadd 添加地理位置
#规则:南极北极无法添加,一般会下载城市数据,之间通过java程序一次性导入
#参数: key 值(经度 纬度 名称)
127.0.0.1:6379> GEOADD china:city 120.672112 28.000574 wenzhou 120.15358 30.287458 hangzhou
(integer) 2
127.0.0.1:6379> GEOADD china:city 121.472641 31.231707 shanghai
(integer) 1
127.0.0.1:6379> GEOADD china:city 114.08 22.54 shenzheng
(integer) 1
127.0.0.1:6379> GEOADD china:city 116.40 39.90 beijing
(integer) 1
127.0.0.1:6379> GEOADD china:city 104.06 30.65 sichuan
(integer) 1

2、GEOPOS

#GEOPOS	获取指定城市的经纬度
127.0.0.1:6379> GEOPOS china:city beijing	#获取指定城市的经纬度
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
127.0.0.1:6379> GEOPOS china:city wenzhou
1) 1) "120.67211419343948364"
   2) "28.00057417867305531"
127.0.0.1:6379> GEOPOS china:city hangzhou
1) 1) "120.15357881784439087"
   2) "30.28745790721532671"
127.0.0.1:6379> GEOPOS china:city sichuan shanghai shenzheng
1) 1) "104.05999749898910522"
   2) "30.6499990746355806"
2) 1) "121.47264093160629272"
   2) "31.23170744181923197"
3) 1) "114.08000081777572632"
   2) "22.53999903789756587"

3、GEODIST

#GEODIST 返回两个给定距离之间的距离
127.0.0.1:6379> GEODIST china:city beijing shanghai #查看北京和上海之间的直线距离
"1067307.2839"
127.0.0.1:6379> GEODIST china:city beijing shanghai km
"1067.3073"
127.0.0.1:6379> GEODIST china:city wenzhou shenzheng km
"898.8201"

4、GEORADIUS

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

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

所有的数据都应该录入china:city,才会让结果更加清晰

127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km	#获取以113 30经纬度为圆心,寻找1000km以内的城市
1) "sichuan"
2) "shenzheng"
3) "hangzhou"
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withdist	#显示到中心距离的直线位置
1) 1) "sichuan"
   2) "574.7802"
2) 1) "shenzheng"
   2) "923.9364"
3) 1) "hangzhou"
   2) "976.8202"
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withcoord	#显示出他人定位信息
1) 1) "sichuan"
   2) 1) "104.05999749898910522"
      2) "30.6499990746355806"
2) 1) "shenzheng"
   2) 1) "114.08000081777572632"
      2) "22.53999903789756587"
3) 1) "hangzhou"
   2) 1) "120.15357881784439087"
      2) "30.28745790721532671"
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withdist withcoord count 3	#筛选出指定结果
1) 1) "sichuan"
   2) "574.7802"
   3) 1) "104.05999749898910522"
      2) "30.6499990746355806"
2) 1) "shenzheng"
   2) "923.9364"
   3) 1) "114.08000081777572632"
      2) "22.53999903789756587"
3) 1) "hangzhou"
   2) "976.8202"
   3) 1) "120.15357881784439087"
      2) "30.28745790721532671"

5、GEORADIUSBYMEMBER

#GEORADIUSBYMEMBER  找出位于指定范围内的元素,中心点是由给定的位置决定
#找出位于指定元素周围的其他元素
127.0.0.1:6379> GEORADIUSBYMEMBER china:city wenzhou 1000 km
1) "shenzheng"
2) "wenzhou"
3) "hangzhou"
4) "shanghai"

6、GEOHASH

#GEOHASH	返回一个或多个位置元素的Geohash表示
#将二维的经纬度转换为一位的字符串,如果两个字符串越接近,则距离越近
127.0.0.1:6379> GEOHASH china:city wenzhou shanghai
1) "wsvz3cqg0j0"
2) "wtw3sjt9vs0"	

7、GEO 底层实现原理

本质是Zset,我们可以使用Zset命令来操作GEO

127.0.0.1:6379> zrem china:city beijing	#通过Zset命令移除一个元素
(integer) 1
127.0.0.1:6379> ZRANGE china:city 0 -1	#查看地图中全部元素
1) "sichuan"
2) "shenzheng"
3) "wenzhou"
4) "hangzhou"
5) "shanghai"

.

二、hyperloglog

什么是基数?

基数:不重复的元素个数

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

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

上面B集合的基数 = 5,可以接受误差

.

简介

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

Redis hyperloglog 是做基数统计的算法

优点:占用的内存是固定的,2^64不同的元素技术,只需要费12KB的内存。

如果要从内存角度来比较的话hyperloglog首选

网页的 UV(页面访问量:一个人访问一个网站多次,还算一个人)

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

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

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

测试使用

pfadd 集合名 元素...		#添加元素
pfcount	集合名		#计算元素基数个数
pfmerge 结果集 要合并集1 要合并集2..		#合并(不含重复数据)

127.0.0.1:6379> pfadd mykey a b c d e f g h i j		#创建第一组元素 mykey
(integer) 1
127.0.0.1:6379> pfcount mykey		#统计集合基数元素个数
(integer) 10
127.0.0.1:6379> pfadd mykey2 i j z x c a b n m		#创建第二组元素 mykey2
(integer) 1
127.0.0.1:6379> PFCOUNT mykey2		#统计集合基数元素个数
(integer) 9
127.0.0.1:6379> pfmerge mykey3 mykey mykey2#创建第三组元素mykey3,由mykey1和mykey2组合,不含重复数据
OK
127.0.0.1:6379> PFCOUNT mykey3
(integer) 14

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

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

.

三、bitmap

位存储

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

1、用位来统计,加入要14亿人,就用14亿个0代表未感染,1代表感染,在计算机中位统计效率高

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

2、统计用户信息,粉丝活跃,粉丝不活跃;登录、未登录;打卡,365打卡(两个状态的,都可以使用bitmaps)

测试

使用bitmap来记录周一到周日的打卡情况

周一:0 周二:1 周三:0 周四:0 周五:1 周六:0 周七:1

Day149.三种特殊数据类型   -Redis

查看某一天是否有打卡:

127.0.0.1:6379> getbit sign 4
(integer) 0
127.0.0.1:6379> getbit sign 5
(integer) 1

统计打卡的天数:

127.0.0.1:6379> BITCOUNT sign	#统计这周打卡记录为1的,就可以是否有全勤
(integer) 3

感谢狂神!!!
https://www.bilibili.com/video/BV1S54y1R7SB?p=21

上一篇:经济学人阅读11月29日


下一篇:PyCon China 2020 中国Python开发者大会开幕啦