Redis 數據類型和各自的使用場景
- 1、String類型
- 2、List類型
- 3、Hash類型
- 4、Set類型
- 5、Zset類
- BitMap:
- HyperLogLog:
- GEO:.
- Stream:
- 跳表
常見的有五種數據類型:String字符串,List列表,Hash哈希,Set集合、Zset有序集合。
1、String類型
String適用場景:一般用于緩存字符串對象
它底層的數據結構是 SDS簡單動態字符串。
1、SDS 不僅可以保存文本數據,而且能保存圖片、視頻、壓縮文件這樣的二進制數據。
2、SDS 獲取字符串長度的效率更高,用 len 屬性記錄了字符串長度,時間復雜度大約是 O(1)。而C 語言的字符串沒有len, O(n);
3、Redis 的 SDS API 是安全的,拼接字符串不會造成緩沖區溢出,因為拼接之前會先檢查,如果空間不夠就自動擴容。
2、List類型
List場景:一般用于任務隊列
底層數據結構由 quicklist 快表實現。
Quicklist :「雙鏈表 + 壓縮列表」組合,一個 quicklist 就是一個鏈表,而鏈表中的每個元素是一個壓縮列表。
壓縮列表:是一塊連續的內存空間,有點像數組。但是它有一個記錄前一個元素長度的字段,主要是幫助快速定位到列表中的下一個元素,從而提高遍歷效率。但是有【連鎖更新】的問題。
- 前一個節點長度 < 254 字節,prevlen 需要用 1 字節的空間來保存這個長度值
- 前一個節點長度 > 254 字節,prevlen 需要用 5 字節的空間來保存這個長度值
- 本來都在250~253 之間,因為前面插入了新的導致最前面大于254,后面都跟著變了
解決辦法:控制每個鏈表節點中的壓縮列表的元素個數,來規避連鎖更新的問題。因為壓縮列表元素越少,連鎖更新帶來的影響就越小。
3、Hash類型
Hash場景:購物車等。
鍵:cart:123 、字段:product:456、值:2 (用戶123的購物車里有456產品,購物車里456產品的數量是2)
在 Redis 7.0 中,由 listpack 數據結構來實現。
listpack 是在壓縮列表的基礎上改造而來的,它沒有壓縮列表中記錄前一個節點長度的字段了,只記錄當前節點的長度,所以加入新元素的時候,不會影響其他節點的長度字段的變化,從而避免了壓縮列表的連鎖更新問題。
4、Set類型
Set 場景:一些聚合計算場景,比如點贊、共同關注等。
Set 類型的底層數據結構是由哈希表或整數集合實現的:
如果集合中的元素都是整數且元素個數小于默認的 512 個,Redis 會使用整數集合作為 Set 類型的底層數據結構;
如果集合中的元素不滿足上面條件,則 Redis 使用哈希表作為 Set 類型的底層數據結構。
5、Zset類
Zset場景:排序場景,比如Rank排行榜、姓名排序等。
Zset 類型的底層數據結構是由 listpack 數據結構來實現。
Redis 后續版本又支持四種數據類型,它們的應用場景如下:
BitMap:
二值狀態統計的場景,比如簽到、判斷用戶登陸狀態等;
HyperLogLog:
海量數據基數統計的場景,比如百萬級網頁訪問量計數等;
GEO:.
存儲地理位置信息的場景,比如滴滴叫車;
Stream:
消息隊列,相比于基于 List 類型實現的消息隊列,有這兩個特有的特性:自動生成全局唯一消息ID,支持以消費組形式消費數據。
跳表
跳表其實是一種多層的有序鏈表,跳表在原有的有序鏈表基礎上結合二分查找的思想增加了多級索引,通過索引來實現快速查詢。
我們知道對于一個單鏈表來說,即使它有序,查找的時間復雜度還是O(n)。我們可以做一些優化,每兩個結點提取一個"索引"到上一級,上一級有到下一級的指針。那如果鏈表數據是1-10,正常查找是O(n),有了索引之后就可以2、4、6、8這樣來查找,甚至說數據多的話可以建立三層四層索引,以此來提升工作效率。
跳表的查詢、插入、刪除時間復雜度都是O(logn),空間復雜度是 O(n)