redis的預設字串型別為sds。只會使用c字串作為字面量(比如列印)。
struct sdshdr ;
sds遵循c字串以空字串結尾的慣例,儲存空字串的1位元組空間不計入sds的len屬性裡面。
優點:字串的複雜度為o(1);len可直接返回長度。
杜絕緩衝區溢位;sds的空間分配杜絕了溢位可能。
減少字串修改帶來的記憶體重分配次數;修改後sds長度小於1m,分配和len同樣大小的未使用空間;修改後大於1m,則每次分配1m空間。
二進位制安全,可儲存二進位制資料;包含空字串的特殊文字格式,會使c字串誤認為結束,是二進位制不安全的。
相容c字串函式;可復用c字串函式庫。
c語言沒有鍊錶的資料結構。redis自己構建了鍊錶的實現。
//鍊錶節點
typrdef struct listnode listnode;
//鍊錶
typrdef struct list ;//節點值複製函式
void (*free) ;//節點值釋放函式
int (*match) ;//節點值對比函式
} list;
特性:雙端;鍊錶節點帶有prev和next指標,獲取前後節點的複雜度為o(1)。
無環;表頭節點的prev和表尾節點的next都指向null。
帶表頭指標和表尾指標。
帶鍊錶長度計數器。
多型;通過三個函式,可用於儲存各種不同型別的值。
c語言沒有字典的資料結構。redis自己構建了字典的實現。、
redis的資料庫就是用字典來實現的,也是雜湊建的底層實現。
//雜湊表
typrdef struct dictht dictht;
//雜湊節點
typrdef struct dictentry v;//值
struct dictentry *next;//指向下個雜湊節點,形成鍊錶
} dictentry;
//字典
typrdef struct dict dict;
typrdef struct dicttype ;//計算雜湊的函式
void *(*keydup);//複製鍵的函式
void *(*valdup);//複製值的函式
void *(*keycompare);//對比鍵的函式
void *(*keydestructor);//銷毀鍵的函式
void *(*keydestructor);//銷毀值的函式
} dicttype;
rehash:為ht[1]分配空間,讓字典同時持有ht[0]和ht[1]兩個雜湊表。在字典中維持乙個rehashidx,值為0.每次對字典的操作,先在ht[0]上執行然後rehash到ht[1],rehashidx值增加一。隨著時間的推移,ht[0]終將全部rehash到ht[1]中。這時將rehashidx置為-1。所有新增加的鍵值都會儲存到ht[1]中
跳躍表是一種有序的資料結構,支援平均o(logn)和最壞o(n)的複雜度;大部分情況下跳躍表的效率和平衡樹相媲美。
redis使用跳躍表作為有序集合鍵的底層實現。
//跳躍表節點
typrdef struct zskiplistnode level;
struct zskiplistnode *backward;//後退指標
double score;//分值
robj *obj;//成員物件
} zskiplistnode;
//跳躍表(層高為1-32的隨機數)
typrdef struct zskiplist zskiplist;
整數集合(inset)是集合鍵的底層實現之一,當乙個集合只包含整數值元素,且元素數量不多時,redis就會使用整數集合作為集合鍵的底層實現。
//整數集合
typrdef struct inset inset;
公升級:當將乙個新元素新增到整數集合裡面,且比集合現有的元素型別都要長時,需要對集合先進行公升級,然後再新增元素。(不支援降級,公升級後會保持公升級後資料型別)
1.根據新元素的型別擴充套件空間
2.將現有元素型別轉換為新型別,並將現有元素放置到新位置上
3.新增新元素到底層陣列
壓縮列表(ziplist)是列表鍵和雜湊鍵的底層實現之一。當包含少量列表項,且每個列表項是比較小的字串時,redis就使用壓縮列表來做列表鍵的底層實現。
壓縮列表:
整個壓縮列表占用大小
起始到結尾節點的位元組數
節點數量
節點1節點2
標記結尾
zlbytes
zltail
zllen
entry1
entry2
zlend
節點:前一節點的長度(長度小於254位元組,值的長度為1位元組.長度大於等於254,值的長度為5位元組)
記錄content儲存資料的型別和長度
值previous_entry_length
encoding
content
連鎖更新:previous_entry_length欄位的長度有1位元組和5位元組,若連續多個節點的長度為253,若其中乙個節點的長度更新為254,則下一節點的previous_entry_length要重1位元組變為5位元組。引起連鎖更新。
redis並沒有直接使用上面的資料結構來實現鍵值的資料庫,而是基於這些資料結構建立乙個物件系統。包含字串物件、列表物件、雜湊物件、集合物件和有序集合物件這五種型別的物件
//物件
typrdef struct redisobject robj;
型別:型別
type值
type命令輸出
字串redis_string
"string"
列表redis_list
"list"
雜湊redis_hash
"hash"
集合redis_set
"set"
有序集合
redis_zset
"zset"
編碼:編碼值對應的資料結構
redis_encoding_int
long型別的整數
redis_encoding_enbstr
embstr編碼的簡單動態字串
redis_encoding_raw
簡單動態字串
redis_encoding_ht
字典redis_encoding_linkedlist
雙向鍊錶
redis_encoding_ziplist
壓縮列表
redis_encoding_intset
整數集合
redis_encoding_skiplist
跳躍表和字典
不同的組合:
型別編碼
物件redis_string
redis_encoding_int
整數值字串
redis_string
redis_encoding_embstr
embstr編碼的簡單動態字串
redis_string
redis_encoding_raw
簡單動態字串
redis_list
redis_encoding_ziplist
壓縮列表實現的列表物件
redis_list
redis_encoding_linkedlist
雙向鍊錶實現的列表物件
redis_hsha
redis_encoding_ziplist
壓縮列表實現的雜湊物件
redis_hsha
redis_encoding_ht
字典實現的雜湊物件
redis_set
redis_encoding_intset
整數集合實現的集合物件
redis_set
redis_encoding_ht
字典實現的集合物件
redis_set
redis_encoding_ziplist
壓縮列表實現的有序集合物件
redis_set
redis_encoding_skiplist
跳躍表和字典實現的有序集合物件
為什麼有序集合要使用跳躍表和字典實現?
字典優點:以o(1)的複雜度查詢成員
跳躍表優點:範圍型操作需排序,而跳躍表是按排序儲存元素的
#可通過下面命令檢視編碼型別
object encoding key值
Redis設計於實現(二)
簡介 字典實現 字典的實現是以雜湊表作為它的底層實現,乙個雜湊表可以有多個雜湊表節點,每個節點儲存了字典中的乙個鍵值對。1.雜湊表節點 key就是鍵,v就是鍵中的值 可以是指標,unit64 t 整數,int64 t s64整數 next是將另外乙個雜湊值相同的鍵值對連線在一起的指標 為了解決衝突 ...
Redis設計於實現之字典
簡介 字典實現 字典的實現是以雜湊表作為它的底層實現,乙個雜湊表可以有多個雜湊表節點,每個節點儲存了字典中的乙個鍵值對。1.雜湊表節點 key就是鍵,v就是鍵中的值 可以是指標,unit64 t 整數,int64 t s64整數 next是將另外乙個雜湊值相同的鍵值對連線在一起的指標 為了解決衝突 ...
element ui實現複雜動態表頭
製作乙個不同省份不同業務的的統計報表。如下圖 動態表頭只需要在中v for迴圈即可,但是在多層迴圈中,prop屬性的賦值卻讓我試了半天,希望能幫到有需要的小夥伴,最終 如下 data datalist width 1200 show summary summary method getsummari...