Redis 的三种特殊数据类型
大多数时候,我们只知道 Redis 的五大数据结构,很多人也可能只知道这五个,而忽略了,其实 Redis 还提供了另外的三种特殊的类型,可以用在一些特殊的场景,在以后遇到这些场景的时,也可以多一种思路。
目录
GEO
概述:主要用于存储地理位置信息,并对存储的信息进行操作,该功能在 Redis 3.2 版本新增。将指定的地理空间项(经度、维度、名称)添加到指定的键中。使用的 zset 的形式存储,这样以后就可以使用 GEORADIUS
或GEORADIUSBYMEMBER
命令按半径查询检索项。
场景: 我们可以用在地图定位上、寻找附近好友、两地(两人)之间的距离等等
注意:
- 有效的经度从-180度到180度。
- 有效的纬度从-85.05112878度到85.05112878度。
- 非常接近极点的区域是不可索引的,比如南北极
添加地理位置
GEOADD key longitude(经度) latitude(维度) 名称 [...]
命令可以添加地理位置
192.168.200.132:6379> geoadd china:city 116.40 39.9 beijing
(integer) 1
192.168.200.132:6379> geoadd china:city 121.47 31.23 shanghai
(integer) 1
192.168.200.132:6379> geoadd china:city 106.50 29.53 chongqing 114.05 22.52 shenzheng
(integer) 2
192.168.200.132:6379> geoadd china:city 120.16 30.24 hangzhou 108.96 34.26 xian
(integer) 2
获取指定的城市的经度和纬度!
GEOPOS key member [member...]
可以获取指定的城市的维度和经度
192.168.200.132:6379> geopos china:city beijing
1) 1) "116.39999896287918091"
2) "39.90000009167092543"
查看附近的城市
在命令中,我们可以指定距离的单位
- m 表示单位为米。
- km 表示单位为千米。
- mi 表示单位为英里。
- ft 表示单位为英尺。
GEORADIUS key longitude latitude radius m|km|mi|ft [withcood] [withdist] ...
命令以给定的经纬度为中心,找出指定半径内的元素
192.168.200.132:6379> georadius china:city 110 30 500 km withdist # 找出以维度 110 经度 30 为中心 半径为 500 km 的城市,并且显示距离信息,单位为 km
1) 1) "chongqing"
2) "341.9374"
2) 1) "xian"
2) "483.8340"
指定显示的数量
192.168.200.132:6379> georadius china:city 110 30 500 km withdist withcoord count 1 ## 指定显示的数量
1) 1) "chongqing"
2) "341.9374"
3) 1) "106.49999767541885376"
2) "29.52999957900659211"
withdist
在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。withcoord
将位置元素的经度和维度也一并返回。count
后面指定显示的数量
两个城市的距离
GEODIST
命令可以算出两个城市之间的直径距离
192.168.200.132:6379> geodist china:city beijing shanghai km # 查看上海到北京的直线距离
"1067.3788"
返回字符串
GEOHASH
命令可以把我们的城市的经纬度信息,转为 11 个字符的字符串
192.168.200.132:6379> geohash china:city beijing
1) "wx4fbxxfke0"
192.168.200.132:6379> geohash china:city beijing xian
1) "wx4fbxxfke0"
2) "wqj6zky6bn0"
删除
底层的实现原理其实就是 zset!我们可以使用 zset命令来操作 geo!
192.168.200.132:6379> zrem china:city beijing # 使用了 zrem 命令删除了数据
(integer) 1
192.168.200.132:6379> geopos china:city beijing
1) (nil)
192.168.200.132:6379> zrange china:city 0 -1 # 使用 zrange 命令来获取保持了哪些信息
1) "xian"
2) "shenzheng"
3) "hangzhou"
4) "shangshi"
Hyperloglog
概述:Hyperloglog 是一种概率数据结构,用于计数唯一的事物。通常计数唯一项需要使用与您希望计数的项数成比例的内存,因为您需要记住过去已经看到的元素,以避免多次计数它们。
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的(每个 HyperLogLog 键只需要花费 12 KB 内存,可以计算接近 2^64 个不同元素的基 数)。
场景:通常,再做网站访问量统计的时候,每当一个人访问网站,网站的访问量就加一,而如果一个人多次访问,就只算是一次。
传统是使用 set 加保存用户的 id 来统计,因为 set 不会报错重复的用户,但是如果大量的用户 id 需要报错,就麻烦了,这个时候就可以使用我们 Redis 提供的 Hyperloglog,虽然官方说有 0.81% 的误差率,但是还是可以接受的。
创建
PFADD
命令可以用来创建一组元素
192.168.200.132:6379> pfadd user1 a b c d e f f a b c c
(integer) 1
统计
PFCOUNT
命令可以统计元素基数的数量
192.168.200.132:6379> pfcount user1
(integer) 6 # 统计元素的数量,重复的会只算 1 个
合并
PFMERGE
命令可以把两组合并,求出并集
192.168.200.132:6379> pfadd user2 g h i j k c c a b d # 新增一个用户列表
(integer) 1
192.168.200.132:6379> pfmerge user3 user1 user2 # 把 user1 user2 合并为 user3
OK
192.168.200.132:6379> pfcount user3
(integer) 11 # 查看数量,相同的发现合并了
Bitmap
位图,一种数据结构,是操作二进制来进行记录,只有 0 和 1 的两种状态
场景 : 上班打卡、登录和未登录、活跃和不活跃等只有两种状态的场景。
案例:
使用 bitmap 来记录周一到周日的打卡
添加
通过使用 SETBIT key offset value
命令来添加打卡信息
192.168.200.132:6379> setbit user 1 0
(integer) 0
192.168.200.132:6379> setbit user 2 0
(integer) 0
192.168.200.132:6379> setbit user 3 0
(integer) 0
192.168.200.132:6379> setbit user 4 1
(integer) 0
192.168.200.132:6379> setbit user 5 1
(integer) 0
192.168.200.132:6379> setbit user 6 1
(integer) 0
192.168.200.132:6379> setbit user 7 1
(integer) 0
统计
上面的 user,假设 value 为 1 表示打卡了,七天,一共是 4 ,5,6,7 打开,记为 1,其他天数为 0,这个时候我们可以统计一下打卡天数,当作是考核。
使用 BITCOUNT key [start end]
命令统计,该命令指挥统计 value 为 1 的。
192.168.200.132:6379> bitcount user
(integer) 4 # 一共是 4 天打卡了
总结
GEO 命令
命令 | 描述 |
---|---|
geoadd | 添加地理位置的坐标。 |
geopos | 获取地理位置的坐标。 |
geodist | 计算两个位置之间的距离。 |
georadius | 根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。 |
georadiusbymember | 根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。 |
geohash | 返回一个或多个位置对象的 geohash 值。 |
Hyperloglog 命令
命令 | 描述 |
---|---|
pfadd | 创建一组基数 |
pfcount | 统计数量 |
pfmerge | 命令可以把两组基数合并,求出并集 |
Bitmap 命令
命令 | 描述 |
---|---|
setbit | 添加 |
bigcount | 统计 |