在上篇文章中我们学习了Redis教程——数据类型(有序集合、位图),这篇文章学习Redis教程——数据类型(基数统计、地理空间、位域)。
基数统计HyperLogLog
HyperLogLog是用来做基数统计的算法,在输入元素的数量或者体积非常大时,计算基数所需的空间总是固定且是很小的。
每个HyperLogLog键只需花费12KB内存,就可以计算接近2^64个不同元素的基数。但HyperLogLog只会根据输入元素来计算基数,而不会存储输入元素本身,所以HyperLogLog不能返回输入的各个元素,而且返回元素去重后的个数。
基数统计一般用于统计某个文章的访客IP、搜索关键词的数量、统计用户搜索不同词条个数。
基本命令
使用pfadd命令定义一个基数统计类型数据,其语法格式如下:
pfadd 键 元素 [元素 ...] # 定义基数统计数据
pfcount 键 # 获取基数
示例代码如下:
pfadd hll1 1 2 3 5 6 7
pfadd hll2 4 4 5 6 7 8 9
合并
通过pfmerge命令合并两个基数统计类型数据,其语法格式如下:
pfmerge 合并后的键 键1 键2[键n ...]
示例代码如下:
pfmerge hll3 hll1 hll2
pfcount hll3
运行结果如下:
地理空间GEO
GEO主要用于存储地理位置信息,并对存储的信息进行操作,包括:
-
添加地理位置的坐标
-
获取地理位置的坐标
-
计算两个位置之间的距离;
-
根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。
基本命令
使用geoadd命令定义地理空间类型数据,其语法格式如下:
geoadd 键 经度 维度 位置名称 [经度 维度 位置名称 ...]
示例代码如下:
geoadd city 116.403963 39.915119 "天安门" 116.403414 39.924091 "故宫" 116.024067 40.362639 "长城"
type city
如下图所示:
获取
地理空间底层的类型是有序集合,所以我们可以通过zrange命令获取地理空间里面的元素,由于设置到中文,需要在启动redis客户端时添加--raw,示例代码如下:
redis-cli -a 123456 -p 6379 --raw
zrange city 0 -1
如下图所示:
通过geopos、geohash命令返回键的经纬度,其语法格式如下:
geopos 键 位置名称 [位置名称...]
geohash 键 位置名称 [位置名称...]
示例代码如下:
geopos city 天安门 故宫 长城 # 获取经纬度
geohash city 天安门 故宫 长城 # 获取hash转换后的经纬度
如下图所示:
地理距离
使用geodist命令获取两个位置之间的距离,其语法格式如下:
geodist 键 位置名 位置名 距离单位(m/km/ft/mi)
示例代码如下:
geodist city 长城 天安门 km
返回结果为:59.3390
使用georadius命令获取与中心的距离不超过给定最大距离的所有位置元素,其语法格式如下:
georadius 键 经纬度 最大距离 距离单位 withdist withcoord count 返回的数量 withhash desc
georadiusbymember 键 位置名 最大距离 距离单位 withdist withcoord count 返回的数量 withhash desc
其中:
-
withdist:在返回位置元素的同时,将位置元素与中心之间的距离也一起返回;
-
withcoord:将位置元素的经纬度一起返回;
-
withhash:以52位有符号整数的形式,返回位置元素经过元素geohash编码的有序集合分值。
示例代码如下:
georadius city 116.418017 39.914492 10 km withdist withcoord count 19 withhash desc
georadiusbymember city 天安门 10 km withdist withcoord count 19 withhash desc
如下图所示:
位域bitfield
通过bitfield命令可以一次性操作连续的多个bit位,它执行一系列操作并返回一个响应数组,这个数组中的元素对应参数列表中的相应操作的执行结果,能对变长位宽和任意没有字节对齐的指定整型位域进行寻址和修改。
基本命令
bitfield命令获取元素的字节,其语法格式如下:
bitfield 键 [get 有符号/无符号的整型数字 偏移量]
示例代码如下:
set field1 hello
bitfield field1 get i8 0
bitfield field1 get i8 8
运行结果如下:
注意:
-
由于hello的第一位为h,其二进制为:01101000,所以返回104;
-
一个字节是8位,所以偏移量8等于hello中的e,所以返回101;
-
i8表示有符号8位;
修改
当我们想修改bitfield里面的数据,可以通过set方法,示例代码如下:
bitfield field1 set i8 8 120
get field1
将第二个字符转为x(120),如下图所示:
也可以通过incrby方法对元素进行增删,示例代码如下:
bitfield field1 incrby u4 2 1 # 从第三个位开始,对接下来的4位无符号数+1
运行结果如下:
注意:当溢出时,会归零。
溢出控制
溢出控制主要有三种方式:
-
WRAP:使用回绕方法处理有符号整数和无符号整数的溢出情况,默认。
-
SAT:使用饱和计算方法处理溢出,下溢取最小的整数值,上溢取最大的整数值;
-
FAIL:拒绝执行导致溢出情况的的计算,并向用户返回空值表示计算未被执行。
示例代码如下:
set field2 a
bitfield field2 get i8 0
bitfield field2 overflow sat set i8 0 -130 # sat控制
bitfield field2 get i8 0
bitfield field2 overflow sat set i8 0 128 # sat控制
bitfield field2 get i8 0
bitfield field2 overflow fail set i8 0 128 # fail控制
bitfield field2 get i8 0
运行结果如下:
好了,Redis教程——数据类型(基数统计、地理空间、位域)就讲到这里了,下篇文章我们学习Redis教程——数据类型(流)。
公众号:白巧克力LIN
该公众号发布Python、数据库、Linux、Flask、Django、自动化测试、Git、算法、前端、服务器等相关文章!
- END -