string(字符串 )
字符串的最大长度为512MB
为了避免频繁的分配内存,扩容方式是:
当字符串小于1MB时,扩容是加倍现有空间,当超过1M,扩容是每次多1M。
使用方式
set key value #设置值
get key #获取值
exists key #判断是否存在 存在为1
del key #删除
mset key1 v1 key2 v2 key3 v3 # 批量保存
mget key1 key2 key3 #批量获取
expire key 5 #设置过期时间,单位s
setex key v 5 #设置值同时设置过期时间
setnx key v #如果值不存在,执行set
set age 10 #设置一个证书
incr age #证书可以进行自增操作,默认每次➕1
incrby age 5 #通过by执行加的值,10+5=15,最大范围为singed long
list 列表
使用双向链表实现,插入删除快,索引定位慢
左进右出:队列
rpush key v1 v2 v3 #从右侧放入3个值
llen key #3
lpop key #v1左侧读出第一个值
lpop key #v2左侧读出第2个值
右进右出:栈
rpush key v1 v2 v3 #从右侧放入3个值
llen key #3
rpop key #v3右侧侧读出第一个值
rpop key #v2右侧读出第2个值
由于是链表,所以索引定位慢,时间复杂度O(n)
lindex key 1 #v2lindex 从左侧索引第几个位置,从0开始
lrange key 0 -1 #获取从左第0个到最后一个位置的值,闭区间
Itrim key 1 -1 #保留 从做边第1到最后一个位置的结果,key变为v2,v3,可以用1 0清零列表
实现
快速列表
在列表元素较少的情况下,使用一块连续的内存,ziplist,压缩列表,当数据量大时改为quicklist 快速列表。因为普通链表的附加空间大,浪费空间,加重碎片化。redis使用ziplist和链表结合组成quicklist。即将多个ziplist使用双向链表串起来。快速插入删除,又不会有太多冗余空间。
hash(字典)
数组+链表实现,用数组实现hash,用链地址法来解决冲突,采用渐进式的rehash策略,避免耗时过长,阻塞服务。
hash和string的对比,string只能一次全部读取消耗网路流量,hash需要存储额外信息。
hset key field1 value1 #存储数据
hgetall key #获取全部数据
hlen key #长度
hget key field #获取某个key
hmset key field1 "value1" field2 "value2" #一次存储多个数据
hmget
set (集合)
集合内部的键值对,是无序的,唯一的。
当集合中的最后一个元素被删除后,数据结构自动删除后,内存回收
sadd key value1 #添加一个元素
sadd key value2 value3 #添加多个元素
smembers key #列出所有的值,无序的
sismembers key value #返回1表示存在这个value
scard key #长度
spop key #弹出一个值
zset(有序列表)
一方面是一个set保证唯一性
另一方面可以给每个value一个score,代表权重
使用跳跃列表实现
zset最后一个value被移除后,数据结构自动删除后,内存被回收
zadd key score value #socre是小数,
zrange key 0 -1 #按照score升序返回0到最后的value
zrevrange key 0 -1 #按照score降序返回所有元素的顺序
zcard key #长度
zscore key value #查看score,double类型,存在精度问题
zrank key value #某个value的排名,从0开始
zrangebyscore key score1 score2 withscores #返回(score1,score2]之间的value
zrem key value #删除
跳跃列表
因为要支持随机插入删除,所以用链表实现
因为要按照score排序,所以要定位插入点,通过二分查找来快速定位
跳跃列表每个元素可以属于不同的层级,如图1中间元素属于三个层级,可以快速的在不同的层级进行跳跃。
跳跃链表一般采取随机的策略来决定新元素的可以属于到第几层。
L0层的概率是100%,L1层是50%,L2层是25%以此类推。