Redis系列--数据结构

Redis是一个基于内存的,存放key-value型数据的Nosql数据库,它的key永远都是字符串,而它的value支持多种数据类型,其中最常用的数据类型有五种:string、list、set、hash、zset;这些数据类型都是基于Redis底层数据结构的实现,Redis底层实现的数据结构包括:sds、list、dict、zskiplist、intset、ziplist等等,在数据类型和数据结构之间有着一座桥梁redisObject。在基础数据类型之上,还有着bitmaps、hyperloglog、geo、Bloomfilter、Pub/Sub、Redis Module等高级应用。

接下来,我们就来了解一下Redis的基础数据类型。

字符串:

  • Redis使用ANSI C语言编写,但是它并没有使用C语言中传统的字符串表示,而是重新定义了一种简单动态字符串(simple dynamic string)sds,将sds作为默认字符串表示。

typedef char *sds;
struct sdshdr {
    unsigned int len; //记录buf中已使用的空间
    unsigned int free; //记录buf中空闲的空间
    char buf[]; //字符数组--传统的字符串表示,存放具体的数据
};

 

  • sds比传统char数组的优势:

    • char数组采用N+1字符来记录N长度的字符串,为了获取N,需遍历数组,而sds获取len变量即可。

    • char数组容易内存溢出,sds通过free校验空间是否足够。

    • sds预留一部分空间,减少了修改字符串时内存重新分配的操作次数。

    • sds为二进制安全,即字符串中间可以有空字符'\0',而'\0'是char数据字符串的结束标记。所以sds可以保存音频、视频、图片、压缩数据等数据。

  • 应用场景:

    • 缓存,最常用的一种。

    • session,实现共享的一种方式。

链表:

  • 可以保存多个数据,为双端链表。

typedef struct listNode {    struct listNode *prev; //指向上一个节点    struct listNode *next; //指向下一个节点    void *value; //数据,具有多态性} listNode;
typedef struct list {    listNode *head; //指向表头    listNode *tail; //指向表尾    void *(*dup)(void *ptr); //指向复制函数    void (*free)(void *ptr); //指向释放函数    int (*match)(void *ptr, void *key); //指向匹配函数    unsigned long len; //链表长度} list;

  • 特点:双向、无环、有表头、有表尾、前后链接、数据可以重复、有序、可通过下标取值。

  • 应用场景:

    • 时间轴,比如微博、博客、评论等按照时间从近到远展示。

哈希表:

  • 字典表,可以参考Redis系列--渐进式哈希这篇文章,里边有详细的介绍。

集合:

  • 可以保存多个数据,与链表有所区别。

  • 特点:元素无序、无重复、不能通过下标取值、支持交并查集合运算。

  • 应用场景:

    • 给人或者文章打标签及打关键字

有序集合:

  • 通过zkiplist实现

typedef struct zskiplist {    struct zskiplistNode *header, *tail;    unsigned long length;    int level;} zskiplist;
typedef struct zset {    dict *dict;    zskiplist *zsl;} zset;
  • 特点:元素有序、无重复、不能通过下标取值、支持交并查集合运算。

  • 应用场景:

    • 排行榜

关于Redis数据类型,我们有了一个大致了解,虽然只是基础的数据类型,却占据了80%的实际应用,关于底层的数据结构和更高级的数据应用,有兴趣的同学可以查阅一下资料。

PS:如有任何问题或疑问,请留言告诉我。


喜欢这篇文章的朋友,欢迎关注公众号,第一时间收到更新内容。

发布了6 篇原创文章 · 获赞 2 · 访问量 120

猜你喜欢

转载自blog.csdn.net/weixin_45784328/article/details/105354096