redis对外公开的有5种数据结构,分别是String,List,Hash,Set,ZSet。这几种底层分别用了不同的数据结构来实现。
redis介绍:
redis是一个开源的使用C语言编写的一个kv存储系统,是一个速度非常快的非关系内存数据库。它支持包括String、List、Set、Zset、hash五种数据结构。
与关系型数据库相比,redis的命令请求不需要经过查询分析器或查询优化器进行处理,也避免了更新数据时引起的随机读\写,这些慢操作。它直接读写内存中的数据,并且数据是按照一定的数据结构存储的。所以它的速度非常快。
Redis采用redisObjec结构来统一五种不同的数据类型,这样所有的数据类型就都可以以相同的形式在函数间传递而不用使用特定的类型结构。
typedef struct redisObject {
unsigned type:4; //保存信息的类型(String,List,Set,Zset,Hash)
unsigned encoding:4;//保存信息的编码方式(底层数据结构)
unsigned lru:LRU_BITS; /* lru time (relative to server.lruclock) */
int refcount;//引用次数
void *ptr;//保存的指针
} robj;
/* Object types */
#define OBJ_STRING 0
#define OBJ_LIST 1
#define OBJ_SET 2
#define OBJ_ZSET 3
#define OBJ_HASH 4
/* Objects encoding. Some kind of objects like Strings and Hashes can be
* internally represented in multiple ways. The 'encoding' field of the object
* is set to one of this fields for this object. */
#define OBJ_ENCODING_RAW 0 /* Raw representation */
#define OBJ_ENCODING_INT 1 /* Encoded as integer */
#define OBJ_ENCODING_HT 2 /* Encoded as hash table */
#define OBJ_ENCODING_ZIPMAP 3 /* Encoded as zipmap */
#define OBJ_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */
#define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define OBJ_ENCODING_INTSET 6 /* Encoded as intset */
#define OBJ_ENCODING_SKIPLIST 7 /* Encoded as skiplist */
#define OBJ_ENCODING_EMBSTR 8 /* Embedded sds string encoding */
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */
String:
由于redis是C语言写的,C语言并没有实现好的字符串类型,是用指针或则char数组实现的,C语言字符串结尾是以'\0'来标识。redis自定义了一种自定义结构,SDS(动态字符串)。
struct sdshdr{
//记录buf数组中已使用字节的数量
//等于 SDS 保存字符串的长度
int len;
//记录 buf 数组中未使用字节的数量
int free;
//字节数组,用于保存字符串
char buf[];
}
SDS的性质:
1.C 语言的字符串不会记录自己的长度,而是需要进行遍历获得,时间复杂度为 O(n) ,而 SDS 已经封装了 len 属性,直接读取 len 的值就可以获得长度,不需要遍历,时间复杂度 O(1) 。
2.二进制安全的(C语言是以\0来表示字符串结束的),如果二进制中有 \0 会结束字符串。所以redis是可以存储图片和视频的。
3. 如果修改后的 SDS 长度 len 小于 1MB,那么程序分配和 len 属性相等的未使用空间,此时 free 和 len 的值相同。所以此时数组的实际长度为 free + len + 1byte(额外的空字符 1 个字节)。
4. 如果修改后的 SDS 长度大于 1MB,那么程序分配 1MB 的未使用空间。实