0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Redis底層數(shù)據(jù)類型

科技綠洲 ? 來源:Java技術(shù)指北 ? 作者:Java技術(shù)指北 ? 2023-10-09 14:05 ? 次閱讀

1. 前言

Redis的鍵值對中的常見數(shù)據(jù)類型有String (字符串)、List(列表)、Hash(哈希)、Set(集合)、Zset(有序集合)。那么其對應(yīng)的底層數(shù)據(jù)結(jié)構(gòu)有SDS(simple dynamic string)、鏈表、字典、跳躍表、壓縮列表、快速列表,整數(shù)集合等。

下面我們來了解一下其底層數(shù)據(jù)結(jié)構(gòu)的精妙之處。

2. Redis底層數(shù)據(jù)結(jié)構(gòu)

2.1 SDS

Redis自定義了一種簡單動態(tài)字符串(simple dynamic string),將其作為Redis的默認(rèn)字符串表示。

其主要結(jié)構(gòu)如下:

圖片

  • len表示這個(gè)SDS字符串長度,如果buff字節(jié)數(shù)組中保存了5個(gè)字符那么長度就是5。同時(shí)也方便獲取SDS的長度。
  • alloc表示分配的字符數(shù)組長度。其值一般是大于SDS字符串長度(len),由于 Redis的設(shè)計(jì)場景就是會頻繁的訪問,修改數(shù)據(jù),所以無論是數(shù)據(jù)增大或者是縮小都需要盡量減少重新分配內(nèi)存的操作 。所以SDS會預(yù)留一些空間,在下一次修改數(shù)據(jù)的時(shí)候可以直接使用原先預(yù)分配的內(nèi)存,同時(shí)在每次數(shù)據(jù)操作的時(shí)候也會動態(tài)的增加或者減少預(yù)留內(nèi)存空間,。Redis3.0的版本的SDS結(jié)構(gòu)中使用free, 表示未分配的空間,但也是同一個(gè)設(shè)計(jì)思想。
  • flags 標(biāo)志位,低3位表示類型,其余5位未使用。
  • buf 實(shí)際存儲數(shù)據(jù)的數(shù)組,可以保存字符,也可以保存二進(jìn)制數(shù)據(jù)。

redis6.0中SDS定義如下 (越來越節(jié)約使用內(nèi)存了,內(nèi)存是省出來的!)

typedef char *sds;

/* Note: sdshdr5 is never used, we just access the flags byte directly.
 * However is here to document the layout of type 5 SDS strings. */
struct __attribute__ ((__packed__)) sdshdr5 {
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
    uint32_t len; /* used */
    uint32_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
    uint64_t len; /* used */
    uint64_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

相對于C語言的字符串,SDS具有以下優(yōu)點(diǎn)。

  • 獲取字符串的長度復(fù)雜度更低(常數(shù)復(fù)雜度)(復(fù)雜度可見此文章 看完這篇,還不清楚時(shí)間復(fù)雜度的,請來懟我
  • 更加節(jié)省內(nèi)存(針對不同長度設(shè)置了不同的數(shù)據(jù)類型 sdshdr5、sdshdr8、sdshdr16等。)
  • 杜絕緩沖區(qū)溢出
  • 大大減少了修改字符串長度時(shí)所需要的內(nèi)存分配次數(shù)
  • 二進(jìn)制安全

2.2 鏈表

鏈表是大家比較熟悉的數(shù)據(jù)結(jié)構(gòu)了,鏈表提供了高效的節(jié)點(diǎn)重排能力,順序訪問,通過增刪節(jié)點(diǎn)調(diào)整長度等特點(diǎn)。Redis List對象的底層實(shí)現(xiàn)之一就是鏈表。

每一個(gè)鏈表節(jié)點(diǎn)使用如下的結(jié)構(gòu)來表示。

/* Node, List, and Iterator are the only data structures used currently. */

typedef struct listNode {
    struct listNode *prev;
    struct listNode *next;
    void *value;
} listNode;

而多了listNode可以通過prev 和 next 指針組成一個(gè)雙端隊(duì)列如下圖:

圖片

多個(gè)節(jié)點(diǎn)可以組成一個(gè)鏈表,Redis使用了List結(jié)構(gòu)來持有這些節(jié)點(diǎn),操作更方便。其結(jié)構(gòu)如下:

typedef struct list {
    listNode *head;  //鏈表頭節(jié)點(diǎn)指針
    listNode *tail;  //鏈表尾節(jié)點(diǎn)指針
    void *(*dup)(void *ptr); // 用于復(fù)制鏈表節(jié)點(diǎn)所保存的值
    void (*free)(void *ptr); // 用于釋放鏈表節(jié)點(diǎn)所保存的值
    int (*match)(void *ptr, void *key); //用于對比鏈表節(jié)點(diǎn)所保存的值和另一個(gè)輸入值是否相等
    unsigned long len; // 鏈表所包含的節(jié)點(diǎn)數(shù)量
} list;

簡單結(jié)構(gòu)如下圖:

圖片

Redis鏈表具有如下特性:

  • 由于是雙端鏈表,有prev和next指針,獲取節(jié)點(diǎn)的前置節(jié)點(diǎn)和后置節(jié)點(diǎn)的復(fù)雜度為O(1)
  • 頭節(jié)點(diǎn)的prev和尾節(jié)點(diǎn)的next均指向NULL,為無環(huán)鏈表,可以以NULL為鏈表訪問終點(diǎn)
  • 鏈表本身提供了指針,可以快速獲取鏈表的表頭節(jié)點(diǎn)和表尾節(jié)點(diǎn)
  • 自帶鏈表長度計(jì)數(shù)器,可以快速獲取鏈表長度
  • 鏈表可以保存各種不同類型的值

2.3 字典

字典是一種用于保存鍵值對的抽象數(shù)據(jù)結(jié)構(gòu)。

在字典中,一個(gè)鍵(key)可以和一個(gè)值(value)進(jìn)行關(guān)聯(lián),稱之為鍵值對。字典中每個(gè)鍵都是獨(dú)一無二的,并且程序都是通過key來操作更新value或者刪除數(shù)據(jù)等。

Redis的字典使用哈希表作為底層實(shí)現(xiàn)的, 一個(gè)哈希表可以包含多個(gè)哈希表節(jié)點(diǎn),而每個(gè)哈希表節(jié)點(diǎn)就保存了字典中的一個(gè)鍵值對。

下面再講一下哈希表,哈希表節(jié)點(diǎn),以及字典的實(shí)現(xiàn)。

哈希表及哈希表節(jié)點(diǎn)結(jié)構(gòu),字典結(jié)構(gòu) 如下:

//字典結(jié)構(gòu)
typedef struct dict {
    dictType *type; // 類型特定的函數(shù)
    void *privdata;  //私有數(shù)據(jù)
    dictht ht[2]; //長度為2的哈希表數(shù)組, 一般情況下字典僅使用 ht[0]哈希表, ht[1]在rehash的時(shí)候會使用到。
    long rehashidx; /* 未進(jìn)行rehash的時(shí)候 rehashidx == -1 */
    unsigned long iterators; /* number of iterators currently running */
} dict;

//哈希表結(jié)構(gòu)
typedef struct dictht {
    dictEntry **table; //哈希數(shù)組
    unsigned long size; //哈希表大小
    unsigned long sizemask; //哈希表掩碼,用于計(jì)算索引值, 總是等于size-1
    unsigned long used; //表示已有節(jié)點(diǎn)數(shù)量
} dictht;

//哈希節(jié)點(diǎn)
typedef struct dictEntry {
    void *key; //鍵
    union { //value值,包含了多種類型的值,不同類型的值可以使用不同的數(shù)據(jù)結(jié)構(gòu)存儲,節(jié)省內(nèi)存。
        void *val;  //其值可以是一個(gè)指針
        uint64_t u64; //其值也可以是一個(gè)uint64_t 整數(shù)
        int64_t s64; //其值可以是一個(gè)int64_t 整數(shù)
        double d; //其值可以是一個(gè)double 
    } v;
    struct dictEntry *next; //指向像一個(gè)哈希節(jié)點(diǎn)
} dictEntry;

普通狀態(tài)下的字典結(jié)構(gòu)示意圖:

圖片

添加新建的機(jī)制是大家比較熟悉的思路啦。

  • 使用字典設(shè)置的哈希函數(shù)計(jì)算key的哈希值,
  • 哈希值與sizemask 進(jìn)行 & 運(yùn)算,計(jì)算出索引值。然后加入到數(shù)組中。

如果出現(xiàn)哈希沖突,那么會使用鏈地址法解決沖突,使用next指針指向下一個(gè)哈希節(jié)點(diǎn)。

哈希表保存的鍵值逐漸增多或者減少地過程中,程序會對哈希表進(jìn)行擴(kuò)展或者收縮,這個(gè)過程稱之為rehash。

rehash過程中會使用上面的ht[0] ht[1],具體過程這里就不詳細(xì)說了,會另外專門寫一篇來介紹。

2.4 跳躍表

跳躍表(skiplist )是一種有序數(shù)據(jù)結(jié)構(gòu),它在每個(gè)節(jié)點(diǎn)中維護(hù)多個(gè)指向其他節(jié)點(diǎn)的指針,從而可以快速訪問。其支持平均O(logN) 復(fù)雜度的節(jié)點(diǎn)查找。

Zset使用了跳躍表和字典作為其底層實(shí)現(xiàn)。其好處就是可以進(jìn)行高效的范圍查詢,也可以進(jìn)行高效的單點(diǎn)查詢。

在源碼中其結(jié)構(gòu)如下:

typedef struct zskiplistNode { //跳躍表節(jié)點(diǎn)
    sds ele; //成員對象,各個(gè)節(jié)點(diǎn)中成員對象唯一的。
    double score; //分值
    struct zskiplistNode *backward; //后退指針
    struct zskiplistLevel { //層, 最大32層
        struct zskiplistNode *forward; //前進(jìn)指針
        unsigned long span; //跨度
    } level[];
} zskiplistNode;

typedef struct zskiplist { //跳躍表
    struct zskiplistNode *header, *tail;//指向 跳躍表頭 和表尾節(jié)點(diǎn)
    unsigned long length; // 節(jié)點(diǎn)數(shù)量
    int level; //跳躍表中層數(shù)最大的節(jié)點(diǎn)層數(shù)量
} zskiplist;

typedef struct zset { // zset的數(shù)據(jù)結(jié)構(gòu)使用了 字典dict 和 zskiplist
    dict *dict;
    zskiplist *zsl;
} zset;

關(guān)于跳躍表節(jié)點(diǎn)的各參數(shù)解釋如下:

  • 層 level:跳躍表節(jié)點(diǎn)的level數(shù)組可以包含多個(gè)節(jié)點(diǎn)元素,每個(gè)元素都包含指向其他節(jié)點(diǎn)的指針,程序可以通過這些指針來加快訪問其他節(jié)點(diǎn)的速度,層數(shù)越多訪問效率越高。每創(chuàng)建一個(gè)新的跳躍表節(jié)點(diǎn),程序會隨機(jī)生成一個(gè)1-32之間層數(shù)的值,作為level數(shù)組的大小。表示節(jié)點(diǎn)的高度。
  • 前進(jìn)指針,forward :每層有一個(gè)指向表尾方向的前進(jìn)指針,可以通過表頭向表尾訪問節(jié)點(diǎn)。
  • 跨度 span:記錄兩個(gè)節(jié)點(diǎn)之間的距離。
  • 后退指針 backward:節(jié)點(diǎn)的后退指針,用于從表尾向表頭訪問節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)只有一個(gè)后退指針,所以每次只能后退一個(gè)節(jié)點(diǎn)。
  • 分值 score:分值是一個(gè)浮點(diǎn)數(shù),跳躍表中的節(jié)點(diǎn)按照分值來排序,
  • 成員對象 ele:一個(gè)指針,指向一個(gè)SDS對象。

下面我們畫一個(gè)跳躍表的示意圖:

圖片

圖中如果要訪問節(jié)點(diǎn)3,則只需要通過頭節(jié)點(diǎn)第四層的前進(jìn)指針,就可以找到此節(jié)點(diǎn)。

如果需要增加元素的時(shí)候,會先使用高層前進(jìn)指針去遍歷,并對比score值,然后逐步縮小插入元素的位置范圍,然后確定最終的位置。這樣其平均時(shí)間復(fù)雜度為O(logN). 相比于鏈表的O(N)的時(shí)間復(fù)雜度來說,其效率大大提高。只不過其代價(jià)就是需要多一點(diǎn)的內(nèi)存空間。

個(gè)人感覺和MySql的索引有點(diǎn)類似。

2.5壓縮列表 ziplist

壓縮列表是 Redis中l(wèi)ist和 hash 對象的底層實(shí)現(xiàn)之一。壓縮列表是為了節(jié)約內(nèi)存而開發(fā)的,是由一系列連續(xù)編碼的內(nèi)存塊組成。其結(jié)構(gòu)示意如下:

圖片

其中各節(jié)點(diǎn)說明如下:

  • zlbytes ,4字節(jié), 記錄壓縮列表占用的內(nèi)存字節(jié)數(shù),對壓縮列表僅進(jìn)行內(nèi)存重分配,或計(jì)算zlend尾節(jié)點(diǎn)位置時(shí)使用。
  • zltail ,4字節(jié), 記錄壓縮列表尾節(jié)點(diǎn)距離壓縮列表的起始地址有多少個(gè)字節(jié)??梢钥焖儆?jì)算得到尾節(jié)點(diǎn)的地址
  • zlen, 2字節(jié) ,記錄了壓縮列表包含的節(jié)點(diǎn)數(shù)量
  • entry X 壓縮列表中的節(jié)點(diǎn),其長度取決于節(jié)點(diǎn)內(nèi)容
  • zlend , 1字節(jié) , 特殊值OxFF (255) 標(biāo)記壓縮列表末端

其中每一個(gè)壓縮列表節(jié)點(diǎn)entry由如下部分組成:

圖片

  • previous_entry_length 記錄了壓縮列表中前一個(gè)節(jié)點(diǎn)的長度,其屬性可以是1或5個(gè)字節(jié)。如果前一個(gè)節(jié)點(diǎn)的長度小于254,那么其長度就是1字節(jié),表示前一節(jié)點(diǎn)的長度。如果遷移節(jié)點(diǎn)的長度大于254字節(jié), 那么其屬性長度則為5個(gè)字節(jié),其中第一個(gè)字節(jié)會設(shè)置為OxFE(254) , 后面的4個(gè)字節(jié)用來表示前一節(jié)點(diǎn)的長度。
  • encoding 表示content 屬性保存的數(shù)據(jù)類型以及長度。content保存字節(jié)數(shù)組時(shí),encoding的值為1,2,5字節(jié), 最高前兩位分別為00,01,10, 最高前兩位后面的其他位數(shù)則記錄content的長度。content保存整數(shù)編碼時(shí),最高2位為11, 其余位記錄整數(shù)類型及。
  • content 保存節(jié)點(diǎn)的內(nèi)容,可以保存字節(jié)數(shù)組或者整數(shù)。

由于previous_entry_length 記錄了前一個(gè)節(jié)點(diǎn)的長度,而且其可能為1個(gè)字節(jié)或者5個(gè)字節(jié),如果前一個(gè)節(jié)點(diǎn)的長度從254之下增加到254之上,那么previous_entry_length 的值就要使用5個(gè)字節(jié)類表示。而如果后面的節(jié)點(diǎn)均存在同樣的情況,那么壓縮列表就會出現(xiàn) 連鎖更新 ,導(dǎo)致內(nèi)存空間重新分配,從而導(dǎo)致壓縮列表增加節(jié)點(diǎn)或者刪除節(jié)點(diǎn)的最壞時(shí)間復(fù)雜度位O(N2).

新版本的redis中,引入了 listpack 。其目的是替換ziplist,整體結(jié)構(gòu)類似。

其entry結(jié)構(gòu)如下:

圖片

len保存了當(dāng)前節(jié)點(diǎn)encoding及data的長度綜合,從而可以避免連鎖更新

2.6快速列表

快速列表(quicklist)可以看成是雙向鏈表和壓縮列表的一種組合。Redis3.2之后 list對象使用快速列表作為其底層實(shí)現(xiàn)。

快速列表使用了quickListNode節(jié)點(diǎn)組成雙向鏈表,然后在每個(gè)快速列表節(jié)點(diǎn)內(nèi)部使用壓縮列表存儲數(shù)據(jù),從而可以控制壓縮列表的長度,避免連鎖更新帶來的性能影響。

其中快速列表的源碼結(jié)構(gòu)如下:

typedef struct quicklist {
    quicklistNode *head;
    quicklistNode *tail;
    unsigned long count;        /* total count of all entries in all ziplists */
    unsigned long len;          /* number of quicklistNodes */
    int fill : QL_FILL_BITS;              /* fill factor for individual nodes */
    unsigned int compress : QL_COMP_BITS; /* depth of end nodes not to compress;0=off */
    unsigned int bookmark_count: QL_BM_BITS;
    quicklistBookmark bookmarks[];
} quicklist;

typedef struct quicklistBookmark {
    quicklistNode *node;
    char *name;
} quicklistBookmark;

typedef struct quicklistNode {
    struct quicklistNode *prev;
    struct quicklistNode *next;
    unsigned char *zl;
    unsigned int sz;             /* ziplist size in bytes */
    unsigned int count : 16;     /* count of items in ziplist */
    unsigned int encoding : 2;   /* RAW==1 or LZF==2 */
    unsigned int container : 2;  /* NONE==1 or ZIPLIST==2 */
    unsigned int recompress : 1; /* was this node previous compressed? */
    unsigned int attempted_compress : 1; /* node can't compress; too small */
    unsigned int extra : 10; /* more bits to steal for future usage */
} quicklistNode;

quickList 中維護(hù)了一個(gè)quicklistBookmark數(shù)組,并且有執(zhí)行qulickListNode 頭尾的指針。

每一個(gè)quicklistBookmark 中有一個(gè)quickListNode的指針,同時(shí)每一個(gè)quickListNode又有指向前一個(gè)后一個(gè)node的指針。

其結(jié)構(gòu)示意圖如下:

圖片

2.7 整數(shù)集合

整數(shù)集合(intset) 是集合鍵底層實(shí)現(xiàn)之一,當(dāng)一個(gè)集合只包含整數(shù)元素的時(shí)候,Redis會使用整數(shù)集合作為集合鍵的實(shí)現(xiàn)。

整數(shù)集合的源碼如下:

typedef struct intset {
    uint32_t encoding;
    uint32_t length;
    int8_t contents[];
} intset;

整數(shù)集合底層是一個(gè)數(shù)組,如果每一個(gè)元素都在16位以內(nèi)的整數(shù)類型(-32768 到 32767),則數(shù)組的每個(gè)元素都為int16_t , 如果新加的整數(shù)超過這個(gè)范圍,并且在32位以內(nèi)的話, 整個(gè)數(shù)組中的每一個(gè)元素都會升級成int32_t 表示的整數(shù), 如果新加入的是64 位才能表示的整數(shù)的話,所以的元素又會再一次升級。

但是整數(shù)集合不支持降級,及 整數(shù)集合中如果有一個(gè)64位的整數(shù),即使移除此元素,整個(gè)集合也不會降級。

這樣做具有一定的靈活性,而且可以節(jié)省內(nèi)存。當(dāng)需要升級的時(shí)候才進(jìn)行升級。

總結(jié)

通過以上 Redis 底層數(shù)據(jù)結(jié)構(gòu)可以看出,其設(shè)計(jì)核心總是在節(jié)約內(nèi)內(nèi)存,提高訪問速度。所以Redis快,這小巧妙的底層設(shè)計(jì)也是功不可沒。同時(shí)我們也可以根據(jù)著些設(shè)計(jì)思想去優(yōu)化我們自己的代碼,優(yōu)秀的設(shè)計(jì)總是值得去學(xué)習(xí)的。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7030

    瀏覽量

    89038
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    3025

    瀏覽量

    74056
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7604

    瀏覽量

    136841
  • Redis
    +關(guān)注

    關(guān)注

    0

    文章

    375

    瀏覽量

    10878
收藏 人收藏

    評論

    相關(guān)推薦

    Redis數(shù)據(jù)類型介紹

    Redis 作為一個(gè)內(nèi)存數(shù)據(jù)庫已經(jīng)被許許多多的公司使用,它的性能非常的優(yōu)秀,讀寫速度支持非常快而且支持 10W 的 QPS 。今天我們就來學(xué)習(xí)下它的豐富的數(shù)據(jù)類型Redis
    的頭像 發(fā)表于 10-09 10:53 ?789次閱讀
    <b class='flag-5'>Redis</b><b class='flag-5'>數(shù)據(jù)類型</b>介紹

    詳解Redis的列表類型list

    Redis入門(四)Redis數(shù)據(jù)類型之列表類型list
    發(fā)表于 05-08 08:16

    Redis基本類型底層實(shí)現(xiàn)

    簡單介紹了Redis的五種對象類型和它們的底層實(shí)現(xiàn)。事實(shí)上,Redis的高效性和靈活性正是得益于對于同一個(gè)對象類型采取不同的
    發(fā)表于 11-25 15:11 ?4484次閱讀
    <b class='flag-5'>Redis</b>基本<b class='flag-5'>類型</b>和<b class='flag-5'>底層</b>實(shí)現(xiàn)

    vhdl數(shù)據(jù)類型

    VHDL中的標(biāo)識符可以是常數(shù)、變量、信號、端口、子程序或參數(shù)的名字。VHDL中的數(shù)據(jù)類型可以分成四大類: 標(biāo)量型(SCALAR TYPE):屬單元素的最基本的數(shù)據(jù)類型,通常用于描述一個(gè)單值數(shù)據(jù)對象
    發(fā)表于 03-30 15:59 ?11次下載

    Redis五種常見對象類型底層數(shù)據(jù)結(jié)構(gòu)

    集合(Zset),我們在日常工作中也會經(jīng)常使用它們。知其然,更要知其所以然,本文將會帶你讀懂這五種常見對象類型底層數(shù)據(jù)結(jié)構(gòu)。 本文主要內(nèi)容參考自《Redis設(shè)計(jì)與實(shí)現(xiàn)》 1. 對象類型
    的頭像 發(fā)表于 11-14 09:50 ?3031次閱讀
    <b class='flag-5'>Redis</b>五種常見對象<b class='flag-5'>類型</b>的<b class='flag-5'>底層數(shù)據(jù)</b>結(jié)構(gòu)

    Redis基本數(shù)據(jù)類型有哪些

    說說Redis基本數(shù)據(jù)類型有哪些吧 字符串:redis沒有直接使用C語言傳統(tǒng)的字符串表示,而是自己實(shí)現(xiàn)的叫做簡單動態(tài)字符串SDS的抽象類型。C語言的字符串不記錄自身的長度信息,而SDS
    的頭像 發(fā)表于 11-02 11:46 ?2575次閱讀

    底層數(shù)據(jù)庫是什么

    底層數(shù)據(jù)庫系統(tǒng)原理
    發(fā)表于 01-11 14:25 ?0次下載

    結(jié)構(gòu)數(shù)據(jù)類型(Struct)及應(yīng)用案例

    Struct數(shù)據(jù)類型使用非常靈活,隨時(shí)可以使用,但是相對于PLC數(shù)據(jù)類型 (UDT) 有以下缺點(diǎn),所以建議需要使用Struct類型時(shí),可以使用PLC數(shù)據(jù)類型(UDT)代替。
    的頭像 發(fā)表于 07-27 16:10 ?1818次閱讀

    什么是數(shù)據(jù)類型轉(zhuǎn)換

    常用的3種數(shù)據(jù)類型:1、Python數(shù)據(jù)類型第一種:字符串(str)。 2、Python數(shù)據(jù)類型第二種:整數(shù)(int)。 3、Python數(shù)據(jù)類型第三種:浮點(diǎn)數(shù)(float)。
    的頭像 發(fā)表于 02-23 15:21 ?1781次閱讀

    定義數(shù)據(jù)類型

    在運(yùn)算之前我們必須首先定義出數(shù)據(jù)類型,定義出腳本支持的數(shù)據(jù)類型,這是運(yùn)算的基礎(chǔ)。 這一小節(jié)我們將定義出數(shù)據(jù)類型,在這里我們暫時(shí)定義四個(gè)數(shù)據(jù)類型:
    的頭像 發(fā)表于 03-03 10:10 ?953次閱讀

    細(xì)說redis十種數(shù)據(jù)類型底層原理

    string 是 Redis 最基本的數(shù)據(jù)類型,它可以存儲任意類型數(shù)據(jù),比如文本、數(shù)字、圖片或者序列化的對象。一個(gè) string 類型的鍵
    的頭像 發(fā)表于 05-15 11:21 ?1890次閱讀
    細(xì)說<b class='flag-5'>redis</b>十種<b class='flag-5'>數(shù)據(jù)類型</b>及<b class='flag-5'>底層</b>原理

    Redis數(shù)據(jù)類型有哪些

    Redis數(shù)據(jù)類型有哪些?有五種常用數(shù)據(jù)類型:String、Hash、Set、List、SortedSet。以及三種特殊的數(shù)據(jù)類型:Bitmap、HyperLogLog、Geospa
    的頭像 發(fā)表于 10-09 10:51 ?807次閱讀

    redis的五種數(shù)據(jù)類型

    Redis是一種高性能的內(nèi)存數(shù)據(jù)庫,常用于緩存、任務(wù)隊(duì)列、分布式鎖等場景。它提供了多種數(shù)據(jù)類型來滿足各種不同的需求,包括字符串(string)、哈希(hash)、列表(list)、集合(set
    的頭像 發(fā)表于 11-16 11:06 ?656次閱讀

    redis的五種數(shù)據(jù)類型底層數(shù)據(jù)結(jié)構(gòu)

    Redis是一種內(nèi)存數(shù)據(jù)存儲系統(tǒng),支持多種數(shù)據(jù)結(jié)構(gòu)。這些數(shù)據(jù)結(jié)構(gòu)不僅可以滿足常見的存儲需求,還能夠通過其底層數(shù)據(jù)結(jié)構(gòu)提供高效的操作和查詢。以
    的頭像 發(fā)表于 11-16 11:18 ?713次閱讀

    redis數(shù)據(jù)結(jié)構(gòu)的底層實(shí)現(xiàn)

    Redis是一種內(nèi)存鍵值數(shù)據(jù)庫,常用于緩存、消息隊(duì)列、實(shí)時(shí)數(shù)據(jù)分析等場景。它的高性能得益于其精心設(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu)和底層實(shí)現(xiàn)。本文將詳細(xì)介紹
    的頭像 發(fā)表于 12-05 10:14 ?620次閱讀