Redis 入门(四)三种特殊数据类型

geospatial 地理位置

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

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

可以查询一些的测试数据:http://www.jsons.cn/lngcodeinfo/0706D99C19A781A3

Redis 入门(四)三种特殊数据类型

 

只有六个命令

Redis 入门(四)三种特殊数据类型

 GEOADD

 http://www.redis.cn/commands/geoadd.html

 geoadd 添加地理位置 将指定的地理空间位置(纬度、经度、名称)添加到指定的key中
 规则,两级无法直接添加,我们一般惠霞在城市数据,直接通过java程序一次性导入
 有效的经度从 -180度 到 180度
 有效的纬度从 -85.05112878度 到 85.05112878度
 当坐标位置超出上述指定范围时,该命令将会返回一个错误。

 参数 key 值 ()

127.0.0.1:6379> GEOADD china:city 116.40 39.90 beijing
(integer) 1
127.0.0.1:6379> GEOADD china:city 121.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> GEOADD china:city 123.42 41.79 liaoning
(integer) 1
127.0.0.1:6379> GEOADD china:city 121.61 38.91 dalian 114.05 22.52 shenzhen
(integer) 2
127.0.0.1:6379> GEOADD china:city 120.12 30.25 hangzhou 104.06 30.65 chengdu
(integer) 2

GEOPOS

http://www.redis.cn/commands/geopos.html

127.0.0.1:6379> GEOPOS china:city beijing    # 获取指定的城市的经度和纬度
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
127.0.0.1:6379> GEOPOS china:city dalian hangzhou
1) 1) "121.61000221967697144"
   2) "38.90999884014095045"
2) 1) "120.11999756097793579"
   2) "30.24999979792261939"

GEODIST

http://www.redis.cn/commands/geodist.html

从key里返回所有给定位置元素的位置(经度和纬度)。

返回两个给定位置之间的距离。

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

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

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

127.0.0.1:6379> GEODIST china:city beijing dalian km    # 查看 北京到大连的直线距离 单位km
"461.0231"
127.0.0.1:6379> GEODIST china:city hangzhou dalian km
"972.7919"

GEOREDIUS

http://www.redis.cn/commands/georadius.html

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

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

  • m 表示单位为米。
  • km 表示单位为千米。
  • mi 表示单位为英里。
  • ft 表示单位为英尺。
127.0.0.1:6379> GEORADIUS china:city 110 30 1500 km    #以110,30 这个经纬度为中心,寻找方圆1500km内的城市
1) "chengdu"
2) "shenzhen"
3) "hangzhou"
4) "shanghai"
5) "beijing"
6) "dalian"
127.0.0.1:6379> GEORADIUS china:city 110 30 1500 km withdist    # 显示到中心位置的直线距离
1) 1) "chengdu"
   2) "574.7802"
2) 1) "shenzhen"
   2) "924.6408"
3) 1) "hangzhou"
   2) "973.6527"
4) 1) "shanghai"
   2) "1105.9098"
5) 1) "beijing"
   2) "1245.2858"
6) 1) "dalian"
   2) "1452.2961"
127.0.0.1:6379> GEORADIUS china:city 110 30 1500 km withcoord    # 显示出城市的经纬度
1) 1) "chengdu"
   2) 1) "104.05999749898910522"
      2) "30.6499990746355806"
2) 1) "shenzhen"
   2) 1) "114.04999762773513794"
      2) "22.5200000879503861"
3) 1) "hangzhou"
   2) 1) "120.11999756097793579"
      2) "30.24999979792261939"
4) 1) "shanghai"
   2) 1) "121.47000163793563843"
      2) "31.22999903975783553"
5) 1) "beijing"
   2) 1) "116.39999896287918091"
      2) "39.90000009167092543"
6) 1) "dalian"
   2) 1) "121.61000221967697144"
      2) "38.90999884014095045"
127.0.0.1:6379> GEORADIUS china:city 110 30 1500 km withdist withcoord count 1 # 筛选出指定结果
1) 1) "chengdu"
   2) "574.7802"
   3) 1) "104.05999749898910522"
      2) "30.6499990746355806"
127.0.0.1:6379> GEORADIUS china:city 110 30 1500 km withdist withcoord count 2
1) 1) "chengdu"
   2) "574.7802"
   3) 1) "104.05999749898910522"
      2) "30.6499990746355806"
2) 1) "shenzhen"
   2) "924.6408"
   3) 1) "114.04999762773513794"
      2) "22.5200000879503861"

GEORADIUSBYMEMBER

http://www.redis.cn/commands/georadiusbymember.html 

127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 1500 km    # 显示指定城市方圆距离内的城市
1) "hangzhou"
2) "shanghai"
3) "beijing"
4) "dalian"
5) "liaoning"
127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 500 km
1) "beijing"
2) "dalian"

GEOHASH

http://www.redis.cn/commands/geohash.html 

返回一个或多个位置元素的 Geohash 表示。

# 将二维的经纬度转换为一维的字符串,如果两个字符串越接近,那么则距离越近
127.0.0.1:6379> GEOHASH china:city beijing dalian
1) "wx4fbxxfke0"
2) "wwymr73enm0"

GEO 底层的实现其实就是 zset ,我们可以使用zset命令来操作 geo

127.0.0.1:6379> ZRANGE china:city 0 -1    # 查看全部元素
1) "chengdu"
2) "shenzhen"
3) "hangzhou"
4) "shanghai"
5) "beijing"
6) "dalian"
7) "liaoning"
127.0.0.1:6379> ZREM china:city liaoning    # 移除 指定元素
(integer) 1
127.0.0.1:6379> ZRANGE china:city 0 -1
1) "chengdu"
2) "shenzhen"
3) "hangzhou"
4) "shanghai"
5) "beijing"
6) "dalian"

Hyperloglog

简介

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

Redis Hyperloglog 基数统计的算法

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

网页的UV(一个人访问一个网站多次,但是还是算作一个人)

创痛的方式,set 保存用户的id,就可以统计set中的元素数量作为标准判断

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

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

测试使用

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    # 统计 mykey 中的基数数量
(integer) 10
127.0.0.1:6379> PFADD mykey2 i j z x c v b n m     # 创建第二组元素 mykey2
(integer) 1
127.0.0.1:6379> PFCOUNT mykey2
(integer) 9
127.0.0.1:6379> PFMERGE mykey3 mykey mykey2    # 合并两组 mykey mykey2 => mykey3 并集
OK
127.0.0.1:6379> PFCOUNT mykey3    # 看并集的数量
(integer) 15

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

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

Bitmaps

位存储

统计用户信息,活跃、不活跃,登录、未登录,打卡、365打卡。

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

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

365天 = 365bit        1字节 = 8bit        46个字节左右

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

周一:1 周二:0 周三:0....

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 3
(integer) 1
127.0.0.1:6379> getbit sign 6
(integer) 0

统计操作,统计打卡的天数

127.0.0.1:6379> BITCOUNT sign    # 统计这周的打卡天数
(integer) 3

上一篇:CF521E Cycling City


下一篇:linux 下jq的使用