Redis系列文章一 Redis数据结构

1,064 阅读5分钟

Redis的数据结构

1、strings

set mystr "hello world!" //设置字符串类型
get mystr //读取字符串类型

还可以对字符串类型进行数值操作

127.0.0.1:6379> set mynum "2"
OK
127.0.0.1:6379> get mynum
"2"
127.0.0.1:6379> incr mynum
(integer) 3
127.0.0.1:6379> get mynum
"3"

在遇到数值操作时,redis会将字符串类型转换成数值。 由于INCR等指令本身就具有原子操作的特性,所以我们完全可以利用redis的INCR、INCRBY、DECR、DECRBY等指令来实现原子计数的效果,假如,在某种场景下有3个客户端同时读取了mynum的值(值为2),然后对其同时进行了加1的操作,那么,最后mynum的值一定是5。不少网站都利用redis的这个特性来实现业务上的统计计数需求。 如果有多客户同时执行setnx,只有一个能设置成功,可做分布式锁 set命令也支持批量处理,mset/mget批量设置和批量获取。批量操作提高了执行效率,否则一批次的n次查询需要发起n次请求。

2、哈希hash

Hash存的是字符串和字符串值之间的映射,特别适合存储对象,比如一个用户要存储其全名、姓氏、年龄等等,就很适合使用哈希(此处如果用String类型就会占用过多的key空间)。

  • hset key field value 单个赋值
  • hmset key field value [filed value]...批量赋值
//建立哈希,并赋值
127.0.0.1:6379> HMSET user:001 username antirez password P1pp0 age 34 
OK

//列出哈希的内容
127.0.0.1:6379> HGETALL user:001 
1) "username"
2) "antirez"
3) "password"
4) "P1pp0"
5) "age"
6) "34"

//更改哈希中的某一个值
127.0.0.1:6379> HSET user:001 password 12345 
(integer) 0

//再次列出哈希的内容
127.0.0.1:6379> HGETALL user:001 
1) "username"
2) "antirez"
3) "password"
4) "12345"
5) "age"
6) "34"

在这里插入图片描述 在一般应用场景中,用户信息缓存化,可以有三种解决方案,1、set存储,2、对象信息序列化存储,3、hset存储,用户信息不经常修改的情况可用2,value值不大的情况可以用3.

3、lists集合

首先要明确一点,redis中的lists在底层实现上并不是数组,而是链表,因此是增删改快,定位较慢。 lists的常用操作包括LPUSH、RPUSH、LRANGE等。我们可以用LPUSH在lists的左侧插入一个新元素,用RPUSH在lists的右侧插入一个新元素,用LRANGE命令从lists中指定一个范围来提取元素。

//新建一个list叫做mylist,并在列表头部插入元素"1"
127.0.0.1:6379> lpush mylist "1" 
//返回当前mylist中的元素个数
(integer) 1 
//在mylist右侧插入元素"2"
127.0.0.1:6379> rpush mylist "2" 
(integer) 2
//在mylist左侧插入元素"0"
127.0.0.1:6379> lpush mylist "0" 
(integer) 3
//列出mylist中从编号0到编号1的元素
127.0.0.1:6379> lrange mylist 0 1 
1) "0"
2) "1"
//列出mylist中从编号0到倒数第一个元素
127.0.0.1:6379> lrange mylist 0 -1 
1) "0"
2) "1"
3) "2"

4、set无序集合

Redis的集合,是一种无序的集合,集合中的元素没有先后顺序。集合相关的操作也很丰富,如添加新元素、删除已有元素、取交集、取并集、取差集等。

//向集合myset中加入一个新元素"one"
127.0.0.1:6379> sadd myset "one" 
(integer) 1
127.0.0.1:6379> sadd myset "two"
(integer) 1
//列出集合myset中的所有元素
127.0.0.1:6379> smembers myset 
1) "one"
2) "two"
//判断元素1是否在集合myset中,返回1表示存在
127.0.0.1:6379> sismember myset "one" 
(integer) 1
//判断元素3是否在集合myset中,返回0表示不存在
127.0.0.1:6379> sismember myset "three" 
(integer) 0
//新建一个新的集合yourset
127.0.0.1:6379> sadd yourset "1" 
(integer) 1
127.0.0.1:6379> sadd yourset "2"
(integer) 1
127.0.0.1:6379> smembers yourset
1) "1"
2) "2"
//对两个集合求并集
127.0.0.1:6379> sunion myset yourset 
1) "1"
2) "one"
3) "2"
4) "two"

使用场景:标签,社交,查询有共同兴趣爱好的人,智能推荐

5、zset有序集合

同无序集合一样,存储string类型且不能重复每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

redis 127.0.0.1:6379> ZADD key 1 redis
(integer) 1
redis 127.0.0.1:6379> ZADD key 2 mongodb
(integer) 1
redis 127.0.0.1:6379> ZADD key 3 mysql
(integer) 1
redis 127.0.0.1:6379> ZADD key 3 mysql
(integer) 0
redis 127.0.0.1:6379> ZADD key 4 mysql
(integer) 0
redis 127.0.0.1:6379> ZRANGE key 0 10 WITHSCORES
1) "redis"
2) "1"
3) "mongodb"
4) "2"
5) "mysql"
6) "4"

常用于排行榜,如视频网站需要对用户上传视频做排行榜,或点赞数

总结数据类型使用场景

string类型

  1. 缓存结构体信息(多用于缓存json)
  2. 各类验证码(带过期时间)
  3. 计数功能
  4. 缓存session、token等

hash类型

  1. 特别适合保存对象结构信息

list(底层链表)

  1. 各种列表
  2. 消息队列(顺序消费)

set java中的HashSet,内部的健值是无序唯一的

  1. 提供快速去重的列表
  2. 提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。
  3. 标签,社交,查询有共同兴趣爱好的人,智能推荐 做集合的交并补操作

sorted Set 排序集合

需要对数据根据某个权重进行排序的场景。比如在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息。