Hash类型
Hash类型,也叫散列,其Value是一个无序字典,其类似于Java中的HashMap结构。但我们都知道Redis本身就是基于Key-Value存储的,但是Hash表也是一个Key-Value结构,那么也就是说**Hash类型的Value又是一个Key-Value类型的结构**。上一篇文章提到过String类型是将对象序列化为Json字符串之后存储,如图所示:
这样可以将一个对象以String类型的Value存储到Redis中,但是当需要修改对象的某一个字段时相当不方便——必须对整个对象进行操作。而反观Hash结构存储对象,因为其Value又是一个Key-Value结构,所以说对于对象的存储更加得心应手:
Hash结构可以将对象中的每个字段独立存储,可以针对单个字段进行CRUD。
上图是Hash类型的常见命令,可见和String类型的操作其实是差不多的,只是Hash结构中的Value也是Key-Value形式存储的,所以说在操作的时候需要注意filed(字段)(为了区别本身存储时的Key-Value,所以说将Hash类型的Value中的Key叫做filed)。
List类型
Redis中的List类型和Java中的LinkedList类似,可以看做是一个双向链表结构(但底层实现远比双向链表更加复杂,此处不讨论)。既可以支持正向检索也可以支持反向检索(双向链表的特性)。既然其底层可以看做双向链表结构,其特性也和双向链表结构类似:插入元素有序、插入元素可重复、插入和删除速度快、查询速度一般。
上图是List类型的常见命令,在使用List类型进行操作时,必须注意是从哪一边进行插入元素或移除元素的,因为其底层可以看作双向链表,所以说元素之间是有方向的。
此时一个List中已经有了两个元素A和B,此时对List进行Lpush一个元素C,需要特别注意:因为元素是Lpush到List中的,所以说插入之后List应该是:
Lpush是从List的左侧进行插入的,所以说元素C此时就会在最左边,此时再对List进行Lpush一个元素D,List会变成这样:
Rpush和Lpush的使用方法完全一致,此时再对List进行Rpush一个元素E,List会变成这样:
总结Lpush和Rpush可以概括为:从左侧(Lpush)插入的元素就会在List的左边;从右侧(Rpush)插入的元素就会在List的右边。Lpop和Rpop的使用方法和Push完全一致,对当前List进行一次Lpop之后会取得元素D,进行一次Rpop后会取得元素E,此时List将会变成:
这里特别说一下BLPOP和BRPOP这两个命令,其和LPOP和RPOP命令类似,但是在List中没有元素的时候会等待指定时间,而不是直接返回nil。其可以用于实现阻塞队列。
如何通过List结构模拟一个栈?
通过数据结构的基础知识,我们可以知道栈(stack)的结构是先进后出(LIFO),那么我们只需要保证入口和出口是同一个即可,所以说可以配合使用L(R)PUSH和L(R)POP模拟一个栈。
如何通过List结构模拟一个队列?
通过数据结构的基础知识,我们可以知道队列(queue)的结构是先进先出(FIFO),那么我们只需要保证入口和出口不是同一个即可,所以说可以配合使用L(R)PUSH和R(L)POP模拟一个队列。
如何通过List结构模拟一个阻塞队列?
阻塞队列是从队列的结构上进化而来的,它必须满足队列的特性,只是在出队时需要等待,所以说我们可以使用所以说可以配合使用L(R)PUSH来入队,但是在出队时使用BR(L)POP模拟一个阻塞队列。