在redis中,类型的参数传递都是通过一个成为redisObject的数据结构来封装的。
数据结构如下:
typedef struct redisObject {
// 类型
unsigned type:4;
// 对齐位
unsigned notused:2;
// 编码方式
unsigned encoding:4;
// LRU 时间(相对于 server.lruclock)
unsigned lru:22;
// 引用计数
int refcount;
// 指向对象的值
void *ptr;
} robj;
/*
* 对象类型
*/
#define REDIS_STRING 0 // 字符串
#define REDIS_LIST 1 // 列表
#define REDIS_SET 2 // 集合
#define REDIS_ZSET 3 // 有序集
#define REDIS_HASH 4 // 哈希表
/*
* 对象编码
*/
#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 // 编码为跳跃表
在结构中的type和coding决定了底层的数据结构,进而决定了底层的操作函数, 编码和类型之间的关系如下:
Reids的hash表类型
在redis中,hash的底层实现时ziplist和dict两种,在创建时默认使用ziplist,并在以后的操作中适时的进行转换位dict。Hash结构是redis中使用最频繁的结构,无论是db还是key/value的存储,基本都是使用hash表。
当使用ziplist实现hash的时候,entry是成对出现的,也就是说第一个entry表示是key,那么一定在他之后还有一个entry表时value。如下:
+------------+-------+------+--------+------+------+----+--------+-------+-----------+
| ZIPLIST | | | | | | | | | ZIPLIST |
| ENTRY | key1 | val1 | key2 | val2 | ... | ... | keyN | valN | ENTRY |
| HEAD | | | | | | | | | END |
+------------+--------+------+-------+------+------+-----+--------+------+------------+