Redis 是一个键值对内存数据库(key-valueDB),数据库的值可以是字符串、集合、列表等多种类型的对象,而数据库的键则总是字符串对象。
最底层用Sds存储(Simple Dynamic String,简单动态字符串),替换char来作为对字符串的支持,既可以高效地实现追加和长度计算,并且它还是二进制安全的。
Sds对象结构维护3个属性len、free、buf,buf是char[]保存真实内容,len是buf的长度,free是剩余长度。Set时free为0,append时free扩展一倍,优点减少再次append对内存重新进行分配,缺点造成内存的浪费,但是append频率不高,所以缺点可以接受。
内部数据结构:
1整数(Int):
没什么特别的,略。
2字符串(String):
同Sds,略。
3双端列表(LinkedList):
由List和ListNode构成
可以从两个方向对双端链表进行迭代:
•沿着节点的 next 指针前进,从表头向表尾迭代;
•沿着节点的 prev 指针前进,从表尾向表头迭代;
4压缩列表(ZipList):
是由一系列特殊编码的内存块构成的列表,它可以保存字符数组或整数值,它还是哈希键、列表键和有序集合键的底层实现之一,本质是为了节省内存。
5字典(Dictionary):
就是Java里的Map<Key, Value>,Redis使用的是Hash表
先用ht[0],rehash的时候往ht[1]上创建
6跳跃表(SkipList):
这种数据结构以有序的方式在层次化的链表中保存元素,前面介绍Lucene时提到过,也有使用跳跃表,因为跳跃表必须是有序的,所以在 Redis 的唯一作用,就是实现有序集数据类型。
7整数集合(IntSet):
整数集合(intset)用于有序、无重复地保存多个整数值,它会根据元素的值,自动选择该用什么长度的整数类型来保存元素。如果在一个 intset 里面,最长的元素可以用 int16_t 类型来保存,那么这个 intset 的所有元素都以 int16_t 类型来保存。
Intset 是集合键的底层实现之一,如果一个集合:1. 只保存着整数元素; 2. 元素的数量不多;那么 Redis 就会使用 intset 来保存集合元素。
对外数据类型:
redisObject数据结构,type 、encoding 和 ptr 是最重要的三个属性。
type 记录了对象所保存的值的类型
#define REDIS_STRING 0 // 字符串
#define REDIS_LIST 1 // 列表
#define REDIS_SET 2 // 集合
#define REDIS_ZSET 3 // 有序集
#define REDIS_HASH 4 // 哈希表
encoding 记录了对象所保存的值的编码
#define REDIS_ENCODING_RAW 0 // 编码为字符串
#define REDIS_ENCODING_INT 1 // 编码为整数
#define REDIS_ENCODING_HT 2 // 编码为哈希表
#define REDIS_ENCODING_ZIPMAP 3 // 编码为 zipmap
#define REDIS_ENCODING_LINKEDLIST 4 // 编码为双端链表
#define REDIS_ENCODING_ZIPLIST 5 // 编码为压缩列表
#define REDIS_ENCODING_INTSET 6 // 编码为整数集合
#define REDIS_ENCODING_SKIPLIST 7 // 编码为跳跃表
ptr 是一个指针,指向实际保存值的数据结构。
内外结果对应关系:
五种对外数据类型的操作案例:
1, String,没啥特别。Get,set,delete 类型只有2个long和sds
2, List,需要注意是双链,就是操作比较特别。LPUSH、RPUSH、LPOP、RPOP、LINDEX、LRANGE、(阻塞BLPOP)
3, Set,与List的差别就是Java中List与Set的差别,很好理解。简单的操作SADD、SREM、SISMEMBER(是否存在)、SMEMBERS。Set对求交接、并集比较方便。
SUNION key1 key2 ... keyN:将所有key合并后取出来,相同的值只取一次
SDIFF key1 key2 ... keyN:获取第一set中不存在后面几个set里的元素。
SINTER key1 key2 ... keyN:取出这些set的交集
4,HASH,注意不要把Redis的key与map中的key搞混淆,命令特别。HSET、HGET、HGETALL、HDEL
5,ZSet,很特殊,key被称为member独一无二的,值被称为score,必须是浮点数。对Zset的访问可以通过member也可以通过score。命令有:ZADD、ZRANGE、ZRANGEBYSCORE、ZREM。