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支持的数据结构_c语言

接下来,我们就来了解一下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[]; //字符数组--传统的字符串表示,存放具体的数据
};

 

redis用于存储半结构化数据吗 redis支持的数据结构_数据结构_02

  • 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用于存储半结构化数据吗 redis支持的数据结构_数据结构_03

  • 特点:双向、无环、有表头、有表尾、前后链接、数据可以重复、有序、可通过下标取值。
  • 应用场景:
  • 时间轴,比如微博、博客、评论等按照时间从近到远展示。

哈希表:

  • 字典表,可以参考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%的实际应用,关于底层的数据结构和更高级的数据应用,有兴趣的同学可以查阅一下资料。