Redis字符串類型爲何能存整數,浮點型甚至是二進制位(使用SETBIT等命令)

Redis沒有直接使C語言傳統的的字符串(以空字符串結尾的字符數組,簡稱C字符串),而是本身構建了一種名爲簡單動態字符串(simple dynamic string, SDS)的抽象類型,並將SDS用做Redis的默認字符串表示。redis

好比,客戶端執行命令:數據庫

redis>SET msg "hello world";
ok
複製代碼

那麼Redis將在數據庫中建立兩個SDS分別存儲鍵和值。api

SDS的定義

每一個sds.h/sdshrd結構表示一個SDS值:數組

struct sdshrd{
    // 記錄buf數組中已使用字節的數量
    // 等於SDS所保存字符串長度
    int len;
    // 記錄buf數組中未使用的字節數量
    int free;
    // 字節數組,用於保存字符串
    char buf[];
}
複製代碼

因此上面set msg "hello world",值在的SDS中的樣子以下: 安全

hello world的SDS
SDS遵循C語言以空字符串結尾的慣例,保存空字符串的一個字節不計算在len屬性當中,而且爲空字符串分配額外的一個字節空間,以及添加空字符串到字符串末尾等操做,都是由SDS函數自動完成的。遵循空字符串結尾這一特性的好處是能夠複用一部分C字符串函數庫中的函數。

常數複雜度獲取字符串長度

C字符串獲取長度須要遍歷整個字符串,複雜度爲O(N),而是用SDS的話,由於使用了一個len屬性來記錄字符串長度,因此獲取長度的複雜度爲O(1)。bash

SDS 其餘特性這裏暫不介紹

二進制安全

C字符串中的字符必須符合某種編碼(好比ASCII),而且除了字符串的末尾以外,字符串裏面不能包含空字符串,不然最早被程序讀入的空字符串會被誤認爲是字符串末尾,這些限制使得C字符串只能保存文本數據,不能保存像圖片、音頻、視頻等這樣子的二進制數據。函數

Redis中的SDS的api都是二進制安全的,會以二進制的方式來處理SDS存放buf數組裏的數據,程序不會對其中的數據作任何限制、過濾等,數據在寫入時是什麼樣的,它被讀取時就是什麼樣子。編碼

使用SDS來保存以前提到的特殊數據格式(好比音頻,視頻等)就沒有任何問題,由於SDS使用len屬性的值而不是字符串來判斷字符串是否結束。因此使用二進制安全的SDS,使得Redis不只考驗保存文本數據,還能夠保存任意格式的二進制數據。spa

參考書籍:《Redis設計與實現》設計

相關文章
相關標籤/搜索