1. string(字符串)

string是redis中最简单的一种数据结构,通常用于存储序列化之后的对象。底层是由字符数组构造的,与java的String类型不同,它是可变字符串,类似于java的StringBuffer。

字符串的长度在1MB以下扩容时,每次都会扩容到原来的2倍;若超过1MB,每次扩容时都只会增加1MB的空间,而且每个字符串占用的最大空间为521MB.

1.1 基本操作

1.1.1 单个操作

127.0.0.1:6379> set testkey testval
OK
127.0.0.1:6379> get testkey
"testval"
127.0.0.1:6379> del testkey
(integer) 1
127.0.0.1:6379> get testkey
(nil)

1.1.2 批量操作

127.0.0.1:6379> mset testkey1 testval1 testkey2 testval2
OK
127.0.0.1:6379> mget testkey1 testkey2
1) "testval1"
2) "testval2"
127.0.0.1:6379> del testkey1 testkey2
(integer) 2
127.0.0.1:6379> mget testkey1 testkey2
1) (nil)
2) (nil)

2.Set(集合)

Redis的Set与Java中的HashSet类似,内部的其实也是key-value键值对的形式,而且是无序的,只不过所有key对应的val值都是NULL而已。

如果当前Set中的最后一个元素被移除,那么这个Set所占的空间也会被回收掉。

2.1 基本操作

# 给set新增一个元素
127.0.0.1:6379> sadd testset member1
(integer) 1
127.0.0.1:6379> sadd testset member1
(integer) 0
127.0.0.1:6379> sadd testset member2 member3
(integer) 2
# 查看所有的元素
127.0.0.1:6379> smembers testset
1) "member1"
2) "member2"
3) "member3"
# 判断元素是否存在
127.0.0.1:6379> sismember testset member1
(integer) 1
127.0.0.1:6379> sismember testset member4
(integer) 0
# 弹出一个元素
127.0.0.1:6379> spop testset
"member2"
# 获取set容量大小
127.0.0.1:6379> scard testset
(integer) 2

3.zset(有序集合)

Redis中的有序集合类似于Java中SortedSet,可以使用一个score来表示权重,然后根据score值进行内部的排序操作,它的底层是由“跳跃链表”实现的。

Redis中的有序集合经常用来保存一个人的粉丝,然后根据关注时间进行排序操作。

3.1 基本操作

# 向zset中添加元素
127.0.0.1:6379> zadd testzset 80 book1 90 book2
(integer) 2
# 正排(score从小到大)
127.0.0.1:6379> zrange testzset 0 -1
1) "book1"
2) "book2"
# 倒排(score从大到小)
127.0.0.1:6379> zrevrange testzset 0 -1
1) "book2"
2) "book1"
# 获取zset的容量
127.0.0.1:6379> zcard testzset 
(integer) 2
# 删除zset中的一个key
127.0.0.1:6379> zrem testzset book1
(integer) 1
127.0.0.1:6379> zcard testzset 
(integer) 1
# 获取key的score
127.0.0.1:6379> zscore testzset book2
"90"

4.list(列表)

Redis中的list相当于java中的LinkedList,所以它底层是类似与双向链表的结构,插入和删除的时间复杂度是O(1),但是随机查找的时间复杂度是O(n)。
列表经常被当做异步队列的结构来使用,将要被延迟处理的任务存放在list中,然后程序中有一个线程异步处理list中任务。

4.1 队列操作(不同方向进出)

127.0.0.1:6379> lpush list1 v1 v2 v3
(integer) 3
127.0.0.1:6379> rpop list1
"v1"
127.0.0.1:6379> rpop list1
"v2"
127.0.0.1:6379> rpop list1
"v3"

4.2 栈操作(相同方向进出)

127.0.0.1:6379> lpush list1 v1 v2 v3
(integer) 3
127.0.0.1:6379> lpop list1
"v3"
127.0.0.1:6379> lpop list1
"v2"
127.0.0.1:6379> lpop list1
"v1"

4.3 区间操作

# 类似于Java的substring截断操作
127.0.0.1:6379> ltrim list1 1 2
OK
# 获取区间内的所有元素
127.0.0.1:6379> lrange list1 0 2
1) "v2"
2) "v1"
# 获取list的长度
127.0.0.1:6379> llen list1
(integer) 2

5 hash(字典)

Redis的字典与Java中的HashMap类似,底层是使用“数组+链表”的二维结构(但是不会像Java在长度超过8时进行红黑树的转化),当发生hash冲突时,使用链表将同一个“桶”中的元素连接到一起。

Redis的字典在扩容也就是ReHash的过程与HashMap是有区别的,Java是一次性完成Rehash的动作,所以这是Java中一个相当耗时的操作;Redis的字典是采用渐进式ReHash操作,会同时存在两个Hash容器,逐渐将旧容器的内容存放到新容器中,当有元素需要查找时,同时查找新旧两个容器,当完全迁移后,Redis会自动删除旧容器。

5.1 基本操作

127.0.0.1:6379> hset testHash hash1 val1
(integer) 1
127.0.0.1:6379> hmset testHash hash2 val2 hash3 val3
OK
127.0.0.1:6379> hget testHash hash1
"val1"
127.0.0.1:6379> hgetall testHash
1) "hash1"
2) "val1"
3) "hash2"
4) "val2"
5) "hash3"
6) "val3"