Redis的数据类型
string
基本操作
1 | set key value |
1 | get key |
过期时间
1 | # 单位是秒 |
查询长度
1 | strlen key |
字符串操作
如果value是数字,还可以执行基本的数学运算
1 | set a 1 |
获取子串
1 | # a[2:5] |
这是一个前闭后闭的操作,比如 a = 1234567
上述操作会获得 3456
覆盖子串
1 | setrange a 2 abcdef |
相当于a[0:2] + newval,这里的a[0:2]是前开后闭
追加子串
1 | append a abcdef |
基本实现
就是往db(哈希表)里插数据
list
redis使用双向链表存储list的元素,所以不是数组,因为是链表,查找能力弱,如果数据量很大,时间复杂度就会升高
支持负下标,和python一样
list不能用set/get操作
list增删操作
1 | # 从尾部增加 |
这四种操作,不同组合,可以构成队列,栈等数据结构
获取list长度
1 | llen key |
随机读
1 | # 读a[1] |
修改元素
1 | # a[1] = newval |
linsert为什么不用index?
分布式环境中,列表的元素会频繁的变动,index也会随之变动,但是val不会
删除特定元素
1 | # 1表示最大删除一个元素 |
也是靠值删除
定长列表
比如top10等等
1 | > rpush ireader go java python javascript ruby erlang rust cpp |
list的基本实现
redis采用了quicklist的数据结构,这是一个双向链表,而和不同的双向链表不同的是,链表节点上存储的并不是数据,而是ziplist,ziplist是为了解决链表造成的存储碎片化,一个quicklistNode上,存储一个ziplist,最大可以存16个item,这些ziplist的item在内存存储上,是紧挨着的。
简单类比,ziplist相当于一个内存池,并且具有压缩编码功能。
典型的是,如果value是整数,ziplist会把字符转成整型,并且根据整数的大小,选择不同的整型存储(省内存)
hash
等价与python中的dict
增加元素
1 | hset key field1 val1 field2 val2 |
获取元素
1 | hget key field1 |
删除元素
1 | hdel key field |
判断元素是否存在
1 | hexists key field |
计数器
1 | hincrby key field num |
这个value需要是整数
hash的基本实现
hash,首先会用ziplist存,会存两个信息,第一个是field,紧挨着下一块内存会存value
当ziplist的大小超过一个阈值后,默认512,就会把ziplist转成dict,读取更高效
1 |
|
dict的实现
redis采用了哈希表的方式,即一个大表,hash值%size的方式维护索引,为了避免碰撞,采用链表定址法,hash值相同的挂链表索引。
装载过小就会扩容,过大会缩容。扩容不是一次性copy old to new。而是摊还copy(扩容后先查新,没有就查旧,然后copy旧到新)
set
介于list和hash之间,set不允许有重复的value出现
增加元素
1 | sadd key val1 val2 val3 |
删除元素
1 | srem key val1 val2 |
判断元素是否存在
1 | sismember key val |
set的基本实现
dict的key
如果val都是int,则用了intset的实现方式,string转int,用数组存整数(类似ziplist),并且通过二分,保证插入是有序的,查找是二分查找
zset(sortset)
set的基础上,每个val都有一个权重score,内部按照score排序
可以理解成sort set
增删元素
1 | zadd a 2.0 val1 3.0 val2 |
score排序
1 | # 获取val的score |
zset的基本实现
链表存数据,跳表实现排序
扫描二维码,分享此文章