Redis系列(一):Redis的五种基本数据类型/操作命令/操作实战/应用场景

2024-05-22 09:10:46 浏览数 (1)

持续创作,加速成长!这是我参与「掘金日新计划 · 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已经存在就不设置,返回0
  • get(key):获取key对应的value
  • getset (key) (value) :先get再set,返回旧值,如果没有旧值返回nil
  • append (key) (value):向指定的key的value后追加字符串
  • del (key) :删除key
  • strlen (key):获取key对应值的字符串长度
代码语言:javascript复制
> 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剩余存活时间
代码语言:javascript复制
> 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 。
代码语言:javascript复制
  > 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 1
  • decr (key) :value - 1
  • incrby (key) (number):value number
  • decrby (key) (number):value - number
代码语言:javascript复制
> 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 表示列表的倒数第二个元素,以此类推。
代码语言:javascript复制
> 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:如果给定键存在于散列中,那么就移除这个键
代码语言:javascript复制
> 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:弹出一个集合成员
代码语言:javascript复制
> 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:返回有序集中,指定成员的分数值
代码语言:javascript复制
> 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来做带权重的队列

0 人点赞