3.4 Set类型
简介
与List类似是一个列表功能,但Set是自动排重的,当需要存储一个列表数据,又不希望出现重复数据时,Set是一个很好的选择。
Set是String类型的无序集合,它底层其实是一个value为null的hash表,所以添加、删除、查找的时间复杂度都是O(1)。
sadd
将一个或多个元素添加到集合key中,已经存在的元素将被忽略。
sadd key value1 value2……
示例:
#向集合中添加值,最终只有v1 v2 v3 v4 v5 v6 127.0.0.1:6379> sadd k1 v1 v2 v2 v3 v4 v5 v6
smembers
取出该集合的所有元素。
smembers key
示例:
127.0.0.1:6379> smembers k1 1) "v2" 2) "v1" 3) "v3"
sismember
判断集合key中是否含有value元素,如有返回1,否则返回0。
sismember key value
示例:
127.0.0.1:6379> sismember k1 v1 (integer) 1 127.0.0.1:6379>
scard
返回该集合的元素个数。
scard key
示例:
127.0.0.1:6379> scard k1 (integer) 3 127.0.0.1:6379>
srem
删除集合中的一个或多个成员元素,不存在的成员元素会被忽略。
srem key value1 value2……
示例:
# 删除v1 v2 srem k1 v1 v2
spop
随机删除集合中一个元素并返回该元素。
spop key
示例:
spop k1 随机删除一个元素,并返回
srandmember
随机取出集合中count个元素,但不会删除。
srandmember key count
示例:
#随机取出集合中的2个元素 srandmember k1 2
smove
将value元素从sourcekey集合移动到destinationkey集合中。
smove sourcekey destinationkey value
示例:
smove k1 k2 v5 将元素v5从集合k1中移动到集合k2
注意:
如果 sourcekey集合不存在或不包含指定的 value元素,则 smove 命令不执行任何操作,仅返回 0 。
sinter
返回两个集合的交集元素。
sinter key1 key2
sunion
返回两个集合的并集元素。
sunion key1 key2
sdiff
返回两个集合的差集元素(key1中的,不包含key2)
sdiff key1 key2
使用场景
- 黑白名单
- 随机展示
- 好友
- 关注人
- 粉丝
- 感兴趣的人集合
3.4 Hash类型
简介
Hash是一个键值对的集合。Hash 是一个 String 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。
- Hash存储结构优化
- 如果field数量较少,存储结构优化为类数组结构
- 如果field数量较多,存储结构使用HashMap结构
hset
给key集合中的field赋值value。相当于是为实体类的属性赋值,此时的属性就相当于是key,属性的值相当于是value。
hset key field value
示例:
#为实体类user的属性name赋值为zhangsan 127.0.0.1:6379> hset user name zhangsan
注意:
- 如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作。
- 如果字段已经存在于哈希表中,旧值将被重写。
hget
从key哈希中,取出field字段的值。相当于是获取实体类哪个属性的值。
hget key field
示例:
#获取实体类user的name属性 127.0.0.1:6379> hget user name "zhangsan"
hmset
批量设置哈希的字段及值。
hmset key field1 value1 field2 value2……
示例:
#为user实体类设置name、age、addres属性并赋值 127.0.0.1:6379> hmset user name zhangsan age 19 address shandong OK
hexists
判断指定key中是否存在某个属性。
hexists key field
示例:
#判断user实体类中是否存在name属性 127.0.0.1:6379> hexists user name (integer) 1
注意:
如果哈希表含有给定字段,返回 1 。 如果哈希表不含有给定字段,或 key 不存在,返回 0 。
hkeys
获取该哈希中所有的field。获取该实体类的属性。
#获取user实体类的全部属性 127.0.0.1:6379> hkeys user 1) "name" 2) "age" 3) "address"
hvals key
获取该哈希中所有的value。获取该实体类的属性值。
hvals key
示例:
127.0.0.1:6379> hvals user 1) "zhangsan" 2) "19" 3) "shandong"
hincrby
为哈希表key中的field字段的值加上增量increment。
hincrby key field increment
示例:
#为实体类user的属性age增1 127.0.0.1:6379> hincrby user age 1 (integer) 20
hdel
删除哈希表 key 中的一个或多个指定字段,不存在的字段将被忽略。
hdel key field1 field2……
示例:
#删除user实体类的age和address属性 127.0.0.1:6379> hdel user age address (integer) 2
hsetnx
给key哈希表中不存在的的字段赋值 。
hsetnx key field value
示例:
#为user中不存在的属性age赋值,因为age属性不存在所以可以赋值。 127.0.0.1:6379> hset user age 10 (integer) 1 #因为name属性不存在所以无法为该属性赋值 127.0.0.1:6379> hset user name zhangsan (integer) 0
注意:
- 如果哈希表不存在,一个新的哈希表被创建并进行 hsetnx 操作。
- 如果字段已经存在于哈希表中,操作无效。
- 如果 key 不存在,一个新哈希表被创建并执行 hsetnx 命令。
使用场景
- 购物车
- 存储对象
3.5 Zset
简介
Zset与Set非常相似,是一个没有重复元素的String集合。不同之处是Zset的每个元素都关联了一个分数(score),这个分数被用来按照从低分到高分的方式排序集合中的元素。集合的元素是唯一的,但分数可以重复。-
注意:
因为元素是有序的,所以可以根据分数(score)或者次序(position)来获取一个范围内的元素。
zadd
将一个或多个元素(value)及分数(score)加入到有序集key中。
zadd key score1 value1 score2 value2……
示例:
#java分数是100,c++分数200,c分数300 127.0.0.1:6379> zadd k1 100 java 200 c++ 300 C (integer) 3
注意:
- 如果某个元素已经是有序集的元素,那么更新这个元素的分数值,并通过重新插入这个元素,来保证该元素在正确的位置上。
- 分数值可以是整数值或双精度浮点数。
- 如果有序集合 key 不存在,则创建一个空的有序集并执行 zadd 操作。
zrange
返回key集合中的索引start和索引end之间的元素(包含start和end)。
zrange key start end [withscores]
示例:
#返回集合中全部的元素 127.0.0.1:6379> zrange k1 0 -1 1) "java" 2) "c++" 3) "C" #返回集合中的元素和分数 127.0.0.1:6379> zrange k1 0 -1 withscores 1) "java" 2) "100" 3) "c++" 4) "200" 5) "C" 6) "300"
注意:
- 其中元素的位置按分数值递增(从小到大)来排序。 其中 0 表示列表的第一个元素,-1表示最后一个元素。
- withscores是可选参数,是否返回分数。
zrangebyscore
返回key集合中的分数minscore 和分数maxscore 之间的元素(包含minscore 和maxscore )。其中元素的位置按分数值递增(从小到大)来排序。
zrangebyscore key minscore maxscore [withscores]
示例:
127.0.0.1:6379> zrangebyscore k1 100 300 [withscores] 1) "java" 2) "c++" 3) "C"
zincrby
为元素value的score加上increment的值。
zincrby key increment value
示例:
#给Java加50 127.0.0.1:6379> zincrby k1 50 java "150"
zrem
删除该集合下value的元素。
zrem k1 php 删除php
zcount
统计该集合在minscore 到maxscore分数区间中元素的个数。
zcount key minscore maxscore
示例:
zcount k1 100 300 统计100分到300分中间元素的个数
zrank
返回value在集合中的排名,从0开始。
zrank key value
示例:
zrank k1 c++ 返回c++排名
使用场景
- 延时队列
- 排行榜
- 限流
3.6 itmaps类型(较难理解)
简介
在计算机中,用二进制(位)作为存储信息的基本单位,1个字节等于8位。
例如 "abc" 字符串是由 3 个字节组成,计算机存储时使用其二进制表示,"abc"分别对应的ASCII码是97、98、99,对应的二进制是01100001、01100010、01100011,在内存中表示如下:
合理地使用位能够有效地提高内存使用率和开发效率。
Redis提供了Bitmaps这个 “数据结构” 可以实现对位的操作:
setbit
设置Bitmaps中某个偏移量的值。
setbit key offset value
示例:
redis中bitmaps可以用来统计用户信息,eg:活跃天数、打卡天数、登录天数
bitmaps位图,都是操作二进制来进行记录,就只有0和1两个状态
统计zhangsan4月份考勤情况,第二个数字代表的是天,第三个数字代表是否迟到:1未迟到0迟到 127.0.0.1:6379> bitcount zhangsan (integer) 0 127.0.0.1:6379> setbit zhangsan:4 1 1 (integer) 1 127.0.0.1:6379> setbit zhangsan:4 2 1 (integer) 1 127.0.0.1:6379> setbit zhangsan:4 3 0 (integer) 0 127.0.0.1:6379> setbit zhangsan:4 4 1 (integer) 1
注意 最后一个数字是偏移量的值,倒数第二个叫偏移量。
getbit
获取Bitmaps中某个偏移量的值。
getbit key offset
示例:
获取key的offset 的值。
127.0.0.1:6379> getbit zhangsan 3 (integer) 0
bitcount
统计字符串被设置为1的bit数量。一般情况下,给定的整个字符串都会被进行统计,可以选择通过额外的start和end参数,指定字节组范围内进行统计(包括start和end),0表示第一个元素,-1表示最后一个元素。
bitcount key [start end]
示例:
bitcount sign 获取整个字符串被设置为1的bit数量,结果为3
如:当前存在一个key为k1的bitmaps存储着[00000001,00000001,00000010,00000011],分别对应[1,1,2,3]。
setbit num 7 1 setbit num 15 1 setbit num 22 1 setbit num 30 1 setbit num 31 1 bitcount num 1 2 统计索引1、2两个字节组中bit=1的数量,即统计00000001,00000010中bit=1的数量,结果为2 bitcount num 1 3 统计索引1、2、3三个字节组中bit=1的数量,即统计00000001,00000010,00000011中bit=1的数量,结果为4 bitcount num 0 -1 统计所有的字节组中bit=1的数量,结果为5
setbit设置或获取的是bit(位)的位置,bitcount计算的是byte(字节)位置。
bitop
将多个bitmaps通过求交集/并集方式合并成一个新的bitmaps。
bitop and/or destkey sourcekey1 sourcekey2……
示例:
bitop and k3 k1 k2 通过求交集将k1 k2合并成k3 bitop or k3 k1 k2 通过求并集将k1 k2合并成k3
使用场景
- 活跃天数
- 打卡天数
- 登录天数
- 用户签到
- 统计活跃用户
- 统计用户是否在线
- 实现布隆过滤器
3.7 Geospatia
简介
GEO,Geographic,地理信息的缩写。该类型就是元素的二维坐标,在地图上就是经纬度。Redis基于该类型,提供了经纬度设置、查询、范围查询、距离查询、经纬度Hash等常见操作。
geoadd
用于存储指定的地理空间位置,可以将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定的 key 中。
geoadd key longitude latitude member
示例:
# 将北京的经纬度和名称添加到china geoadd china 116.405285 39.904989 beijing # 将成都和上海的经纬度、名称添加到china geoadd china 104.065735 30.659462 chengdu 121.472644 31.231706 shanghai
geopos
从给定的 key 里返回所有指定名称(member)的位置(经度和纬度),不存在的返回 nil。
geopos key member [member ……]
示例:
#返回china中名称为shanghai和beijing的经纬度 geopos china shanghai beijing
geodist
用于返回两个给定位置之间的距离。
geodist key member1 member2 [m|km|ft|mi]
参数说明:
- m :米,默认单位。
- km :千米。
- mi :英里。
- ft :英尺。
# 返回shanghai和beijing之间的距离,结果1067597.9668,单位米 geodist chinacity shanghai beijing # 返回shanghai和chengdu之间的距离,结果1660.0198,单位是千米 geodist chinacity shanghai chengdu km
georadius
以给定的经纬度(longitude latitude)为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离(radius )的所有位置元素。
georadius key longitude latitude radius m|km|ft|mi
示例:
#获取经纬度110 30为中心,在china内1200公里范围内的所有元素。 georadius china 110 30 1200 km
使用场景
- 附近的电影院
- 附近的好友
- 离最近的火锅店
前提是将这些商铺的坐标放到redis
3.8 HyperLogLog
简介
在我们做站点流量统计的时候一般会统计页面UV(独立访客:unique visitor)和PV(即页面浏览量:page view)。redis HyperLogLog是用来做基数统计的算法,HyperLogLog的优点是:在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且使很小的。
什么是基数
比如数据集{1,3,5,7,5,7,8},那么这个数据集的基数集为{1,3,5,7,8},基数(不重复元素)为5.基数估计就是在误差可接受的范围内,快速计算基数。
pfadd
将所有元素参数添加到 Hyperloglog 数据结构中。
pfadd key element1 element2……
示例:
如果至少有个元素被添加返回 1, 否则返回 0。
pfadd book1 uid1 uid2 uid3
注意:
添加元素到HyperLogLog中,如果内部有变动返回1,没有返回0。
pfcount
计算Hyperloglog 近似基数,可以计算多个Hyperloglog ,统计基数总数。
pfcount key1 key2……
示例:
pfcount book1 #计算book1的基数,结果为3 pfadd book2 uid3 uid4 #添加两个元素到book2中 pfcount book1 book2 #统计两个key的基数总数,结果为5
pfmerge
将一个或多个Hyperloglog(sourcekey1) 合并成一个Hyperloglog (destkey )。
pfmerge destkey sourcekey1 sourcekey2……
示例:
比如每月活跃用户可用每天活跃用户合并后计算。
#将book1和book2合并成book,结果为5 pfmerge book book1 book2
使用场景
基数不大,数据量不大就用不上,会有点大材小用浪费空间,有局限性,就是只能统计基数数量,而没办法去知道具体的内容是什么,和bitmap相比,属于两种特定统计情况,简单来说,HyperLogLog 去重比 bitmaps 方便很多,一般可以bitmap和hyperloglog配合使用,bitmap标识哪些用户活跃。
- 网站PV统计
- 网站UV统计
- 统计访问量(IP数)
- 统计在线用户数
- 统计每天搜索不同词条的个数
- 统计文章真实阅读数