三种特殊数据类型

三种特殊数据类型

学习视频遇见狂神说

Geospatial(地理空间)

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

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

可以查询一些测试数据

六个命令

在这里插入图片描述

geoadd

在这里插入图片描述

# geoadd  添加地理位置
# 规则:两极(南极和北极)无法直接添加,我们一般会下载城市数据,直接通过java程序一次性导入
# 参数 key 值(经度、纬度、名称) 经度必须在纬度之前

127.0.0.1:6379> GEOADD china:city 106.549 29.581 chongqing
(integer) 1
127.0.0.1:6379> GEOADD china:city 119.427 32.386 yangzhou
(integer) 1
127.0.0.1:6379> GEOADD china:city 113.095 29.378 yueyang
(integer) 1
127.0.0.1:6379> GEOADD china:city 111.692 29.048 changde
(integer) 1
127.0.0.1:6379> GEOADD china:city 116.408 39.904 beijing
(integer) 1

geopos

获得当前定位:一定是一个坐标值!

# geopos  获取指定目标的经度和纬度

127.0.0.1:6379> geopos china:city yueyang   # 获取一个指定城市的经度和纬度
1) 1) "113.09500247240066528"
   2) "29.37799995524451191"
127.0.0.1:6379> geopos china:city chongqing yangzhou    # 获取多个指定城市的经度和纬度
1) 1) "106.54900163412094116"
   2) "29.58100070345364685"
2) 1) "119.42700058221817017"
   2) "32.38599918001290945"

geopist

获得两人之间的直线距离!

如果两个位置之间的其中一个不存在, 那么命令返回空值。

指定单位的参数 unit 必须是以下单位的其中一个:

  • m 表示单位为米。
  • km 表示单位为千米。
  • mi 表示单位为英里。
  • ft 表示单位为英尺。

如果用户没有显式地指定单位参数, 那么 GEODIST 默认使用米作为单位。

# geodist  两个给定位置之间的距离

127.0.0.1:6379> GEODIST china:city chongqing yangzhou km  # 重庆到扬州的直线距离(km)
"1266.0939"
127.0.0.1:6379> GEODIST china:city changde yueyang km    # 常德到岳阳的直线距离(km)
"141.0610"

georadius

附近的人

以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。

范围可以使用以下其中一个单位:

  • m 表示单位为米。
  • km 表示单位为千米。
  • mi 表示单位为英里。
  • ft 表示单位为英尺。

在给定以下可选项时, 命令会返回额外的信息:

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

命令默认返回未排序的位置元素。 通过以下两个参数, 用户可以指定被返回位置元素的排序方式:

  • ASC: 根据中心的位置, 按照从近到远的方式返回位置元素。

  • DESC: 根据中心的位置, 按照从远到近的方式返回位置元素。

    在默认情况下, georadius 命令会返回所有匹配的位置元素。 虽然用户可以使用 COUNT <count> 选项去获取前 N 个匹配元素, 但是因为命令在内部可能会需要对所有被匹配的元素进行处理, 所以在对一个非常大的区域进行搜索时, 即使只使用 COUNT 选项去获取少量元素, 命令的执行速度也可能会非常慢。 但是从另一方面来说, 使用 COUNT 选项去减少需要返回的元素数量, 对于减少带宽来说仍然是非常有用的。

# georadius  以给定的经纬度为中心, 与中心的距离不超过给定最大距离的所有位置元素

127.0.0.1:6379> GEORADIUS china:city 112 34 800 km   # 以112,34为中心,不超过800km的元素
1) "chongqing"
2) "changde"
3) "yangzhou"
4) "beijing"
5) "yueyang"
127.0.0.1:6379> GEORADIUS china:city 112 34 600 km    # 以112,34为中心,不超过600km的元素
1) "changde"
2) "yueyang"
127.0.0.1:6379> GEORADIUS china:city 112 34 700 km withcoord  #  返回元素的经纬度
1) 1) "changde"
   2) 1) "111.6919979453086853"
      2) "29.04799953806784885"
2) 1) "yueyang"
   2) 1) "113.09500247240066528"
      2) "29.37799995524451191"
127.0.0.1:6379> GEORADIUS china:city 112 34 700 km withdist   # 返回元素与中心的直线距离(km)
1) 1) "changde"
   2) "551.5652"
2) 1) "yueyang"
   2) "524.4179"
127.0.0.1:6379> GEORADIUS china:city 112 34 1000 km count 4  # 获取前 4个匹配元素
1) "yueyang"
2) "changde"
3) "chongqing"
4) "yangzhou"

georadiusbymember

这个命令和 georadius 命令一样, 都可以找出位于指定范围内的元素, 但是 GEORADIUSBYMEMBER 的中心点是由给定的位置元素决定的, 而不是像 georadius那样, 使用输入的经度和纬度来决定中心点

指定成员的位置被用作查询的中心。

#georadiusbymember 

127.0.0.1:6379> GEORADIUSBYMEMBER china:city yueyang 500 km   # 以岳阳为中心,500km内的城市
1) "yueyang"
2) "changde"
127.0.0.1:6379> GEORADIUSBYMEMBER china:city chongqing 700 km  # 以重庆为中心,700km内的城市
1) "chongqing"
2) "changde"
3) "yueyang"

geohash

返回11个字符的Geohash字符串

# geohash 返回11个字符的Geohash字符串
# 将二维的经纬度转化为一维的字符串,如果两个字符串越相似,则这两个的距离越近

127.0.0.1:6379> GEOHASH china:city chongqing yangzhou
1) "wm7b2949gd0"
2) "wtubjxsn4g0"

geo的底层实现原理其实就是Zset,可以使用Zset的命令来操作geo

127.0.0.1:6379> ZRANGE china:city 0 -1   # 查看地图中的全部元素
1) "chongqing"
2) "changde"
3) "yueyang"
4) "yangzhou"
5) "beijing"
Hyperloglog(基数统计)

什么是基数?

比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

简介

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

Redis Hyperloglog基数统计的算法

**优点:**占用的内存是固定的,2^64不同的元素的基数,只需要12KB的内存。如果从内存角度来比较的话Hyperloglog就成为了首选。

网页的UV(独立访客)

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

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

有0.81%的错误率

# pfadd
# pfcount
# pfmerge

127.0.0.1:6379> PFADD key1 a b c d e f  # 创建第一组元素 key1
(integer) 1 
127.0.0.1:6379> PFCOUNT key1     # 统计key1中元素的基数
(integer) 6
127.0.0.1:6379> PFADD key2 d e f g h i    # 创建第二组元素 key1
(integer) 1
127.0.0.1:6379> PFCOUNT key2   # 统计key2中元素的基数
(integer) 6
127.0.0.1:6379> PFMERGE key3 key1 key2  # 合并 key1 和 key2 到 key3
OK
127.0.0.1:6379> PFCOUNT key3      # 统计key3中元素的基数
(integer) 9

小结

使用Hyperloglog的前提是允许有一定的容错

Bitmap(位图)

位存储

  • 统计感染人数:全中国14亿人用14亿个“0”表示,感染的话将“0”变为“1”;
  • 统计用户信息(活跃和不活跃);
  • 登录和未登录;
  • 打卡

等两个状态的都可以使用Bitmaps

Biotmap:位图,和Hyperloglog一样都是数据结构。操作二进制位来进行记录,只有0和1两个状态。

一个用户365天的打卡记录:365天 = 365 bit 1个字节 = 8bit 365天 ≈ 46个字节

# 使用bitmap来记录周一到周日的打卡
# 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 1  # 周四打卡
(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 2  # 周三未打卡
(integer) 0
127.0.0.1:6379> GETBIT sign 4  # 周五打卡
(integer) 1
# 统计打卡天数
127.0.0.1:6379> BITCOUNT sign
(integer) 3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值