redis三种特殊数据类型

geospatiald地理位置

朋友的定位,附近的人,打车距离
redis的geo从3.2版本就有了
可以用来推算地理位置信息,两地之间的距离和方圆几里的人
最新版有8个命令,比狂神讲的版本多了2个
在这里插入图片描述
经度纬度查询,可用这个https://jingweidu.bmcx.com/
geoadd #添加地理位置
#规则:两级无法添加,我们一般会下载城市数据,直接通过Java程序一次性导入
redis中文网:http://www.redis.cn/commands/geoadd.html
文档介绍
将指定的地理空间位置(纬度、经度、名称)添加到指定的key中。这些数据将会存储到sorted set这样的目的是为了方便使用GEORADIUS或者GEORADIUSBYMEMBER命令对数据进行半径查询等操作。

该命令以采用标准格式的参数x,y,所以经度必须在纬度之前。这些坐标的限制是可以被编入索引的,区域面积可以很接近极点但是不能索引。具体的限制,由EPSG:900913 / EPSG:3785 / OSGEO:41001 规定如下:

有效的经度从-180度到180度。
有效的纬度从-85.05112878度到85.05112878度。
当坐标位置超出上述指定范围时,该命令将会返回一个错误。

GEOADD key [NX|XX] [CH] longitude latitude member [longitude latitude member …]

127.0.0.1:6379> GEOADD china:city 121.48941 31.40527 shanghai
(integer) 1
127.0.0.1:6379> GEOADD china:city 106.54041 29.40268 chongqing
(integer) 1
127.0.0.1:6379> GEOADD china:city 104.10194 30.65984 chengdu
(integer) 1
127.0.0.1:6379> GEOADD china:city 113.88308 22.55329 shenzhen
(integer) 1
127.0.0.1:6379> GEOADD china:city 108.93425 34.23053 xian
(integer) 1
127.0.0.1:6379> GEOADD china:city 120.21201 30.2084 hangzhou
(integer) 1
127.0.0.1:6379> GEOADD china:city 102.82147 24.88554 kunming
(integer) 1
127.0.0.1:6379> GEOADD china:city 106.62298 26.67865 guiyang
(integer) 1

geopos key member [member…] #获取一个或多个元素的经度、纬度

127.0.0.1:6379> GEOPOS china:city xian chengdu
1) 1) "108.93425256013870239"
   2) "34.23053097599082406"
2) 1) "104.10194188356399536"
   2) "30.65983886217613019"

#两个元素之间的距离
GEODIST key member1 member2 [m|lm|ft|mi]
时间复杂度:O(log(N))
返回两个给定位置之间的距离。
如果两个位置之间的其中一个不存在, 那么命令返回空值。

指定单位的参数 unit 必须是以下单位的其中一个:
m 表示单位为米。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。
如果用户没有显式地指定单位参数, 那么 GEODIST 默认使用米作为单位。

GEODIST 命令在计算距离时会假设地球为完美的球形, 在极限情况下, 这一假设最大会造成 0.5% 的误差。

127.0.0.1:6379> geodist china:city shanghai chengdu km #上海到成都的距离

"1657.4968"
127.0.0.1:6379> geodist china:city chengdu chongqing km
"273.2796"

#以给定经纬度为中心,找出某一半径内的元素
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]
以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。
范围可以使用以下其中一个单位:

m 表示单位为米。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。
在给定以下可选项时, 命令会返回额外的信息:

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

127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km #获取100 30 这个经纬度为中心寻找 china:city这个集合方圆1000km内的城市
1) "kunming"
2) "guiyang"
3) "chongqing"
4) "chengdu"
5) "xian"
6) "shenzhen"
7) "hangzhou"
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km count 3 #取该经纬度,1000km范围内的3个城市
1) "chongqing"
2) "xian"
3) "guiyang"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km
1) "guiyang"
2) "chongqing"
3) "xian"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withdist #显示到中心位置的距离
1) 1) "guiyang"
   2) "495.6831"
2) 1) "chongqing"
   2) "340.7667"
3) 1) "xian"
   2) "481.1278"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withcoord #该经纬度500km内城市的经纬度
1) 1) "guiyang"
   2) 1) "106.62298232316970825"
      2) "26.67865119132765273"
2) 1) "chongqing"
   2) 1) "106.54040783643722534"
      2) "29.40268053517299762"
3) 1) "xian"
   2) 1) "108.93425256013870239"
      2) "34.23053097599082406"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withhash # 返回500km内城市经过原始 geohash 编码的有序集合分值
1) 1) "guiyang"
   2) (integer) 4024944342351520
2) 1) "chongqing"
   2) (integer) 4026046519194590
3) 1) "xian"
   2) (integer) 4040115270369361

#找出周围指定元素周围距离的元素
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]

127.0.0.1:6379> GEORADIUSBYMEMBER china:city shanghai 400 km #找出上海周围400km的城市
1) "hangzhou"
2) "shanghai"

GEOHASH key member [member …]
返回一个或多个位置元素的 Geohash 表示。该命令将返回11个字符的Geohash字符串

127.0.0.1:6379> geohash china:city chongqing chengdu shanghai #将二维的经纬度转换为一纬的字符串,如果两个字符串越接近,那么距离越近
1) "wm5z22s7520"
2) "wm6n2vkwx00"
3) "wtw6st1uuq0"

GEO底层的实现原理其实就是zset,我们可以使用zset来操作geo
比如可以实现取消某些定位呀,关掉定位信息

127.0.0.1:6379> zrange china:city 0 -1 # 查看地图中的所有元素
1) "kunming"
2) "guiyang"
3) "chongqing"
4) "chengdu"
5) "xian"
6) "shenzhen"
7) "hangzhou"
8) "shanghai"
127.0.0.1:6379> zrem china:city hangzhou #移除指定元素
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1
1) "kunming"
2) "guiyang"
3) "chongqing"
4) "chengdu"
5) "xian"
6) "shenzhen"
7) "shanghai"

GEOSEARCH key [FROMMEMBER member] [FROMLONLAT longitude latitude] [BYRADIUS radius m|km|ft|mi] [BYBOX width height m|km|ft|mi] [ASC|DESC] [COUNT count [ANY]] [WITHCOORD] [WITHDIST] [WITHHASH]

GEOSEARCH
相当于是GEORADIUS的升级款,这个命令代替了现在已弃用的GEORADIUS和GEORADIUSBYMEMBER。

BYRADIUS:类似于GEORADIUS,根据给定的搜索圆形区域内。
BYBOX:在一个轴对齐的矩形内搜索,由<高度>和<宽度>确定。感觉这个功能比较适合在重庆这个5d城市找位置
FROMMEMBER:使用给定的现有元素在排序集合中的位置。
FROMLONLAT:使用给定的经纬度

127.0.0.1:6379> GEOSEARCH china:city fromlonlat 110 37 byradius 1000 km asc #该经纬度方圆1000km的城市,并由近到远排序
1) "xian"
2) "chengdu"
3) "chongqing"
127.0.0.1:6379> GEOSEARCH china:city fromlonlat 110 37 bybox 1000 1000 km asc #该经纬度度高宽1000km的城市
1) "xian"

127.0.0.1:6379> GEOSEARCH china:city frommember chengdu byradius 300 km #集合中指定元素方圆300km的城市
1) "chongqing"
2) "chengdu"
127.0.0.1:6379> GEOSEARCH china:city frommember chengdu bybox 300 300 km
1) "chengdu"
127.0.0.1:6379> GEOSEARCH china:city frommember chengdu bybox 500 500 km #集合中指定元素举行距离高宽500km的城市
1) "chongqing"
2) "chengdu"
127.0.0.1:6379>
127.0.0.1:6379> GEOSEARCH china:city frommember chengdu bybox 500 500 km withhash
1) 1) "chongqing"
   2) (integer) 4026046519194590
2) 1) "chengdu"
   2) (integer) 4026137837689489
127.0.0.1:6379> GEOSEARCH china:city frommember chengdu bybox 500 500 km count 1
1) "chengdu"
127.0.0.1:6379> GEOSEARCH china:city frommember chengdu bybox 500 500 km withdist
1) 1) "chongqing"
   2) "273.2796"
2) 1) "chengdu"
   2) "0.0000"
127.0.0.1:6379> GEOSEARCH china:city frommember chengdu bybox 500 500 km withcoord
1) 1) "chongqing"
   2) 1) "106.54040783643722534"
      2) "29.40268053517299762"
2) 1) "chengdu"
   2) 1) "104.10194188356399536"
      2) "30.65983886217613019"

GEOSEARCHSTORE destination source [FROMMEMBER member] [FROMLONLAT longitude latitude] [BYRADIUS radius m|km|ft|mi] [BYBOX width height m|km|ft|mi] [ASC|DESC] [COUNT count [ANY]] [WITHCOORD] [WITHDIST] [WITHHASH] [STOREDIST]
此命令类似于GEOSEARCH,但将结果存储在目标键中

GEOSEARCHSTORE 类似与GEOSEARCH,只是将查询出来的数据存到集合中去

127.0.0.1:6379> GEOSEARCHSTORE china:targetcity china:city frommember chengdu byradius 300 km asc #将查询出来的数据存放到 china:targetcity 中,如果不存在这个集合则创建集合
(integer) 2
127.0.0.1:6379> zrange china:targetcity 0 -1
1) "chongqing"
2) "chengdu"
127.0.0.1:6379> GEOADD china:destcity 110 37 test1
(integer) 1
127.0.0.1:6379> zrange china:destcity 0 -1
1) "test1"
127.0.0.1:6379> GEOSEARCHSTORE china:destcity china:city frommember chengdu byradius 300 km asc #将查询出来的数据存放到 china:targetcity 中,如果存在这个集合则覆盖里面的数据
(integer) 2
127.0.0.1:6379> zrange china:destcity 0 -1
1) "chongqing"
2) "chengdu"
127.0.0.1:6379> GEOSEARCHSTORE china:targetcity china:city fromlonlat  110 37 byradius 1000 km asc #自定经纬度方圆1000km的数据存储到china:targetcity集合中
(integer) 3
127.0.0.1:6379> zrange china:targetcity 0 -1
1) "chongqing"
2) "chengdu"
3) "xian"
127.0.0.1:6379> GEOSEARCHSTORE china:targetcity china:city frommember chengdu bybox 1000 1000 km asc #指定元素矩形范围内的城市
(integer) 4
127.0.0.1:6379> zrange china:targetcity 0 -1
1) "guiyang"
2) "chongqing"
3) "chengdu"
4) "xian"

Hyperloglog 基数统计

在这里插入图片描述

Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。
花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。
因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
其底层使用string数据类型

什么是基数?
数据集中不重复的元素的个数。
A{1,3,5,6,3,1} B{1,3,5,6} 不重复的元素为 {1,3,5,6}=4个,可以接受误差

redis Hyperloglog 基数统计的算法
网页的浏览人数(一个访问一个网站多次,但是还是算做一个人)
传统的方式,set保存用户的唯一id,然后统计set中的元素数量作为标准判断
这个如果保存大量的用户会比较麻烦,我们的目的是为了计数,而不是保存用户id

优点:
占用的内存是固定的,2^64不同元素的基数,只需要12kb内存!如果从内存的角度来比较的话Hyperloglog是首选。
0.81%的错误率,统计浏览量这种可以忽略不计

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 mykey2 i j z x c v b
(integer) 1
127.0.0.1:6379> PFCOUNT mykey2
(integer) 7
127.0.0.1:6379> PFCOUNT mykey2 mykey #合并统计两个key的基数数量
(integer) 13
127.0.0.1:6379> PFMERGE mykey3 mykey mykey2 #合并两组key的基数到mykey3
OK
127.0.0.1:6379> pfcount mykey3 #查看并集的数量
(integer) 13
127.0.0.1:6379> PFADD mykey4  a b a c a d
(integer) 1
127.0.0.1:6379> pfcount mykey4 #统计基数数量,统计不重复元素的个数
(integer) 4

总结:

  • 如果允许容错,那么一定可以使用hyperloglog
  • 如果不允许容错,就使用set或者自己的数据类型(保证不重复)即可,(但是大数据量时效率较低)

Bitmaps

在这里插入图片描述

位存储
统计疫情感染人数(14亿个0,感染则为1,统计效率高)
统计用户信息,活跃,不活跃;登录,未登录;打卡,未打卡;两个状态的都可以用bitmaps

Bitmaps位图,数据结构,都是操作二进制位来进行记录,就只有0和1两个状态。
365天=365bit,1字节=8bit==>只需要46个字节就可以存一个人一年的打卡信息

使用bitmap来记录一周的打卡

127.0.0.1:6379[1]> setbit sign 0 1
(integer) 0
127.0.0.1:6379[1]> setbit sign 1 0
(integer) 0
127.0.0.1:6379[1]> setbit sign 2 0
(integer) 0
127.0.0.1:6379[1]> setbit sign 3 1
(integer) 0
127.0.0.1:6379[1]> setbit sign 4 1
(integer) 0
127.0.0.1:6379[1]> setbit sign 5 0
(integer) 0
127.0.0.1:6379[1]> setbit sign 6 1
(integer) 0

查看具体的第一天是否打卡

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

统计一周的打卡天数

127.0.0.1:6379[1]> BITCOUNT sign
(integer) 4
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值