3.Redis的数据结构

Redis的数据结构

Redis支持StringHashListSetSorted Set五种数据类型。

Redis内部使用一个redisObject对象来表示所有的keyvalue

 

字符串类型 String

简介:可以存储任何形式的字符串,一个字符串类型键允许存储的数据的最大容量是512MB

常用命令:set/get/decr/incr/mget等;

应用场景:String是最常用的一种数据类型,普通的key/value存储都可以归为此类;

实现方式:Stringredis内部存储默认就是一个字符串,被redisObject所引用,当遇到incrdecr等操作时会转成数值型进行计算,此时redisObjectencoding字段为int

命令示例:SET key value / GET key

散列类型 Hash

简介:散列类型适合存储对象,使用对象类别和ID构成键名,使用字段表示对象的属性,而字段值则存储属性值。

常用命令:hget/hset/hgetall

应用场景:我们要存储一个用户信息对象数据,其中包括用户ID、用户姓名、年龄和生日,通过用户ID我们希望获取该用户的姓名或者年龄或者生日;

实现方式:RedisHash实际是内部存储的Value为一个 HashMap,并提供了直接存取这个Map成员的接口。这个Mapkey是成员的属性名,value是属性值。这样对数据的修改和存取都可以直接通过其内部Map Key(Redis里称内部Mapkeyfield),也就是通过 key+ field(属性标签)就可以操作对应属性数据。当前HashMap的实现有两种方式:当HashMap的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,这时对应的valueredisObjectencodingzipmap,当成员数量增大时会自动转成真正的HashMap,此时encodinght

命令:HSET key field value / HGET key field  ( HMSET key field value [fielld value ...]  / HMGET key field [field ...])


列表类型 List

简介:列表类型可以存储一个有序的字符串列表,常用的操作是向列表的两端添加元素,或者获得列表的某一个片段。列表类型内部是使用双向链表实现的,向两端添加删除元素较快,但通过索引访问元素较慢。

常用命令:lpush/rpush/lpop/rpop/lrange等;

应用场景:Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redislist结构来实现;

实现方式:Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。

命令:LPUSH key value [value ...] / RPUSH key value [value ...] / LPOP key / RPOP key / LRANGE key start stop


集合类型 Set

简介:集合中每个元素都是不同的,且没有顺序。常用操作是向集合中加入或删除元素、判断某个元素是否存在等,集合类型在Redis内部是使用值为空的散列表实现的,所以这些操作较快。集合类型键之间还可以进行并集、交集和差集运算。

常用命令:sadd/spop/smembers/sunion等;

应用场景:Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的;

实现方式:set的内部实现是一个 value永远为nullHashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。

命令:SADD key member [member ...] / SREM key member [member ...] / SDIFF key [key ...] / SINTER key [key ...] / SUNION key [key ...]


有序集合类型 Scored Set

简介:在集合类型的基础上有序集合类型为集合中的每一个元素都关联了一个分数,按照这个分数对每个元素进行排序。我们进行获得分数最高(或最低)的前N个元素、获得指定分数范围内的元素等于分数有关的操作。虽然集合中每个元素都是不同的,但是他们的分数却可以相同。有序集合可以调整某个元素的位置,通过更改该元素的分数。

常用命令:zadd/zrange/zrem/zcard等;

应用场景:Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,比如twitterpublic timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。

实现方式:Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

命令:ZADD key score member [score member ...] / ZSCORE key member / ZRANGE key start stop [WITHSCORES] / ZREVRANGE key start stop [WITHSCORES]