1. Redis --- 八種數據類型(基本命令)
String、Hash、List、Set和Zset。
等同於java中的, Map<String,String> string 是redis裡面的最基本的數據類型,一個key對應一個value。
應用場景 :String是最常用的一種數據類型,普通的key/value存儲都可以歸為此類,如用戶信息,登錄信息和配置信息等;
實現方式 :String在redis內部存儲默認就是一個字元串,被redisObject所引用,當遇到incr、decr等操作(自增自減等原子操作)時會轉成數值型進行計算,此時redisObject的encoding欄位為int。
Redis雖然是用c語言寫的,但卻沒有直接用C語言的字元串,而是自己實現了一套字元串。目的就是為了提升速度,提升性能。 Redis構建了一個叫做簡單動態字元串(Simple Dynamic String),簡稱SDS。
Redis的字元串也會遵守C語言的字元串的實現規則,即 最後一個字元為空字元。然而這個空字元不會被計算在len里頭。
Redis動態擴展步驟:
Redis字元串的性能優勢
常用命令 :set/get/decr/incr/mget等,具體如下;
ps:計數器(字元串的內容為整數的時候可以使用),如 set number 1。
補充:
等同於java中的: Map<String,Map<String,String>> ,redis的hash是一個string類型的field和value的映射表, 特別適合存儲對象。 在redis中,hash因為是一個集合,所以有兩層。第一層是key:hash集合value,第二層是hashkey:string value。所以判斷是否採用hash的時候可以參照有兩層key的設計來做參考。並且注意的是, 設置過期時間只能在第一層的key上面設置。
應用場景 :我們要存儲一個用戶信息對象數據,其中包括用戶ID、用戶姓名、年齡和生日,通過用戶ID我們希望獲取該用戶的姓名或者年齡或者生日;
實現方式 :Redis的Hash實際是內部存儲的Value為一個HashMap,並提供了直接存取這個Map成員的介面。如,Key是用戶ID, value是一個Map。 這個Map的key是成員的屬性名,value是屬性值 。這樣對數據的修改和存取都可以直接通過其內部Map的Key(Redis里稱內部Map的key為field), 也就是通過 key(用戶ID) + field(屬性標簽) 就可以操作對應屬性數據。 當前HashMap的實現有兩種方式 :當HashMap的成員比較少時Redis為了節省內存會採用類似一維數組的方式來緊湊存儲,而不會採用真正的HashMap結構,這時對應的value的redisObject的encoding為zipmap,當成員數量增大時會自動轉成真正的HashMap,此時redisObject的encoding欄位為int。
常用命令 :hget/hset/hgetall等,具體如下:
等同於java中的 Map<String,List<String>> ,list 底層是一個鏈表,在redis中,插入list中的值,只需要找到list的key即可,而不需要像hash一樣插入兩層的key。 list是一種有序的、可重復的集合。
應用場景 :Redis list的應用場景非常多,也是Redis最重要的數據結構之一,比如twitter的關注列表,粉絲列表等都可以用Redis的list結構來實現;
實現方式 :Redis list的實現為一個 雙向鏈表 ,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,Redis內部的很多實現,包括 發送緩沖隊列 等也都是用的這個數據結構。
常用命令 :lpush/rpush/lpop/rpop/lrange等,具體如下:
性能總結 :
它是一個字元串鏈表,left、right都可以插入添加。
等同於java中的 Map<String,Set<String>> ,Set 是一種無序的,不能重復的集合。並且在redis中,只有一個key它的底層由hashTable實現的,天生去重。
應用場景 :Redis set對外提供的功能與list類似是一個列表的功能,特殊之處在於set是可以自動去重的,當你需要存儲一個列表數據,又不希望出現重復數據時,set是一個很好的選擇,並且 set提供了判斷某個成員是否在一個set集合內的重要介面 ,這個也是list所不能提供的;如保存一些標簽的名字。標簽的名字不可以重復,順序是可以無序的。
實現方式 :set 的內部實現是一個 value永遠為null的HashMap,實際就是通過計算hash的方式來快速排重的,這也是set能提供判斷一個成員是否在集合內的原因。
常用命令 :sadd/spop/smembers/sunion等,具體如下:
ZSet(Sorted Set:有序集合) 每個元素都會關聯一個double類型的分數score,分數允許重復,集合元素按照score排序( 當score相同的時候,會按照被插入的鍵的字典順序進行排序 ),還可以通過 score 的范圍來獲取元素的列表。
應用場景 :Redis sorted set的使用場景與set類似,區別是set不是自動有序的,而sorted set可以 通過用戶額外提供一個優先順序(score)的參數來為成員排序,並且是插入有序的,即自動排序。 當你需要一個有序的並且不重復的集合列表,那麼可以選擇sorted set數據結構,比如twitter 的public timeline可以以發表時間作為score來存儲,這樣獲取時就是自動按時間排好序的。
底層實現 : zset 是 Redis 提供的一個非常特別的數據結構,常用作排行榜等功能,以用戶 id 為 value ,關注時間或者分數作為 score 進行排序。實現機制分別是 zipList 和 skipList 。規則如下:
zipList:滿足以下兩個條件
skipList:不滿足以上兩個條件時使用跳錶、組合了hash和skipList
為什麼用skiplist不用平衡樹?
主要從內存佔用、對范圍查找的支持和實現難易程度這三方面總結的原因。
拓展:mysql為什麼不用跳錶?
常用命令 :zadd/zrange/zrem/zcard等;
官網地址: https://redis.io/commands/geoadd
可以用來推算兩地之間的距離,方圓半徑內的人。
關於經度緯度的限制: https://www.redis.net.cn/order/3685.html
一般我們使用Hyperloglog做基數統計。
什麼是基數?就是一個集合中不重復的數的個數。
集合A:{1,3,5,7,9,7}
集合B:{1,3,5,7,9}
AB集合的基數都是5
應用:統計網站的訪問量(一個人訪問網站很多次仍然算作一次)。
優點:佔用的內存是固定的,找2^64次方個數的基數,只需要12KB內存。
缺點:有0.81%的錯誤率,可以忽略不計
概述: bitmap 存儲的是連續的二進制數字(0 和 1),通過 bitmap, 只需要一個 bit 位來表示某個元素對應的值或者狀態,key 就是對應元素本身 。 我們知道 8 個 bit 可以組成一個 byte,所以 bitmap 本身會極大的節省儲存空間。
應用場景: 適合需要保存狀態信息(比如是否簽到、是否登錄...)並需要進一步對這些信息進行分析的場景。比如用戶簽到情況、活躍用戶情況、用戶行為統計(比如是否點贊過某個視頻)。
針對上面提到的一些場景,這里進行進一步說明。
使用場景一:用戶行為分析 很多網站為了分析你的喜好,需要研究你點贊過的內容。
使用場景二:統計活躍用戶
使用時間作為 key,然後用戶 ID 為 offset,如果當日活躍過就設置為 1
那麼我該如果計算某幾天/月/年的活躍用戶呢(暫且約定,統計時間內只有有一天在線就稱為活躍),有請下一個 redis 的命令
使用場景三:用戶在線狀態
對於獲取或者統計用戶在線狀態,使用 bitmap 是一個節約空間效率又高的一種方法。
只需要一個 key,然後用戶 ID 為 offset,如果在線就設置為 1,不在線就設置為 0。
補充 :
巨人的肩膀:
https://www.cnblogs.com/Small-sunshine/p/11687809.html
https://mp.weixin.qq.com/s/CMu7oXVIKp2s-PXTdMlimA
2. redis數據類型和應用場景
Redis是當前比較熱門的NOSQL系統之一,它是一個開源的使用ANSI c語言編寫的key-value存儲系統(區別於MySQL的二維表格的形式存儲。),Redis數據都是緩存在計算機內存中並且它會周期性的把更新的數據寫入磁碟或者把修改操作寫入追加的記錄文件,實現數據的持久化。談到存儲數據,那麼必然要涉及到相關的數據類型,redis主要有以下數據類型:
描述:string 是 redis 最基本的類型,你可以理解成與 Memcached 一模一樣的類型,一個 key 對應一個 value。value其實不僅是String,也可以是數字。string 類型是二進制安全的。意思是 redis 的 string 可以包含任何數據。比如jpg圖片或者序列化的對象。string 類型是 Redis 最基本的數據類型,string 類型的值最大能存儲 512MB。
常用命令:get、set、incr、decr、mget等。
應用場景:規key-value緩存應用。常規計數: 點贊數, 粉絲數。
描述: hash 是一個鍵值(key => value)對集合。Redis hash 是一個 string 類型的 field 和 value 的映射表,hash 特別適合用於存儲對象。
常用命令:hget,hset,hgetall 等。
應用場景:存儲部分變更數據,如商品信息等。
描述:list 列表是簡單的字元串列表,按照插入順序排序。你可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)。列表最多可存儲 232 - 1 元素 (4294967295, 每個列表可存儲40多億)。
常用命令:lpush(添加左邊元素),rpush,lpop(移除左邊第一個元素),rpop,lrange(獲取列表片段,LRANGE key start stop)等。
應用場景:消息隊列,關注列表,粉絲列表等都可以用Redis的list結構來實現。
描述: set是string類型的無序集合。集合是通過hashtable實現的,概念和數學中個的集合基本類似,可以交集,並集,差集等等,set中的元素是沒有順序的。所以添加,刪除,查找的復雜度都是O(1)。
常用命令:sadd,spop,smembers,sunion 等。
應用場景:交集,並集,差集(微博中,可以將一個用戶所有的關注人存在一個集合中,將其所有粉絲存在一個集合。Redis還為集合提供了求交集、並集、差集等操作,可以非常方便的實現如共同關注、共同喜好、二度好友等功能,對上面的所有集合操作,你還可以使用不同的命令選擇將結果返回給客戶端還是存集到一個新的集合中)
描述:zset 和 set 一樣也是string類型元素的集合,且不允許重復的成員。不同是可以打分(排序)
常用命令:zadd,zrange,zrem,zcard等
應用場景:排行榜,帶權重的消息隊列
描述:Bitmaps這個「數據結構」可以實現對位的操作。 把數據結構加上引號主要因為:
Bitmaps本身不是一種數據結構, 實際上它就是字元串 , 但是它可以對字元串的位進行操作。
Bitmaps單獨提供了一套命令, 所以在Redis中使用Bitmaps和使用字元串的方法不太相同。 可以把Bitmaps想像成一個以位為單位的數組, 數組的每個單元只能存儲0和1, 數組的下標在Bitmaps中叫做偏移量。其實大多數Bitmaps的應用場景可以用其他數據類型來實現,用Bitmaps主要是存儲空間佔用特別少
常用命令:getbit key offset;setbit key offset value
應用場景:統計用戶訪問,統計電影某天的的播放量
描述:Redis 在 2.8.9 版本添加了 HyperLogLog 結構。Redis HyperLogLog 是用來做基數統計的演算法,HyperLogLog 的優點是,在輸入元素的數量或者體積非常非常大時,計算基數所需的空間總是固定 的、並且是很小的。在 Redis 裡面,每個 HyperLogLog 鍵只需要花費 12 KB 內存,就可以計算接近 2^64 個不同元素的基 數。這和計算基數時,元素越多耗費內存就越多的集合形成鮮明對比。但是,因為 HyperLogLog 只會根據輸入元素來計算基數,而不會儲存輸入元素本身,所以 HyperLogLog 不能像集合那樣,返回輸入的各個元素。這類數據結構的基本大的思路就是使用統計概率上的演算法,犧牲數據的精準性來節省內存的佔用空間及提升相關操作的性能
常用命令:pfadd, pfcount,pfmerge
應用場景:統計網站的每日UV
描述:GEO功能在Redis3.2版本提供,支持存儲地理位置信息用來實現諸如附近位置、搖一搖這類依賴於地理位置信息的功能.geo的數據類型為zset.
常用命令:geoadd,geopos, geodist
應用場景:附近位置、搖一搖
參考列表:
Redis五種數據類型及應用場景
3. Redis有哪些數據類型
一、String | 字元串類型
Redis的字元串類型,可以存儲字元串、整數或浮點數,如果存儲的是整數或者浮點數,還能執行自增或自減操作。Reids的string類型是二進制的,可以包含任何數據,比如一個序列化的對象、一個圖片、位元組流等,不過存儲大小上限是512M。
Redis底層定義了自己的一種數據結構。
二、List | 列表類型
Redis的列表類型和許多編程語言中的列表類型類似,可以有序地存儲多個字元串,支持從列表的左端和右端推入或彈出元素,Redis列表的底層實現是壓縮列表,Redis內容自己實現的數據結構和雙端鏈表。
將一個或者多個value值插入列表的表頭。如果 key 不存在,會創建一個空列表並執行 LPUSH 操作。當 key
存在但不是列表類型時,返回一個錯誤。
三、set | 集合類型
Redis的集合以無序的方式存儲多個不同的元素,這里要注意的是無序和不同。除了對集合能快速執行添加、刪除、檢查一個元素是否在集合中之外,還可以對多個集合執行交集、並集和差集運算。
Redis的集合類型底層實現主要是通過一種叫做字典的數據結構。不過Redis為了追求極致的性能,會根據存儲的值是否是整數,選擇一種intset的數據結構。當滿足一定條件後,會切換成字典的實現。
四、hash | 散列表(哈希表)
Redis的hash類型其實就是一個縮減版的redis。它存儲的是鍵值對,將多個鍵值對存儲到一個redis鍵裡面。
hash類型的底層主要也是基於字典這種數據結構來實現的。
五、zset | 有序集合
有序集合相比較於集合,多個有序兩個字,我們知道set集合類型存儲的元素是無序的,那Redis有序集合是怎麼保證有序的?使用分值,有序集合里存儲這成員與分值之間的映射,並提供了分值處理命令,以及根據分值的大小有序地獲取成員或分值的命令。
Redis有序集合的實現使用了一種叫跳躍表的數據結構(簡稱跳錶,可自行查閱),同時也使用到了前面提到的壓縮列表。也是滿足一定條件的話,會自行轉換。
4. redis數據結構
redis數據結構
Redis是一種存儲key-value的內存型資料庫,它的key都是字元串類型,value支持存儲5種類型的數據:String(字元串類型)、List(列表類型)、Hash(哈希表類型、即key-value類型)、Set(無序集合類型,元素不可重復)、Zset(有序集合類型,元素不可重復)。
針對這5種數據類型,Redis在底層都是使用的redisObject對象表示的。redisObject有3個重要的屬性:type、encoding、ptr。
redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字元串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。
在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁碟或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。
5. Redis支持幾種數據類型
Redis支持五種數據類型:string(字元串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
意思是 redis 的 string 可以包含任何數據。比如jpg圖片或者序列化的對象,string 類型的值最大能存儲 512MB。
Redis hash是一個 string 類型的 field 和 value 的映射表,hash 特別適合用於存儲對象。
Redis list是簡單的字元串列表,按照插入順序排序。可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)。
Redis的Set是string類型的無序集合,集合是通過哈希表實現的,所以添加,刪除,查找的復雜度都是O(1)。
Redis zset 和 set 一樣也是string類型元素的集合,且不允許重復的成員,不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。
6. Redis的五種數據結構及其底層實現原理
redis的字元串類型是由一種叫做簡單動態字元串(SDS)的數據類型來實現
SDC和C語言字元串的區別:
1:SDS保存了字元串的長度,而C語言不保存,只能遍歷找到第一個 的結束符才能確定字元串的長度
2:修改SDS,會檢查空間是否足夠,不足會先擴展空間,防止緩沖區溢出,C字元串不會檢查
3:SDS的預分配空間機制,可以減少為字元串重新分配空間的次數
備註:重新分配空間方式,小於1M的數據 翻倍+1,例如:13K+13K+1,如果大於1M,每次多分配1M,例如:10M+1M+1,如果字元串變短,並不會立即縮短,而是採用惰性空間釋放,有專門的API可以釋放多餘空間
hash結構里其實是一個字典,有許多的鍵值對
redis的哈希表是一個dictht結構體:
哈希表節點的結構體如下:
hash演算法:
當要將一個新的鍵值對添加到字典裡面時, 程序需要先根據鍵值對的鍵計算出哈希值和索引值, 然後再根據索引值, 將包含新鍵值對的哈希表節點放到哈希表數組的指定索引上面。
hash沖突解決方式:鏈表法,後入的放到最前面
rehash:
鍵值數據量變動時,時為了讓哈希表的負載因子(load factor)維持在一個合理的范圍之內, 當哈希表保存的鍵值對數量太多或者太少時, 程序需要對哈希表的大小進行相應的擴展或者收縮。
如果是擴充,新數組的空間大小為 大於2*used的2的n次方,比如:used=5,則去大於10的第一個2的n次方,為16
如果是縮小,新數組的空間大小為第一個不大於used的2的n次方,比如:used=5,則新大小為4
redis的list列表是使用雙向鏈表來實現的
···
typedef struct listNode {
struct listNode * pre; //前置節點
struct listNode * next; //後置節點
void * value; //節點的值
}
typedef struct list {
listNode *head; //表頭節點
listNode tail; //表尾節點
unsigned long len; //鏈表所包含的節點數量
void ( p) (void ptr); //節點值賦值函數 這里有問題
void ( free) (void ptr); //節點值釋放函數
int ( match) (void *ptr, void *key) //節點值對比函數
}
···
1:有序集合的底層實現之一是跳錶, 除此之外跳錶它在 Redis 中沒有其他應用。
2:整數集合(intset)是集合鍵的底層實現之一: 當一個集合只包含整數值元素, 並且這個集合的元素數量不多時, Redis 就會使用整數集合作為集合鍵的底層實現。
3:數據少是,使用ziplist(壓縮列表),佔用連續內存,每項元素都是(數據+score)的方式連續存儲,按照score從小到大排序。ziplist為了節省內存,每個元素佔用的空間可以不同,對於大數據(long long),就多用一些位元組存儲,而對於小的數據(short),就少用一些位元組來存儲。因此查找的時候需要按順序遍歷。ziplist省內存但是查找效率低。
無序集合可以用整數集合(intset)或者字典實現
Redis的5.0版本中,放出一個新的數據結構Stream。其實也是一個隊列,沒一個不同的key對應的是不同的隊列,沒個隊列的元素,也就是消息,都有一個msgid,並且需要保證msgid是嚴格遞增的。在Stream當中,消息是默認持久化的,即便是Redis重啟,也能夠讀取到信息。
Stream的多播,與其它隊列系統相似,對不同的消費者,也有消費者Group這樣的概念,不同的消費組,可以消費通一個消息,對於不同的消費組,都維護一個Idx下標,表示這一個消費群組費到了哪裡,每次進行消費,都會更新一下這個下標,往後面一位進行偏移。
跳躍表是一種有序數據結構,它通過在每個節點中維持多個指向其它節點的指針,從而大道快速訪問節點的目的,具有以下性質:
1:有很多層結構組成
2:每一層都是一個有序的鏈表,排列順序為由高到低,都至少包含兩個鏈表節點,分別是前面的head節點和後面的nil節點
3:最底層的鏈表包含了所有的元素
4:如果一個元素出現在某一層的鏈表中,那麼在該層之下的鏈表也全部都會出現
5:鏈表中的每個節點都包含兩個指針,一個指向同一層的下一個鏈表節點,另一個指向下一層的通一個鏈表節點
多個跳躍表節點構成一個跳躍表
1:搜索,從最高層的鏈表節點開始,如果比當前節點要大和比當前層的下一個節點要小,那麼則往下找,也及時和當前層的下一層的節點下一個節點
2:插入,首先確定插入的層數,有一種方法是拋一個硬幣,如果是正面就累加,直到遇到反面為止,最後記錄正面的次數作為插入的層數,當確定插入的層數K後,則需要將新元素插入從底層到K層
3:刪除,在各個層中找到包含指定值得節點,然後將節點從鏈表中刪除即可,如果刪除以後只剩下頭尾兩個節點,則刪除這一層。
整數集合是Redis用於保存整數值集合的抽象數據類型,它可以保存int16_t、int32_t、int64_t的整數值,並且保證集合中不會出現重復元素。
整數集合的每個元素都是contents數組的一個數據項,他們按照從小到大的順序排列,並且不包含任何重復項。
length屬性記錄了contents數組的大小。
需要注意的是雖然contents數組聲明為int8_t類型,但是實際上contents數組並不保存任何int8_t類型的值,其真正類型由encoding來決定。
壓縮列表(ziplist)是Redis為了節省內存而開發的,是由一系列特殊編碼的連續內存塊組成的順序型數據結構,一個壓縮列表可以包含任意多個節點(entry),每個節點可以保存一個位元組數組或一個整數值。
壓縮列表的原理:壓縮列表並不是對數據利用某種演算法進行壓縮的,而是將數據按照一定規則編碼在一塊連續的內存區域,目的是節省內存。
壓縮列表的每個節點構成如下:
7. redis的五種數據類型是什麼
如下:
一、string
string 是 redis 最基本的類型,你可以理解成與 Memcached 一模一樣的類型,一個 key 對應一個 value。
string 類型是二進制安全的。意思是 redis 的 string 可以包含任何數據。比如jpg圖片或者序列化的對象。
string 類型是 Redis 最基本的數據類型,string 類型的值最大能存儲 512MB。
命令: SET 和 GET 命令。
二、hash
Redis hash 是一個鍵值(key=>value)對集合。
Redis hash 是一個 string 類型的 field 和 value 的映射表,hash 特別適合用於存儲對象。
HMSET, HGET 命令,HMSET 設置了兩個 field=>value 對, HGET 獲取對應 field 對應的 value。
三、list
列表是簡單的字元串列表,按照插入順序排序。可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)。
列表最多可存儲 232 - 1 元素 (4294967295,每個列表可存儲40多億)。
lpush 設置值,lrange取值。
四、set
redis的set是string的無序集合。集合通過哈希表實現。
添加一個string元素到key對應的set集合中,用 sadd命令。返回1表示成功,0表示在集合中已存在,返回錯誤表示key對應的set不存在。
查看用smembers 命令。
集合內元素的唯一性,第二次插入的元素將被忽略。
集合中最大的成員數為 232 - 1(4294967295, 每個集合可存儲40多億個成員)。
五、zset
redis的zset 和 set 一樣也是string類型元素的集合,且不允許重復的成員。
不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。zset的成員是唯一的,但分數(score)卻可以重復。
添加元素到集合,元素在集合中存在則更新對應score:zadd key score member。
Redis數據模型:
Redis的外圍由一個鍵、值映射的字典構成。與其他非關系型資料庫主要不同在於:Redis中值的類型不僅限於字元串,還支持如下抽象數據類型:
1、字元串列表。
2、無序不重復的字元串集合。
3、有序不重復的字元串集合。
4、鍵、值都為字元串的哈希表。
值的類型決定了值本身支持的操作。Redis支持不同無序、有序的列表,無序、有序的集合間的交集、並集等高級伺服器端原子操作。
8. Redis五個基本數據類型詳解
docker pull redis
docker run -p 6379:6379 --name redis -v {路徑}/redis.conf:/etc/redis/redis.conf -v {路徑}/data:/data -d redis redis-server /etc/redis/redis.conf --appendonly yes
如果在setnx之後執行expire之前進程意外crash或者要重啟維護了,那會怎麼樣?
set指令有非常復雜的參數,這個應該是可以同時把setnx和expire合成一條指令來用的!後面會講具體怎麼做。
下面是sds定義
而對於SDS,由於len屬性和free屬性的存在,對於修改字元串SDS實現了空間預分配和惰性空間釋放兩種策略:
1、空間預分配:對字元串進行空間擴展的時候,擴展的內存比實際需要的多,這樣可以減少連續執行字元串增長操作所需的內存重分配次數。
2、惰性空間釋放:對字元串進行縮短操作時,程序不立即使用內存重新分配來回收縮短後多餘的位元組,而是使用 free 屬性將這些位元組的數量記錄下來,等待後續使用。(當然SDS也提供了相應的API,當我們有需要時,也可以手動釋放這些未使用的空間。)
在原來的單鏈表基礎上,我們查詢數據需要從頭遍歷到尾,時間復雜度太高了。我們在思考提高查詢效率時,在原有鏈表上添加索引,如果還是覺得查詢太慢我們又在索引上再增加一級索引,以此類推。跳躍表的實質就是在單鏈表上一級一級地增加索引來達到加快查詢的目的。
參考: https://zhuanlan.hu.com/p/161835019
9. 5種數據類型
Redis支持5種數據類型:string(字元串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
① 簡介:String是Redis最基礎的數據結構類型,它是二進制安全的,可以存儲數字,圖片或者序列化的對象,值最大存儲為512M
簡單使用舉例: set key value、get key等
應用場景:共享session、分布式鎖,計數器、限流。
② 哈希類型是指v(值)本身又是一個鍵值對(k-v)結構
簡單使用舉例:hset key field value 、hget key field
內部編碼:ziplist(壓縮列表) 、hashtable(哈希表)
應用場景:緩存用戶信息等。
③ Redis list 列表是簡單的字元串列表,按照插入順序排序。你可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)。
底層雙向鏈表,可以通過push和pop操作從列表的頭部或者尾部添加或者刪除元素,這樣List即可以作為棧,也可以作為隊列
lpush+lpop=Stack(棧)
lpush+rpop=Queue(隊列)
④ Redis set是string類型的無序集合。不包含重復元素
⑤ Redis zset 和 set 一樣也是string類型元素的集合,且不允許重復的成員。但sorted set可以通過用戶額外提供一個優先順序(score)的參數來為成員排序,並且是插入有序的,即自動排序。
Redis sorted set的內部使用ziplist或跳錶,跳錶組合了skiplist和hash,HashMap里放的是成員到score的映射,而跳錶裡存放的是所有的成員,
跳錶就是在鏈表的基礎上,增加多級索引提升查找效率。
跳錶支持平均 O(logN),最壞 O(N)復雜度的節點查找,還可以通過順序性操作批量處理節點。
10. redis支持的數據類型有哪些
Redis支持五種數據類型:string(字元串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
string 是 redis 最基本的類型,可以理解成與 Memcached 一模一樣的類型,一個 key 對應一個 value。string 類型是二進制安全的。意思是 redis 的 string 可以包含任何數據。比如jpg圖片或者序列化的對象,string 類型的值最大能存儲 512MB。
(10)redis五種數據類型存儲方式擴展閱讀:
Redis hash是一個 string 類型的 field 和 value 的映射表,hash 特別適合用於存儲對象。
Redis list是簡單的字元串列表,按照插入順序排序。可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)。
Redis的Set是string類型的無序集合,集合是通過哈希表實現的,所以添加,刪除,查找的復雜度都是O(1)。
Redis zset 和 set 一樣也是string類型元素的集合,且不允許重復的成員,不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。
zset的成員是唯一的,但分數(score)卻可以重復。