Redis基础数据结构
Redis中有5中基础数据结构,分别为:string(字符串)、list(列表)、set(列表)、hash(哈希)和zset(有序集合)
string
Redis所有的数据结构都是以唯一的key字符串作为名称,然后通过这个唯一的key来获取对应的value。不同的数据类型的差别就在于value的结构不一样。字符串的应用非常广泛,常见的用途就是用来缓存用户信息。将用户信息转化为JSON序列成字符串,然后将序列化的字符串塞进Redis来缓存。
Redis的字符串是动态字符串,是可以修改的字符串,内部结构实现了类似Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。扩容的机制为,当字符串的的长度小于1M时,扩容都是加倍现有的空间,如果操作1M,扩容一次就会多增加1M的空间。字符串的最大长度为512M
键值对
set key value
,设置键对应的value
get key
,获取键对应的value
del key
删除key
批量键值对
mset key1 value1 key2 value2 key3 value3
,设置多个键值对
mget key1 key2 key3
,获取多个键值对
过期和set命令拓展
可以对key设置过期时间,到点自动删除,这个功能通常用来控制缓存失效的时间
expire name 5
设置key为name的键值对5s后过期
setnx name jack
如果name不存在就执行set创建
计数
如果value是一个整数,还可以对他进行自增操作,自增也是有范围的,他的范围是signed long的最大值和最小值,超过这个值,Redis会报错
set age 30
incr age # age的值 +1
incrby age 5 # age的值+5
字符串是由多个字节组成,每个字节又是由8个bit位组成,如此便可以将一个字符串看成很多bit的组合,这就是位图数据结构
list
Redis中的列表相当于Java语言中的LinkedList,采用链表实现,所以list的插入和删除操作非常快,时间复杂度是O(1),但是索引的定位是很慢的,复杂度(O(n)),list可以支持头部和尾部的操作,通常可以被当做队列和栈来使用
rpush
从右边插入元素
lpop
从左边弹出元素
rpop
从右边弹出元素
lpush
从左边插入元素
push操作支持一次性插入多个元素
慢操作
lindex相当于Java链表的get(int index)
方法,需要对链表进行遍历,新能随着index
的增大而变差
ltrim start_index end_index
定义了一个区间,在这个区间内的值,ltrim会保留,区间之外的值统统砍掉,可以通过ltrim来实现一个定长链表,index可以为负数,表示从后向前取
rpush book python java golang
lindex book 1 # O(1)
"java"
lrange books 0 -1 # 获取所有的元素,O(n)
快速链表
Redis底层存储的链表不是一个简单的linkedlist
,而是一个快速链表。在元素比较少的时候会使用一块连续的内存存储,这个结构是ziplist
,压缩列表。是将所有元素紧挨在一起存储,分配的是一块连续的内存。当数据量比较多的时候会改变成quicklist
。因为普通链表需要附加的指针空间太多了,会浪费空间,而且会加重内存碎片。Redis将链表和ziplist
结合起来生成quicklist
。也就是将多个ziplist
使用双向指针穿起来使用。