- 这里是redis数据库除string和list之外的数据类型,需要了解srting和list的可以转到上一篇文章:
https://blog.csdn.net/L18291789297/article/details/140531974
1.Set
- Redis 的 Set 是 String 类型的无序集合。集合中成员是唯一的,这就意味着集合中不能出现重复的数据。Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)
- Set类型一般用于赞、踩、标签、好友关系等。
向集合添加一个或多个成员
127.0.0.1:6379> SADD myset 1 1 2 2 3 3 4 4
(integer) 4
返回集合中的所有成员
127.0.0.1:6379> SMEMBERS myset
1) "1"
2) "2"
3) "3"
4) "4"
返回集合中一个或多个随机数
127.0.0.1:6379> SRANDMEMBER myset
"2"
127.0.0.1:6379> SRANDMEMBER myset 4
1) "1"
2) "2"
3) "3"
4) "4"
SCARD key获取集合的成员数
127.0.0.1:6379> SCARD myset
(integer) 4
判断 member 元素是否是集合 key 的成员
127.0.0.1:6379> SISMEMBER myset 5
(integer) 0
127.0.0.1:6379> SISMEMBER myset 3
(integer) 1
移除集合中一个或多个成员
127.0.0.1:6379> SREM myset 3 4
(integer) 2
127.0.0.1:6379> SMEMBERS myset
1) "1"
2) "2"
测试数据准备
127.0.0.1:6379> SADD myset2 1 2 3 4
(integer) 4
127.0.0.1:6379> SMEMBERS myset2
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> sadd myset3 1 3 4 5
(integer) 4
127.0.0.1:6379> SMEMBERS myset3
1) "1"
2) "3"
3) "4"
4) "5"
返回给定所有集合的差集
127.0.0.1:6379> SDIFF myset2 myset3
1) "2"
返回给定所有集合的差集并存储在 destination 中
127.0.0.1:6379> SDIFFSTORE myset4 myset2 myset3
(integer) 1
127.0.0.1:6379> SMEMBERS myset4
1) "2"
返回给定所有集合的交集
127.0.0.1:6379> SINTER myset2 myset3
1) "1"
2) "3"
3) "4"
返回给定所有集合的交集并存储在 destination 中
127.0.0.1:6379> SINTERSTORE myset5 myset2 myset3
(integer) 3
127.0.0.1:6379> SMEMBERS myset5
1) "1"
2) "3"
3) "4"
返回所有给定集合的并集
127.0.0.1:6379> SUNION myset2 myset3
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
将 member 元素从 source 集合移动到 destination 集合
127.0.0.1:6379> SMOVE myset2 myset3 2
(integer) 1
127.0.0.1:6379> SMEMBERS myset2
1) "1"
2) "3"
3) "4"
127.0.0.1:6379> SMEMBERS myset3
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
移除并返回集合中的一个随机元素
127.0.0.1:6379> SPOP myset3
"2"
127.0.0.1:6379> SMEMBERS myset3
1) "1"
2) "3"
3) "4"
4) "5"
127.0.0.1:6379> SPOP myset3 2
1) "3"
2) "5"
127.0.0.1:6379> SMEMBERS myset3
1) "1"
2) "4"
迭代集合中的元素 :SSCAN key cursor [MATCH pattern] [COUNT count]
127.0.0.1:6379> sadd myset6 'apple' 'banana' 'berry' 'blueberry' 'peach' 'grape' 'watermelon' 'strawberry' 'pear'
(integer) 9
127.0.0.1:6379> SMEMBERS myset6
1) "apple"
2) "banana"
3) "berry"
4) "blueberry"
5) "peach"
6) "grape"
7) "watermelon"
8) "strawberry"
9) "pear"
127.0.0.1:6379> SSCAN myset6 5 count 3 match *a*
1) "0"
2) 1) "apple"
2) "banana"
3) "peach"
4) "grape"
5) "watermelon"
6) "strawberry"
7) "pear"
- 注意:SCAN 是一个基于游标的迭代器,需要基于上一次的游标延续之前的迭代过程。SCAN 以 0 作为游标,开始一次新的迭代,直到命令返回游标 0 完成一次遍历。
此命令并不保证每次执行都返回某个给定数量的元素,甚至会返回 0 个元素,但只要游标不是 0,程序都不会认为 SCAN 命令结束,但是返回的元素数量大概率符合 Count 参数。另外,SCAN 支持模糊查询。
2.ZSet
- Redis 有序集合和集合一样也是string类型元素的集合且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。
- Zset类型一般用于排行榜等。
向有序集合添加一个或多个成员,或者更新已存在成员的分数
127.0.0.1:6379> ZADD myzset 20 'zhangsan' 40 lisi 80 wangwu
(integer) 3
通过索引区间返回有序集合指定区间内的成员
127.0.0.1:6379> ZRANGE myzset 0 -1 withscores
1) "zhangsan"
2) "20"
3) "lisi"
4) "40"
5) "wangwu"
6) "80"
获取有序集合的成员数
127.0.0.1:6379> ZCARD myzset
(integer) 3
计算在有序集合中指定区间分数的成员数
127.0.0.1:6379> ZCOUNT myzset 20 40
(integer) 2
127.0.0.1:6379> ZCOUNT myzset 10 100
(integer) 3
有序集合中对指定成员的分数加上增量 increment
127.0.0.1:6379> ZADD myzset incr 60 zhaoliu
"60"
127.0.0.1:6379> ZRANGE myzset 0 -1 withscores
1) "zhangsan"
2) "20"
3) "lisi"
4) "40"
5) "zhaoliu"
6) "60"
7) "wangwu"
8) "80"
127.0.0.1:6379> ZADD myzset incr 60 zhaoliu
"120"
127.0.0.1:6379> ZRANGE myzset 0 -1 withscores
1) "zhangsan"
2) "20"
3) "lisi"
4) "40"
5) "wangwu"
6) "80"
7) "zhaoliu"
8) "120"
127.0.0.1:6379> ZADD myzset2 70 a 70 b 70 c 70 d 70 e 70 f
(integer) 6
通过索引区间返回有序集合指定区间内的成员
127.0.0.1:6379> ZRANGE myzset2 0 -1 withscores
1) "a"
2) "70"
3) "b"
4) "70"
5) "c"
6) "70"
7) "d"
8) "70"
9) "e"
10) "70"
11) "f"
12) "70"
通过字典区间返回有序集合的成员,前提是元素分数一样
127.0.0.1:6379> ZRANGEBYLEX myzset2 - +
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
127.0.0.1:6379> ZRANGEBYLEX myzset2 [a [d
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> ZRANGEBYLEX myzset2 [c [f
1) "c"
2) "d"
3) "e"
4) "f"
在有序集合中计算指定字典区间内成员数量
127.0.0.1:6379> ZLEXCOUNT myzset2 - +
(integer) 6
127.0.0.1:6379> ZLEXCOUNT myzset2 [b [f
(integer) 5
通过分数返回有序集合指定区间内的成员
127.0.0.1:6379> ZRANGEBYSCORE myzset 20 80
1) "zhangsan"
2) "lisi"
3) "tony"
4) "lily"
5) "wangwu"
返回有序集合中指定成员的索引
127.0.0.1:6379> ZRANK myzset tony
(integer) 2
通过索引区间返回有序集合指定区间内的成员
127.0.0.1:6379> ZRANGE myzset 0 -1
1) "zhangsan"
2) "lisi"
3) "tony"
4) "lily"
5) "wangwu"
6) "zhaoliu"
通过索引区间返回有序集合指定区间内的成员
127.0.0.1:6379> ZRANGE myzset 0 -1 withscores
1) "zhangsan"
2) "20"
3) "lisi"
4) "40"
5) "tony"
6) "40"
7) "lily"
8) "60"
9) "wangwu"
10) "80"
11) "zhaoliu"
12) "120"
返回有序集中指定区间内的成员,通过索引,分数从高到低
127.0.0.1:6379> ZREVRANGE myzset 0 -1 withscores
1) "zhaoliu"
2) "120"
3) "wangwu"
4) "80"
5) "lily"
6) "60"
7) "tony"
8) "40"
9) "lisi"
10) "40"
11) "zhangsan"
12) "20"
返回有序集合中指定成员的索引
127.0.0.1:6379> ZRANK myzset zhangsan
(integer) 0
返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
127.0.0.1:6379> ZRevrANK myzset zhangsan
(integer) 5
返回有序集中,成员的分数值
127.0.0.1:6379> ZSCORE myzset zhangsan
"20"
- ZADD的语法里的相关内容
LT: Only update existing elements if the new score is less than the current score. This flag doesn’t prevent adding new elements.
less than: 只更新的分数小于当前分数的已存在的元素
GT: Only update existing elements if the new score is greater than the current score. This flag doesn’t prevent adding new elements.
greater than: 只更新分数大于当前分数的已存在元素,
CH: 修改返回元素的数量:ZADD可以做更新的操作,可以不对我们未做更改的元素做统计,只返回新添加的和更新的元素数量
2.Hash
- Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。
- Hash类型一般用于存储用户信息、用户主页访问量、组合查询等。
将哈希表 key 中的字段 field 的值设为 value
127.0.0.1:6379> hset myhash name zhangsan age 20 gender M
(integer) 3
127.0.0.1:6379> hset myhash2 name zhangsan age 20 gender M name lisi
(integer) 3
获取存储在哈希表中指定字段的值
127.0.0.1:6379> HGET myhash name
"zhangsan"
127.0.0.1:6379> HGET myhash2 name
"lisi"
获取在哈希表中指定 key 的所有字段和值
127.0.0.1:6379> HGETALL myhash
1) "name"
2) "zhangsan"
3) "age"
4) "20"
5) "gender"
6) "M"
127.0.0.1:6379> HGETALL myhash2
1) "name"
2) "lisi"
3) "age"
4) "20"
5) "gender"
6) "M"
只有在字段 field 不存在时,设置哈希表字段的值
127.0.0.1:6379> HEXISTS myhash name
(integer) 1
127.0.0.1:6379> HEXISTS myhash one
(integer) 0
获取哈希表中所有值
127.0.0.1:6379> HVALS myhash
1) "zhangsan"
2) "20"
3) "M"
获取所有哈希表中的字段
127.0.0.1:6379> HKEYS myhash
1) "name"
2) "age"
3) "gender"
获取哈希表中字段的数量
127.0.0.1:6379> HLEN myhash
(integer) 3
获取所有给定字段的值
127.0.0.1:6379> HMGET myhash name age gender
1) "zhangsan"
2) "20"
3) "M"
为哈希表 key 中的指定字段的整数值加上增量 increment
127.0.0.1:6379> HINCRBY myhash age 10
(integer) 30
为哈希表 key 中的指定字段的浮点数值加上增量 increment
127.0.0.1:6379> HINCRBYfloat myhash age 10.1
"40.1"
删除一个或多个哈希表字段
127.0.0.1:6379> HDEL myhash gender
(integer) 1
127.0.0.1:6379> HKEYS myhash
1) "name"
2) "age"
3.Bitmaps
- 位图
- Bitmaps本身不是一种数据类型,实际上它就是字符串(key-value),但是它可以对字符串的位进行操作。
- Bitmaps单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同。 可以把Bitmaps想象成一个以位为单位的数组, 数组的每个单元只能存储0和1, 数组的下标在Bitmaps中叫做偏移量。
下面示例是代表 2024-07-19 这天的独立访问用户的Bitmaps
127.0.0.1:6379> setbit unique:users:20240719 1 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240719 7 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240719 14 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240719 21 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240719 28 1
(integer) 0
getbit用于获取Bitmaps中某个偏移量的值
127.0.0.1:6379> getbit unique:users:20240719 1
(integer) 1
127.0.0.1:6379> getbit unique:users:20240719 2
(integer) 0
BITCOUNT:这个命令用于统计字符串被设置为1的bit数。一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。start 和 end 参数的设置,都可以使用负数值:比如 -1 表示最后一个位,而 -2 表示倒数第二个位,start、end 是指bit组的字节的下标数,二者皆包含。
127.0.0.1:6379> BITCOUNT unique:user:20240719
(integer) 0
127.0.0.1:6379> BITCOUNT unique:users:20240719
(integer) 5
测试一周上班情况
127.0.0.1:6379> SETBIT weekwork 1 1
(integer) 0
127.0.0.1:6379> SETBIT weekwork 2 1
(integer) 0
127.0.0.1:6379> SETBIT weekwork 3 1
(integer) 0
127.0.0.1:6379> SETBIT weekwork 4 1
(integer) 0
127.0.0.1:6379> SETBIT weekwork 5 1
(integer) 0
127.0.0.1:6379> SETBIT weekwork 6 1
(integer) 0
127.0.0.1:6379> BITCOUNT weekwork
(integer) 6
127.0.0.1:6379> BITCOUNT weekwork 1 5 bit
(integer) 5
127.0.0.1:6379> BITCOUNT weekwork 3 7 bit
(integer) 4
bitop:这个命令是一个复合操作, 它可以做多个Bitmaps的and(交集) 、 or(并集) 、 not(非) 、 xor(异或) 操作并将结果保存在destkey中。
127.0.0.1:6379> setbit eight 3 1
(integer) 0
127.0.0.1:6379> setbit ten 1 1
(integer) 0
127.0.0.1:6379> setbit ten 3 1
(integer) 0
127.0.0.1:6379> BITOP and ten eight
(integer) 1
127.0.0.1:6379> BITOP and result ten eight
(integer) 1
127.0.0.1:6379> getbit result 3
(integer) 1
127.0.0.1:6379> getbit result 2
(integer) 0
127.0.0.1:6379> getbit result 1
(integer) 0
127.0.0.1:6379> BITOP or result2 ten eight
(integer) 1
127.0.0.1:6379> getbit result2 1
(integer) 0
127.0.0.1:6379> getbit ten 1
(integer) 0
127.0.0.1:6379> setbit ten 1 1
(integer) 0
127.0.0.1:6379> BITOP or result2 ten eight
(integer) 1
127.0.0.1:6379> getbit result2 1
(integer) 1
127.0.0.1:6379> getbit result2 3
(integer) 1
127.0.0.1:6379> getbit result2 4
(integer) 0
127.0.0.1:6379> getbit result2 2
(integer) 0
127.0.0.1:6379> BITOP not result3 eight
(integer) 1
127.0.0.1:6379> getbit result3 3
(integer) 0
127.0.0.1:6379> getbit result3 1
(integer) 1
127.0.0.1:6379> getbit result3 2
(integer) 1
127.0.0.1:6379> getbit result3 0
(integer) 1
127.0.0.1:6379> getbit result3 8
(integer) 0
127.0.0.1:6379> BITOP xor result4 eight ten
(integer) 1
127.0.0.1:6379> GETBIT result4 4
(integer) 0
127.0.0.1:6379> GETBIT result4 3
(integer) 0
127.0.0.1:6379> GETBIT result4 2
(integer) 0
127.0.0.1:6379> GETBIT result4 1
(integer) 1
测试这两天都访问过网站的用户的数量
127.0.0.1:6379> setbit unique:users:20240719 2 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240719 10 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240719 15 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240719 19 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240719 20 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240718 1 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240718 2 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240718 10 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240718 15 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240718 19 1
(integer) 0
127.0.0.1:6379> setbit unique:users:20240718 20 1
(integer) 0
127.0.0.1:6379> BITCOUNT unique:users:20240718
(integer) 6
127.0.0.1:6379> BITCOUNT unique:users:20240719
(integer) 10
127.0.0.1:6379> BITOP and result5 unique:users:20240718 unique:users:20240719
(integer) 4
127.0.0.1:6379> BITCOUNT result5
(integer) 6
4.HyperLogLog
- 解决基数问题(像UV(UniqueVisitor,独立访客)、独立IP数、搜索记录数等需要去重和计数的问题如何解决?这种求集合中不重复元素个数的问题称为基数问题)
什么是基数?
比如数据集 {1, 3, 5, 7, 5, 7, 8},那么这个数据集的基数集为 {1, 3, 5 ,7, 8},基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。
解决基数问题有很多种方案:
1)数据存储在MySQL表中,使用distinct count计算不重复个数
2)使用Redis提供的hash、set、bitmaps等数据结构来处理
以上的方案结果精确,但随着数据不断增加,导致占用空间越来越大,对于非常大的数据集是不切实际的。
为了能够降低一定的精度来平衡存储空间,Redis推出了HyperLogLog。
相关命令
添加指定元素到 HyperLogLog 中
127.0.0.1:6379> PFADD myhyper 1 1 2 2 3 3 4 4 5 5 6 6 7 7
(integer) 1
127.0.0.1:6379> PFADD myhyper2 8 8 9 9 10 10 11 11 12 13 14
(integer) 1
返回给定 HyperLogLog 的基数估算值
127.0.0.1:6379> PFCOUNT myhyper
(integer) 7
127.0.0.1:6379> PFCOUNT myhyper2
(integer) 7
将多个 HyperLogLog 合并为一个 HyperLogLog
127.0.0.1:6379> PFMERGE myhyper3 myhyper myhyper2
OK
127.0.0.1:6379> PFCOUNT myhyper3
(integer) 14
5.Geospatial
- Redis 3.2 中增加了对GEO类型的支持。GEO,Geographic,地理信息的缩写。该类型,就是元素的2维坐标,在地图上就是经纬度。redis基于该类型,提供了经纬度设置,查询,范围查询,距离查询,经纬度Hash等常见操作。
添加数据
127.0.0.1:6379> GEOADD china:city 121.47 31.32 shanghai 108.94 34.26 xian
(integer) 2
127.0.0.1:6379> GEOADD china:city 113.62 34.74 zhengzhou 117.22 31.82 hefei
(integer) 2
127.0.0.1:6379> GEOADD china:city 118.79 32.06 nanjing 114.30 30.59 wuhan
(integer) 2
127.0.0.1:6379> GEOADD china:city 120.15 30.27 hangzhou 115.49 28.70 nanchang
(integer) 2
127.0.0.1:6379> GEOADD china:city 106.55 29.56 chongqing
(integer) 1
查看城市信息
127.0.0.1:6379> GEOPOS china:city shanghai
1) 1) "121.47000163793563843"
2) "31.3199993839624824"
输出两城市之间直线距离
127.0.0.1:6379> GEODIST china:city shanghai xian km
"1215.4403"
以哈希值输出
127.0.0.1:6379> GEOHASH china:city shanghai
1) "wtw6hjeu0p0"
127.0.0.1:6379> GEOHASH china:city xian
1) "wqj6yuzdvy0"
输出某一经纬度范围内的城市
127.0.0.1:6379> GEORADIUS china:city 108.94 34.26 1000 km
1) "xian"
2) "chongqing"
3) "zhengzhou"
4) "nanjing"
5) "nanchang"
6) "wuhan"
7) "hefei"