一、String
String类是二进制安全的,意味着String类可以包含任何数据,比如图片或者序列化的对象。一个value最多是512M。
常用命令
- set get set会覆盖旧值
- append
- setnx:key不存在的时候才会设置key
- incr和decr 给数字加一和减一
- incrby/decrby设置加减步长
- mset/mget设置多个key/value
- msetnx原子性存入,存在就不会存入
- getrange 截取字符串,相当于substring
- setrange相当于repace
- setex设置过期时间
- getset新值换旧值
底层结构
String的数据结构相当于简单动态字符串(SDS),内部结构类似于Java的ArrayList,预分配冗余空间方式来减少内存的频繁分配。
当前字符串实际分配的空间capacity是要大于当前字符串长度len的,当字符串长度小于1M时,扩容会加倍现有的空间,大于1M的时候,每次扩容只会增加1M的空间,最多只会扩容到512M.
二、List
单键多值,按照插入顺序排序,可以添加一个元素到链表的头部或者尾部,底层是双向链表,俩端操作性能高,通过索引下标操作中间的节点性能会比较差。
常用命令
- Lpush/rpush,从左边/右边插入一个或者多个值
- lpop/rpop从左边/右边取出一个值,值在键在,值光键亡
- rpoplpush从k1右边取出一个值插入k2左边
- lindex 获得索引下标元素
- llen获取列表长度
- linsert key before value newvalue在value前/后插入新的value
- lrem key n value从左到右删n个value
- lset key index value将列表下标index的值换成value
底层结构
List的底层结构为快速链表quickList,在元素较少的时候会使用连续的内存空间,这个结构是zipList,也就是压缩链表。数据量多的时候会将多个ziplist使用双向指针连起来形成快速链表quickList,能满足插入和删除的性能需求。
三、Set
Set类似List,可以自动排重,Redis中的Set是String的无序集合,底层是一个value为null的Hash表,添加、删除、查找的时间复杂度都是O(1)
命令
- sadd 添加一个或者多个元素,smembers 取出元素
- sismember查看是否有指定value
- scard查看元素个数
- srem删除一个或多个member
- spop随机吐出一个值
- srandmember随机从集合中取出n个值,不会删除
- smove 把集合中一个值从一个集合移动到另外一个集合
- sinter 返回俩个集合的交集元素
- sunion返回俩个集合的并集元素
- sdiff返回俩个集合中的差集元素 k1中的,不包含k2的
底层结构
使用Hash表实现,所有的value指向同一个內部值
四、Hash
hash是一个键值对集合,Redis中的Hash是一个String类型的filed和value的映射表,hash表适合用于存储对象。类似于Java中的Map<String,Object>
命令
- hset赋值
- hget取值
- hmset批量设置值
- hexists查看指定字段值是否存在
- hkeys查看key的所有字段
- hvals查看所有value
- hincrby设置增量
- hsetnx不存在添加,存在不添加
底层结构
Hash类型对应的数据结构有俩种:ziplist和hashtable,数据少和字段少使用ziplist,数据量大使用hashtable。
五、zset
常用命令
- zadd 添加score和值
- zrange取出值,根据score大小排序
- zrangebyscore 返回score介于min和max中的值
- zrevrangebyscore,同上,改为从大到小排列
- zincrby增加增量
- zrem删除指定值
- zcount统计指定区间的元素个数
- zrank返回集合中的排名,从0开始
底层结构
zset底层使用俩种数据结构,分别是ziplist和skiplist,score,value键值对小于128个并且每个元素长度小于64字节的时候使用ziplist,否则使用跳表。
跳表组合了hash
和skiplist
,hash
用来存储value到score的映射,可以在O(1)的时间复杂度下找到value对应的分数。skiplist
按照从从小到大的顺序来存储分数score,skiplist中每个元素都是一个键值对(score,value)。跳表可以保证增删查改的时间复杂度为O(logn),是一种以空间换取时间的思想。
每个跳表节点都维护着一个score值,按照score值从小到大排序,实际上就是为链表添加了索引,查找的效率会更高。
查找51,顺序为1->21->41->51,4次查找,如果是链表,需要6次查找。