五:redis的三种特殊数据类型
一:geospatial 地理位置
定位,附近的人,距离计算;该功能可以推算出地理位置信息,两地间距离,周围几里的人!
Redis GEOHASH 命令 返回一个或多个位置元素的 Geohash 表示
Redis GEOPOS 命令 从key里返回所有给定位置元素的位置(经度和纬度)
Redis GEODIST 命令 返回两个给定位置之间的距离
Redis GEORADIUS 命令 以给定的经纬度为中心, 找出某一半径内的元素
Redis GEOADD 命令 将指定的地理空间位置(纬度、经度、名称)添加到指定的key中
Redis GEORADIUSBYMEMBER 命令 找出位于指定范围内的元素,中心点是由给定的位置元素决定
国内城市经纬度查询:http://www.jsons.cn/lngcode/
官方文档:https://www.redis.net.cn/order/3685.html
有效的经度从-180度到180度。
有效的纬度从-85.05112878度到85.05112878度。
#geoadd
#一般下载城市数据通过java程序存入
127.0.0.1:6379> geoadd china:city 106.504962 29.533155 chongqing #添加地理位置坐标
(integer) 1
127.0.0.1:6379> geoadd china:city 121.472644 31.231706 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 120.153576 30.287459 hangzhou
(integer) 1
#geopos
127.0.0.1:6379> geopos china:city chongqing #获取指定城市的经度和纬度
1) 1) "106.50495976209640503"
2) "29.53315530684997015"
#geodist 两地间直线距离
m 表示单位为米。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。
127.0.0.1:6379> geodist china:city chongqing shanghai km #查看重庆到上海的直线距离,单位km
"1447.3973"
#georadius 附近的人,获取某半径内的元素
127.0.0.1:6379> georadius china:city 110 30 500 km #获取(110,30)坐标半径500km范围内的城市
1) "chongqing"
127.0.0.1:6379> georadius china:city 110 30 500 km withdist #获取(110,30)坐标半径500km范围内的城市并显示距离到中心坐标的距离
1) 1) "chongqing"
2) "341.4052"
127.0.0.1:6379> georadius china:city 110 30 500 km withcoord #获取(110,30)坐标半径500km范围内的城市并显示城市坐标
1) 1) "chongqing"
2) 1) "106.50495976209640503"
2) "29.53315530684997015"
127.0.0.1:6379> georadius china:city 110 30 500 km count 1 #获取(110,30)坐标半径500km范围内的城市并限制查询的个数
1) "chongqing"
#georadiusbymember 查找指定元素周围其它元素
127.0.0.1:6379> georadiusbymember china:city shanghai 1000 km #查找上海周围在半径1000km内的城市
1) "hangzhou"
2) "shanghai"
#geohash 返回一个或多个位置元素的geohash值
127.0.0.1:6379> geohash china:city chongqing shanghai #将二维的经纬度转换为一个字符串,字符串越相似距离越近
1) "wm78p86e170"
2) "wtw3sjt9vg0"
geo地理位置的原理其实就是Zset,可以用Zset命令来操作geo地理元素:
127.0.0.1:6379> zrange china:city 0 -1 #查看地理位置所有元素
1) "chongqing"
2) "hangzhou"
3) "shanghai"
127.0.0.1:6379> zrem china:city shanghai #移除地理位置某个元素
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1
1) "chongqing"
2) "hangzhou"
二.Hyperloglog(基数)
A={1,3,4,5,6,5} B={1,3,4,5,6}
基数(不重复的元素) = 5,可能存在误差但可接受。
Redis Hyperloglog 基数统计的算法
优点:占用的内存是固定的,存2^64个不同元素只需12KB内存
应用:例如网页的UV(一个人访问一个网站多次,只计算为一个人)
传统方式解决办法:用redis缓存set类型保存用户标识,统计set个数
这种办法的问题在于若存在大量访问量将会比较占用内存。我们的目的是为了计数而非保存用户标识,则可以用Hyperloglog来统计
127.0.0.1:6379> pfadd mykey a b c d e f g #创建第一组元素 mykey
(integer) 1
127.0.0.1:6379> pfadd mykey2 f g h i j k #创建第二组元素 mykey2
(integer) 1
127.0.0.1:6379> pfcount mykey #统计mykey元素的基数数量
(integer) 7
127.0.0.1:6379>
127.0.0.1:6379> pfcount mykey2
(integer) 6
127.0.0.1:6379> pfmerge mykey mykey2 #合并两组元素,并集
OK
127.0.0.1:6379> pfcount mykey #查看并集的数量
(integer) 11
如果统计不重复的数量且允许容错,就可使用Hyperloglog
三.Bitmaps(位存储-0,1)
用于统计拥有两个状态的情况:如用户的 活跃,不活跃;打卡,未打卡
Bitmaps位图,数据结构!只有0(false)和1(true)两个状态
# 使用Bitmaps来记录用户一周内是否打卡
# 周一:0 周二:0 周三:1 周四:0 周五:1 周六:1 周日:0
127.0.0.1:6379> setbit day 1 0
(integer) 0
127.0.0.1:6379> setbit day 2 0
(integer) 0
127.0.0.1:6379> setbit day 3 1
(integer) 0
127.0.0.1:6379> setbit day 4 0
(integer) 0
127.0.0.1:6379> setbit day 5 1
(integer) 0
127.0.0.1:6379> setbit day 6 1
(integer) 0
127.0.0.1:6379> setbit day 7 0
(integer) 0
#查看某天是否打卡
127.0.0.1:6379> getbit day 7
(integer) 0
127.0.0.1:6379> getbit day 6
(integer) 1
# 统计操作,统计打卡(true)的天数
127.0.0.1:6379> bitcount day
(integer) 3