持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第28天,点击查看活动详情
Redis的基本数据类型
redis是以key-value形式保存,并且所有的key都是字符串,所以讨论基础数据结构都是讨论的value值的数据类型。Redis的基本数据结构有5种,String-字符串、List-列表、Hash-哈希、Set-集合、ZSet-有序集合。
本文中的指令可以使用网页版的 Web Redis 直接免安装上手。
String-字符串
String是redis最基本的类型,一个key对应一个value,字符串数据结构存储的值可以是字符串、整型和浮点型,可以对整个字符串或字符串的一部分进行操作,对整数或浮点数进行自增或自减操作。一个字符串value中最大可以存储512M。
在常见用途中,可以用户缓存json序列化的字符串、序列化对象或者二进制jpg图像。
命令
set (key) (value)
:设置键值对setnx (key) (value)
:防止覆盖,设置键值对,如果key不存在就设置,返回1; 如果key已经存在就不设置,返回0get(key)
:获取key对应的valuegetset (key) (value)
:先get再set,返回旧值,如果没有旧值返回nilappend (key) (value)
:向指定的key的value后追加字符串del (key)
:删除keystrlen (key)
:获取key对应值的字符串长度
> set name 鳄鱼儿
OK
> get name
"鳄鱼儿"
> setnx name 鳄鱼儿
(integer) 0
> strlen name
(integer) 9
> getset name new-鳄鱼儿
"鳄鱼儿"
> del name
(integer) 1
> get name
(nil)
getrange (key) (begin) (end)
:获取字符串[begin,end]下标范围内的值setrange (key) (begin) (xxxx)
:从begin下标开始将后续4位字符内容替换成xxx值,替换长度为新内容xxxx的长度
注:字符串统计的字节数,而中文的编码采用unicode编码,一个汉字占用三个字节
代码语言:javascript复制> set name 鳄鱼儿
OK
> getrange name 0 5 # 中文占3字节
"鳄鱼"
> setrange name 6 大王
12
> get name
"鳄鱼大王"
- 设置键值过期时间,缓存的key-value到期自动删除
setex (key) (seconds) expire
:设置键过期时间ttl (key)
:查看key剩余存活时间
> get name
"鳄鱼儿"
> setex name 5 expire
OK
> ttl name
(integer) 3
> ttl name
(integer) 0
> get name
(nil)
redis可以同时设置或获取多个key-value,以节省系统开销
mset (key1) (value1) (key2) (value2)
:用于同时设置一个或多个 key-value 对mget (key1) (key2)
:返回所有(一个或多个)给定 key 的值(如果某个key不存在,不存在的key返回null)msetnx (key1) (value1) (key2) (value2)
:当所有 key 都成功设置,返回 1 。 如果有一个key设置失败,所有的key设置都会失败,返回 0 。
> mset name1 鳄鱼儿 name2 鳄鱼 name3 鱼儿
OK
> mget name1 name2 name3
1) "鳄鱼儿"
2) "鳄鱼"
3) "鱼儿"
> msetnx name3 new-鱼儿 name4 小鱼儿
(integer) 0
> mget name1 name2 name3 name4
1) "鳄鱼儿"
2) "鳄鱼"
3) "鱼儿"
4) (nil)
string中数字value(整型、浮点型)的加减操作命令
incr (key)
:value 1decr (key)
:value - 1incrby (key) (number)
:value numberdecrby (key) (number)
:value - number
> set cnt 1
OK
> get cnt
"1"
> incr cnt
(integer) 2
> get cnt
"2"
> incrby cnt 10
(integer) 12
> decr cnt
(integer) 11
> decrby cnt 10
(integer) 1
使用场景
- 缓存: 将热加载的数据缓存,降低对db源的请求压力,如使用redis作为缓存层,mysql做持久化层,降低mysql的读写压力。
- 计数器:如统计文章访问量、点赞等。
- 分布式锁:如在一个集群环境下,多个web应用时对同一个商品进行抢购和减库存操作时,可能出现超卖时,会用到分布式锁。使用
SETNX key value
指令返回1表示获得锁,返回0表示获取锁失败,使用完毕后通过DEL key
指令释放锁。
List-列表
Redis中的List其实就是双端链表,与Java中LinkedList类似。
List可以通过指令实现栈、队列等基础数据结构
命令
- RPUSH key value:将给定值推入到列表右端
- LPUSH key value:将给定值推入到列表左端
- RPOP key:从列表的右端弹出一个值,并返回被弹出的值
- LPOP key:从列表的左端弹出一个值,并返回被弹出的值
- LRANGE key begin end:获取列表在给定范围上的所有值
- LINDEX key index:通过索引获取列表中的元素。你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
> rpush list a b c
(integer) 3
> lpush list b c
(integer) 5
> LRANGE list 0 5
1) "c"
2) "b"
3) "a"
4) "b"
5) "c"
> lpop list
"c"
> rpop list
"c"
> LRANGE list 0 3
1) "b"
2) "a"
3) "b"
> lindex list 2
"b"
应用场景
- 消息队列,将需要处理的任务结构序列化后存入list,以此按进入的顺序处理
Hash-哈希
Redis hash 是一个 string 类型的 field(字段) 和 value(属性) 的映射表,相当于Java中的HashMap,结构也是一致的,数组➕链表,不同的是redis中set的key只能是字符串。
一个hash可以存多个key-value,类似一个HashMap对象的多个字段和属性。
命令
- HSET hash-key sub-key1 value1:添加键值对
- HGET hash-key key1:获取指定散列键的值
- HGETALL hash-key:获取散列中包含的所有键值对
- HDEL hash-key sub-key1:如果给定键存在于散列中,那么就移除这个键
> hset hash a 1
1
> hget hash a
"1"
> hgetall hash
1) "a"
2) "1"
> hdel hash a
(integer) 1
> hget hash a
(nil)
应用场景
- 缓存:相比string缓存更节省空间,可以更直观的维护一系列关联的缓存消息,如一个set中缓存用户名称、账户、头像等信息。
Set-集合
Redis 的 Set 是 String 类型的无序集合,所有key的value都是null,结构上相当于Java中HashSet。Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)
指令
- SADD key value1 value2:向集合添加一个或多个成员
- SCARD key:获取集合的成员数
- SMEMBERS key:返回集合中的所有成员
- SISMEMBER key member:判断 member 元素是否是集合 key 的成员,返回1表示存在,返回0表示不存在
- SPOP:弹出一个集合成员
> sadd set a b
(integer) 2
> scard set
2
> smembers set
1) "b"
2) "a"
> sismember set a
(integer) 1
> spop set
"a"
> spop set
"b"
使用场景
- 标签(tag):给用户添加标签,或者用户给消息添加标签,这样有同一标签或者类似标签的可以给推荐关注的事或者关注的人。
- 点赞、点踩、收藏:可以放到set实现
ZSet-有序集合
Redis 有序集合和集合一样基本一致,相当于 Java 的 SortedSet 。每个 value都被赋予一个 score,代表这个 value 的排序权重,使得集合中的元素能够按score进行有序排列。ZSet通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
命令
- ZADD key score value:用于将一个或多个成员添加到有序集合中,或者更新已存在成员的 score 值
- ZCARD key:获取有序集合中成员的数量
- ZCOUNT key begin end:用于统计有序集合中指定 score 值范围内的元素个数
- ZINCRBY key:用于增加有序集合中成员的分值
- ZINTERSTORE :求两个或者多个有序集合的交集,并将所得结果存储在新的 key 中
- ZRANGE key begin end:返回有序集合中指定索引区间内的成员数量
- ZRANGEBYLEX:返回有序集中指定字典区间内的成员数量
- ZRANGEBYSCORE key scoremin scoremax:返回有序集合中指定分数区间内的成员
- ZRANK key value:返回有序集合中指定成员的排名
- ZREM:移除有序集合中的一个或多个成员
- ZREMRANGEBYRANK:移除有序集合中指定排名区间内的所有成员
- ZREMRANGEBYSCORE:移除有序集合中指定分数区间内的所有成员
- ZREVRANGE:返回有序集中指定区间内的成员,通过索引,分数从高到低
- ZREVRANK:返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
- ZSCORE key value:返回有序集中,指定成员的分数值
> zadd zset 1 a 2 b 3 c
(integer) 3
> zcard zset
3
> zcount zset 1 2
2
> zrange zset 0 -1 # 按 score 排序列出,参数区间为排名范围
1) "a"
2) "b"
3) "c"
> zrevrange zset 0 -1 # 按 score 逆序列出,参数区间为排名范围
1) "c"
2) "b"
3) "a"
> zscore zset a
1.0
> zrank zset c
2
> zrangebyscore zset 0 2
1) "a"
2) "b"
> zrangebyscore zset -inf 2 # 根据分值区间 (-∞, 2] 遍历 zset,同时返回分值。inf 代表 infinite,无穷大的意思。
1) "a"
2) "b"
> zrem zset a
1
> zrange zset 0 -1
1) "b"
2) "c"
使用场景
- 排行榜:有序集合经典使用场景。
- 粉丝列表:score可以是关注时间,以关注时间进行排序
- 权重分配:可以用sorted set来做带权重的队列