Redis 三个特殊数据类型之Geospatail、Hyperloglog、bitMaps

简介

在 Redis 中除了常用的五大基本类型,还存在有三个比较特殊的数据类型:Geospatail 地理位置数据结构,Hyperloglog 用来做基数统计的算法,bitMaps 位图。下面就一个一个的看下。

Geospatail

Redis 中的 Geospatail(下面简称为 GEO 或者 geo),主要用于存储地理位置信息,这点在 MongoDB 中也有对应的实现。这个功能是在 redis 3.2 的版本中增加的。

使用这个功能,可以用来查找附近的人,或者打车的距离等等。

GEO 底层实现原理是使用了 sorted set(zset)有序集合,也可以使用 zset 集合的相关命令来操作 GEO 数据类型。

相关命令详解

更多详细说明点击这里,主要的操作命令有:

操作

命令

例子

说明

geoadd geoadd key longitude latitude menber geoadd Sicily 13.361389 38.115556 添加地理空间位置的 经度和纬度。
geopos geo key member [member...] geopos Sicily Palermo Catania NonExisting 获取地理位置的坐标
geodist geodist key member1 member2 [m|km|ft|mi] geodist Sicily Foo Bar 计算两个位置之间的距离,可以输入对应的距离单位
georadius georadius key longitude latitude radius [m|km|ft|mi] georadius Sicily 15 37 200 km WITHDIST 根据用户给定的经纬度坐标来获取指定范围内的地理位置集合
georadiusbymember georadiusbymember  key member radius  [m|km|ft|mi] georadiusbymember Sicily Agrigento 100 km 根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合
geohash geohash key member geohash Sicily Palermo Catania 返回一个或多个位置对象的 geohash 值

具体操作说明

geoadd 添加操作

geoadd 用于添加新的地理位置,可以用添加一个或者多个 经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中。

指定的规则:两级(南极和北极)无法直接添加,有效的经度从 -180 度到180 度,有效的纬度从 -85.05112878 度到 85.05112878度,当坐标位置超出上述指定范围时,该命令将会返回一个错误。

127.0.0.1:6379> geoadd China 113.27324 23.15792 guangzhou 112.89262 22.90026 foshan        # 添加城市数据
(integer) 2
127.0.0.1:6379> geoadd China 113.3926 22.51595 zhongshan 113.88308 22.55329 shenzhen        # 添加城市数据
(integer) 2
127.0.0.1:6379> geoadd China 113.75179 23.02067 dongguan
(integer) 1
127.0.0.1:6379> zrange China 0 -1                        # 查看添加的信息, 由于 geo 底层是使用 zset 实现,所以可以使用 zset 相关命令
1) "zhongshan"
2) "shenzhen"
3) "foshan"
4) "guangzhou"
5) "dongguan"
127.0.0.1:6379>

geopos 获取当前定位

geopos 用于获取当前地理位置的坐标,返回值是一个坐标值,如果不存在就返回 nil

127.0.0.1:6379> geopos China dongguan                # 查看 东莞这个城市的坐标
1) 1) "113.75178962945938"
   2) "23.020670884948807"
127.0.0.1:6379> geopos China guangzhou zhongshan     # 查看 广州、中山的坐标
1) 1) "113.27324062585831"
   2) "23.157920966284692"
2) 1) "113.39259892702103"
   2) "22.515949603537756"
127.0.0.1:6379>

 geodist 获取指定位置的距离

geodist 用于返回两个给定位置之间的距离,可以按照不同的距离单位显示。

  • m :米,默认单位。
  • km :千米。
  • mi :英里。
  • ft :英尺。
127.0.0.1:6379> geodist China guangzhou zhongshan m        # 查看 广州到中山的距离
"72444.7482"
127.0.0.1:6379> geodist China guangzhou foshan km          # 查看 广州到佛山的距离
"48.3663"
127.0.0.1:6379> geodist China zhongshan shenzhen km
"50.5598"
127.0.0.1:6379> geodist China beijing guangzhon m          # 查看北京到广州的距离,北京没有录入,所以返回值为 nil
(nil)
127.0.0.1:6379>

georadius、georadiusbymember 根据经纬度为中心,查找的半径长度查找所有位置元素

georadius 是以给定的经纬度为中心,返回指定半径内所有城市元素。

georadiusbymember 是根据指定的城市的经纬度,返回指定半径所有城市的元素。

georadius 与 georadiusbymember 最大的差别在于:georadius 这个是需要自己指定经纬度,georadiusbymember 这个直接以某一个成员的经纬度作为查询。

127.0.0.1:6379> georadius China 113 23 5 km        # 以经纬度为 113 23 半径为 5km 查询范围内的元素 
(empty list or set)
127.0.0.1:6379> georadius China 113 23 20 km       # 以经纬度为 113 23 半径为 20km 查询范围内的元素 
1) "foshan"
127.0.0.1:6379> georadius China 113 23 40 km
1) "foshan"
2) "guangzhou"
127.0.0.1:6379> georadius China 113 23 40 km withcoord    # 查询数据之后,返回范围内元素的经纬度
1) 1) "foshan"
   2) 1) "112.89261907339096"
      2) "22.900258956274406"
2) 1) "guangzhou"
   2) 1) "113.27324062585831"
      2) "23.157920966284692"
127.0.0.1:6379> georadius China 113 23 40 km withdist     # 查询到数据之后,返回范围内元素的距离
1) 1) "foshan"
   2) "15.6216"
2) 1) "guangzhou"
   2) "33.0188"
127.0.0.1:6379> georadius China 113 23 40 km withdist withcoord    # 查询到数据之后,返回范围内数据的距离以及经纬度
1) 1) "foshan"
   2) "15.6216"
   3) 1) "112.89261907339096"
      2) "22.900258956274406"
2) 1) "guangzhou"
   2) "33.0188"
   3) 1) "113.27324062585831"
      2) "23.157920966284692"
127.0.0.1:6379> georadius China 113 23 40 km withdist count 1       # 筛选出1条结果
1) 1) "foshan"
   2) "15.6216"
127.0.0.1:6379> georadius China 113 23 40 km withcoord withdist count 2  # 筛选出2条结果,并且返回距离以及经纬度
1) 1) "foshan"
   2) "15.6216"
   3) 1) "112.89261907339096"
      2) "22.900258956274406"
2) 1) "guangzhou"
   2) "33.0188"
   3) 1) "113.27324062585831"
      2) "23.157920966284692"
127.0.0.1:6379>
127.0.0.1:6379> georadiusbymember China zhongshan 50 km withdist         # 根据中山城市的经纬度查询 50千米内的城市,如果没有就返回自己
1) 1) "zhongshan"
   2) "0.0000"
127.0.0.1:6379> georadiusbymember China zhongshan 150 km withdist
1) 1) "zhongshan"
   2) "0.0000"
2) 1) "shenzhen"
   2) "50.5598"
3) 1) "foshan"
   2) "66.7746"
4) 1) "guangzhou"
   2) "72.4447"
5) 1) "dongguan"
   2) "67.1458"
127.0.0.1:6379> georadiusbymember China zhongshan 150 km withdist DESC    # 默认返回的方式是升序,可以多加一个 desc 参数返回就为降序了
1) 1) "guangzhou"
   2) "72.4447"
2) 1) "dongguan"
   2) "67.1458"
3) 1) "foshan"
   2) "66.7746"
4) 1) "shenzhen"
   2) "50.5598"
5) 1) "zhongshan"
   2) "0.0000"
127.0.0.1:6379>

 geohash 指的是返回一个或者多个位置元素的 hash 值

127.0.0.1:6379> geohash China foshan guangzhou                # 将 二维的经纬度转换为 一维的字符串
1) "ws062bvgst0"
2) "ws0e9xg09v0"
127.0.0.1:6379> geohash China dongguan guangzhou shenzhen
1) "ws0fuqz90u0"
2) "ws0e9xg09v0"
3) "ws0br3xnkn0"
127.0.0.1:6379>

Hyperloglog

hyperloglog 表示基数,在 redis 2.8.9 的版本中添加的数据结构,hyperloglog 是用来做基数统计的算法,优点是在输入的元素数量或者体积非常非常大的时候,计算基数的空间是固定、并且特别小的。

每个Hyperloglog 的 key 只需要花费 12 kb 内存,就可以计算出  2^64 个不同元素的基数。

 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

通常的应用,网页的浏览量(一个人访问一个网站多次,但是只会算作一个人)

什么是基数?

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

127.0.0.1:6379> pfadd testPF 1 2 3 4 5 6                # 添加一组元素
(integer) 1
127.0.0.1:6379> pfadd testPF1 1 0 6 7 8                 # 添加另外一组元素
(integer) 1
127.0.0.1:6379> pfcount testPF                          # 查看个数
(integer) 6
127.0.0.1:6379> pfcount testPF1
(integer) 5
127.0.0.1:6379> pfmerge newPF testPF testPF1            # 将 testPF 与 testPF1 合并之后的结果存到 newPF 中
OK
127.0.0.1:6379> pfcount newPF
(integer) 9
127.0.0.1:6379>

bitMaps

bitMaps 位图,是操作二进制来进行记录,只有 0 和 1两个状态。

应用:比如统计用户信息,活跃或者不活跃,登录,未登录;打卡记录,365 天打卡, 365 天 = 365 bit , 1 字节 = 8 bit  46 个字节左右

127.0.0.1:6379> setbit sign 1 0            # 添加数据
(integer) 0
127.0.0.1:6379> setbit sign 2 1
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 0
(integer) 0
127.0.0.1:6379> setbit sign 5 1
(integer) 0
127.0.0.1:6379> setbit sign 6 1
(integer) 0
127.0.0.1:6379> setbit sign 7 1
(integer) 0
127.0.0.1:6379> getbit sign 2
(integer) 1
127.0.0.1:6379> getbit sign 1
(integer) 0
127.0.0.1:6379> bitcount sign              #  统计
(integer) 5
127.0.0.1:6379>

猜你喜欢

转载自blog.csdn.net/qq_18948359/article/details/115211290
今日推荐