五種基礎資料結構先就不多說了,string,list,hash, set, zset。
兩種特殊資料結構:位圖,hyperloglog。
實現原理及應用場景:
[string] 是 redis 最基本的型別,你可以理解成與 memcached 一模一樣的型別,乙個 key 對應乙個 value。value其實不僅是string,也可以是數字。string 型別是二進位制安全的。意思是 redis 的 string 可以包含任何資料。比如jpg或者序列化的物件。string 型別是 redis 最基本的資料型別,string 型別的值最大能儲存 512mb。
應用場景:
可以利用redis的incr、incrby、decr、decrby等指令來實現原子計數的效果。即可以用來實現業務上的統計計數需求。也可用於實現idmaker,即生成全域性唯一的id。 (常規key-value快取應用。常規計數: 微博數, 粉絲數。)
實現方式:
sds(****** dynamic string)簡單動態字串,它是由c語言完成;string在redis內部儲存預設就是乙個字串,被redisobject所引用,當遇到incr,decr等操作時會轉成數值型進行計算,此時redisobject的encoding欄位為int。採用預分配冗餘空間方式減少記憶體的頻繁分配。1mb內擴容加倍現有空間,超過1mb每次加1mb。
[list] 是簡單的字串列表,按照插入順序排序。
應用場景:
由鍊錶形成,插入刪除操作非常快,時間複雜度o(1);但索引定位很慢,時間複雜度o(n)。實現由壓縮列表ziplist 或雙向鍊錶linkedlist 因為雙向鍊錶占用的記憶體比壓縮列表要多, 所以當建立新的列表鍵時, 列表會優先考慮使用壓縮列表, 並且在有需要的時候, 才從壓縮列表實現轉換到雙向鍊錶實現。 redis list實現乙個雙向鍊錶,即可以支援反向查詢和遍歷,更方便操作,不過帶來了部分額外的記憶體開銷,redis內部的很多實現,包括傳送緩衝佇列等也都是用的這個資料結構。
[hash/字典] 是乙個鍵值(key => value)對集合。redis hash 是乙個 string 型別的 field 和 value 的對映表,hash 特別適合用於儲存物件。
應用場景:
儲存部分變更資料,如使用者資訊等。
實現方式:
hash對應value內部實際就是乙個hashmap,實際這裡會有2種不同實現,這個hash的成員比較少時redis為了節省記憶體會採用類似一維陣列的方式來緊湊儲存,而不會採用真正的hashmap結構,對應的value redisobject的encoding為zipmap,當成員數量增大時會自動轉成真正的hashmap。儲存消耗高於單個string,根據世界情況定吧。
[set]是string型別的無序集合。集合是通過hashtable實現的,概念和數學中個的集合基本類似,可以交集,並集,差集等等,set中的元素是沒有順序的。所以新增,刪除,查詢的複雜度都是o(1)。
應用場景:
set對外提供的功能與list類似是乙個列表的功能,特殊之處在於set是可以自動排重的,當你需要儲存乙個列表資料,又不希望出現重複資料時,set是乙個很好的選擇,並且set提供了判斷某個成員是否在乙個set集合內的重要介面,這個也是list所不能提供的。 set 就是乙個集合,集合的概念就是一堆不重複值的組合。利用redis提供的set資料結構,可以儲存一些集合性的資料。可實現如共同關注、共同喜好、共同好友等功能。
實現方式:
set 的內部實現是乙個 value永遠為null的hashmap,實際就是通過計算hash的方式來快速排重的,這也是set能提供判斷乙個成員是否在集合內的原因。
[zset] 是和 set 一樣也是string型別元素的集合,且不允許重複的成員,增加了score.
應用場景:
a:如 key 儲存學科成績,value儲存學生id,score儲存成績
b:如 key 儲存城市id(1101),value儲存員工id,score 儲存員工業績權重分(某相親網可用)
實現方式:
內部使用hashmap和跳躍表(skiplist)來保證資料的儲存和有序,hashmap裡放的是成員到score的對映,而跳躍表裡存放的是所有的成員,排序依據是hashmap裡存的score,使用跳躍表的結構可以獲得比較高的查詢效率,並且在實現上比較簡單。
(那麼為什麼要用跳躍表?b+tree不香?)
[位圖]嚴格意義其實並不是一種資料結構,其實就是一種普通的字串,也可以說是byte陣列。
應用場景:
假如要統計使用者一年簽到次數,這裡如果用記錄表來記錄的話,每個使用者就用存365條記錄,一千個使用者就是365*1000條記錄,想一下這個資料量是不少的,而且實際業務意義不是很明顯。位圖就是byte數字,假如簽到就表示1,沒簽到就表示0,這裡可以用365個位元組來記錄前端數,這樣很節省資源了,提高效率。使用者簽到統計,月活躍使用者數統計等等業務場景都適合用位圖實現
實現方式:
我是理解成」位陣列「這樣吧。
[hyperloglog]是一種高階資料結構,是用來做基數統計的演算法,每個 hyperloglog 鍵只需要花費 12 kb 記憶體,只會根據輸入元素來計算基數,而不會儲存輸入元素本身。
應用場景:
如千萬uv,允許標準誤差0.81%,可用之。
實現方式:
暫無?(實現較複雜,回頭再補,該睡覺了。。。),
Redis資料結構
字典 dict 是redis裡最核心的資料結構,正如其全稱remote dictionary service所說,redis其實就是乙個字典服務,字典以key value的形式呈現給使用者,key是簡單的字串,而value可以是各種資料結構,比如字串 string 鍊錶 list 集合 set 排序...
Redis 資料結構
最近接觸到了redis的使用,借這個機會深入的了解一下redis的實現和設計原理。下面先介紹一下redis底層所用到的資料結構。redis的實現幾乎都是基於下面的幾個資料結構之上的。struct sdshdr struct listnode struct list struct dictentry ...
redis 資料結構
今天學習了redis的列表型別 lpush ltrim lrange lpush mylist content ltrim 0,99 lrange 0,1 lrange 兩個引數 分別代表第乙個元素和最後乙個元素 redis的列表型別,可以用來做訊息佇列 使用乙個程序 用lpush命名作為生產者 使...