Redis 特殊数据类型 :Geospatial、Hyperloglog、Bitmap


Geospatial(地理空间)

在使用一些小程序的时候,里面通常都会通过定位使用者的位置,来显示附近的人、外卖距离、剩余路径等功能,在Redis3.2中也引入了推算地理信息的数据结构,即Geospatial

介绍

把某个具体的位置信息(经度,纬度,名称)添加到指定的key中,数据将会用一个sorted set存储,以便稍后能使用 GEORADIUS和 GEORADIUSBYMEMBER命令来根据半径来查询位置信息。

这个命令(指GEOADD)的参数使用标准的x,y形式,所以经度(longitude)必须放在纬度(latitude)之前,对于可被索引的坐标位置是有一定限制条件的:非常靠近极点的位置是不能被索引的, 在EPSG:900913 / EPSG:3785 / OSGEO:41001指定如下:

  • 有效的经度是-180度到180度
  • 有效的纬度是-85.05112878度到85.05112878度

上面是官方文档的描述,其实Geo并没有我们想象中的复杂,它的本质就是一个Zset,通过将坐标以Geohash的方式进行处理,将经度纬度错位后形成一个52位整数,所以我们同样能够使用Zset提供的接口来操作Geo

用法

命令 作用
GEOADD key 经度 纬度 地点名称 将指定的地理空间位置(经度、纬度、名称)添加到指定的key中
GEODIST key 地点1 地点2 返回两个给定位置之间的距离
GEOPOS key 地点 从key里返回所有给定位置元素的位置(经度和纬度)
GEOHASH key 地点 返回一个或多个位置元素的 Geohash 表示
GEORADIUS key 经度 纬度 半径 以给定的经纬度为中心, 找出某一半径内的元素
GEORADIUSBYMEMBER key 地点 半径 找出位于指定范围内的元素,中心点是由给定的位置元素决定

Zset的接口同样适用于Geo,因此需要删除、查询全部时就可以使用Zset的接口。

下面示范一下这些命令的使用方式

# 为了方便示范,下面加入一些城市的地理信息——GEOADD 
127.0.0.1:6379> GEOADD CHINA 108.94683  34.29296  "xian"
(integer) 1
127.0.0.1:6379> GEOADD CHINA 116.405285 39.904989 "beijing"
(integer) 1
127.0.0.1:6379> GEOADD CHINA 121.472644 31.231706 "shanghai"
(integer) 1
127.0.0.1:6379> GEOADD CHINA 113.280637 23.125178 "guangzhou"
(integer) 1
127.0.0.1:6379> GEOADD CHINA 114.085947 22.547    "shenzhen"
(integer) 1
127.0.0.1:6379> GEOADD CHINA 110.33119  20.031971 "hainan"
(integer) 1

# 获取北京和上海的距离——GEODIST 
127.0.0.1:6379> GEODIST CHINA beijing shanghai km
"1067.5980"

# 获取西安的坐标——GEOPOS 
127.0.0.1:6379> GEOPOS CHINA xian
1) 1) "108.94683212041854858"
   2) "34.29296115814533863"

# 以经度120 纬度35位置为中心,获取半径1000千米内的城市——GEORADIUS 
127.0.0.1:6379> GEORADIUS CHINA 120 35 1000 km
1) "beijing"
2) "shanghai"

# 获取在广州半径500千米内的城市——GEORADIUSBYMEMBER  
127.0.0.1:6379> GEORADIUSBYMEMBER CHINA guangzhou 500 km
1) "shenzhen"
2) "guangzhou"
3) "hainan"

# 将广州和深圳的坐标转换为11为的GEO哈希值——GEOHASH
127.0.0.1:6379> GEOHASH CHINA guangzhou shenzhen
1) "ws0e9cb3yj0"
2) "ws10k0dcg10"


Hyperloglog(基数统计)

在我们为网站统计访问量、日活量时,由于我们统计的是用户数量而非访问次数,因此即使一个用户多次访问也只会统计一次,这种不重复的数据通常被称为基数

在传统的做法中,我们通常会采用set来保存用户的ID来进行计数,因为其本身存在着去重的功能,但是由于我们所需要的是对用户进行计数,如果通过将所有用户的ID保存的方法来完成,当用户量大的时候就会对内存产生巨大的压力,并且效率也大大降低。

为了解决这个问题,Redis在2.8.9版本添加了HyperLogLog结构。

介绍

Redis HyperLogLog是用来做基数统计的算法,HyperLogLog的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的

在Redis 里面,每个HyperLogLog键只需要花费12KB内存,就可以计算接近2^64个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

但是,由于HyperLogLog使用的是概率算法,通过存储元素的hash值的第一个1的位置,来计算元素数量,所以HyperLogLog 不会存储元素本身,在数据量大的时候也可能会存在一定的误差。但是在基数统计这一方面,它的效果是其他结构无法比拟的。

用法

命令 作用
PFADD key value 添加指定的值到Hyperloglog中
PFCONUT key 返回给定Hyperloglog的基数估算值
PFMERGE destkey sourcekey 将目标Hyperloglog合并到源Hyperloglog中

使用示范

127.0.0.1:6379> PFADD NUMS1 1 2	3 4	#向NUMS1插入1-4
(integer) 1
127.0.0.1:6379> PFADD NUMS1 1		#数据已存在,不再插入
(integer) 0
127.0.0.1:6379> PFCOUNT NUMS1		#查看当前基数数量
(integer) 4

127.0.0.1:6379> PFADD NUMS2 3 4 5 6	#向NUMS2插入3-6
(integer) 1
127.0.0.1:6379> PFMERGE NUMS1 NUMS2	#将NUMS2合并到NUMS1中
OK
127.0.0.1:6379> PFCOUNT NUMS1		#此时NUMS1中记录了1-6,六个元素
(integer) 6									

Bitmap(位图)

介绍

位图其实就是哈希的变形,他通过哈希映射来处理数据,位图本身并不存储数据,而是存储标记。通过一个比特位,即0/1来标记一个数据的两种状态

位图通常情况下用在数据量庞大,且数据不重复的情景下标记某个数据的两种状态。 我们可以使用位图来记录当前用户的登陆情况、或者实现打卡、签到等功能。

用法

命令 作用
GETBIT key offset value(0/1) 设置Bitmap中偏移量为offset的位置的值
SETBIT key offset value 返回Bitmap中偏移量为offset的位置的值
BITCOUNT key 计算位图中有多少个1
127.0.0.1:6379> SETBIT TEST 1 1	#将位图中第1,3,5位设置为1
(integer) 0
127.0.0.1:6379> SETBIT TEST 3 1
(integer) 0
127.0.0.1:6379> SETBIT TEST 5 1
(integer) 0

127.0.0.1:6379> GETBIT TEST 1 	#查看位图中1,2,3位的值
(integer) 1
127.0.0.1:6379> GETBIT TEST 2
(integer) 0
127.0.0.1:6379> GETBIT TEST 3
(integer) 1

127.0.0.1:6379> BITCOUNT TET	#统计位图中1的数量,由于我们只设置了1,3,5位,因此为3
(integer) 3

猜你喜欢

转载自blog.csdn.net/qq_35423154/article/details/109674794
今日推荐