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类型
- 缓存结构体信息(多用于缓存json)
- 各类验证码(带过期时间)
- 计数功能
- 缓存session、token等
hash类型
- 特别适合保存对象结构信息
list(底层链表)
- 各种列表
- 消息队列(顺序消费)
set java中的HashSet,内部的健值是无序唯一的
- 提供快速去重的列表
- 提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。
- 标签,社交,查询有共同兴趣爱好的人,智能推荐 做集合的交并补操作
sorted Set 排序集合
需要对数据根据某个权重进行排序的场景。比如在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息。