深入理解redis數據類型:String,Lists,Sets,Sorted Sets,Hashes,Bitmaps,HyperLogLogs等 ...
轉載請註明出處:https://www.cnblogs.com/wenjunwei/p/9720033.html
redis的存儲模型
redis不是普通的鍵值對存儲,它實際上是一個數據結構存儲伺服器,可以支持不同類型的值。這意味著redis相比傳統鍵值對字元串key和字元串value存儲來說,redis的值可以包含更複雜的數據結構。
redis支持哪些數據結構呢?
1.String: 二進位安全字元串(Binary-safe strings)
2.列表(Lists): 根據插入順序排序的字元串元素集合。從根本上來說就是鏈表。
3.集合(Sets): 無序且唯一的字元串元素集合。
4.有序集合(Sorted sets): 與Sets類似,但每個字元串元素都與一個浮點數關聯,稱為分數(score)。這裡的元素總是會按分數來進行排序,因此又與Sets不同。(例如:你可以這樣取值: 我要前十名、我要後十名)
5.哈希(Hashes): 是由與值相關聯的欄位組成的映射。欄位和值都是字元串。這與Ruby或Python哈希非常相似。
6.位數組或簡稱點陣圖(Bit arrays or simply bitmaps): 可以使用特殊命令處理字元串值,如:您可以設置和清除各個位,將所有位設置為1,查找第一組或未設置位等等。
7.HyperLogLogs: 這是一個概率數據結構,用於計算集合的基數。
Redis Key
RedisKey是二進位安全的,這意味著您可以使用任何二進位序列作為key,從"foo"這樣的字元串到JPEG文件內容,又或者是空字元串,都是有效鍵。
rediskey的一些規則:
1.key太長是不好的。例如:一個1024位元組的key,在記憶體方面就占用不少,而且在數據集中查找key的時候可能會需要幾次高昂的key對比的過程。即使現在任務需要一個很大的key,我們通過散列法hashing(如SHA1)來獲得key,從帶寬和記憶體來看,這也是一個更好的辦法。
2.key太短也是不好的。如果你將一個"user:1000:followers"的key改為"u1000flw",那是沒有任何意義的。因為這種做法節省的空間很小,但是前者會更顧名思義。我們在工作中應該要找到一個衡量key值的平衡點。
3.最好堅持使用一種命名格式。例如:“object-type:id”,如“user:1000”。而點或短劃線通常用於多字詞欄位,如“comment:1234:reply.to”或“comment:1234:reply-to”。可以定一個命名規範。
4.最大記憶體。redis中允許的key值最大是512MB。
Redis expires:有時間限制的key
在使用更複雜的數據結構之前,我們討論一個無論任何數據類型都有的一個特性,稱為Redis過期。您可以為key設置一個超時時間,這是一個有限的生存時間。當生存時間過去時,key就會自動銷毀,就類似於key被調用了del命令一樣。
關於redis到期信息:
1.可以使用秒或者毫秒精度進行設置。
2.但是,到期時間的分辨繫數始終為1毫秒。
3.過期信息將被覆制保留在磁碟中,當redis伺服器停止時,時間依然在度過(這意味著redis會保存key過期的時間)。
一.Redis String
Redis的String類型是最簡單的類型,與redis key有著密切關聯。也是Memcached中唯一的數據類型,對於新手來說,在redis使用這個類型是很自然的。
由於Redis key是字元串,當value也是字元串的時候,會將字元串映射到另一個字元串。
常見實例:
1.例如緩存HTML片段或頁面。
2.session緩存。
3.驗證碼緩存。
二.Redis Lists
列表實現主要有數組和鏈表,兩種實現方法的到的list的屬性差異很大。Redis Lists是通過鏈表實現的。這意味著即使列表中有數百萬個元素,在列表頭部或尾部新增元素的速度都是一樣的。當然鏈表結構也是有缺點的,使用數組實現list,通過索引訪問元素的速度非常快,而使用鏈表就咩有那麼快了。
Redis使用鏈表實現Lists,對於資料庫而言,最重要的是能夠以非常快的方式將元素添加到很長的列表中。當快速訪問大量元素集合的中間位置很重要時,可以使用不同的數據結構,稱為sorted sets(後面會介紹到)。
常見實例:
1.記住用戶發佈到社交網路的最新消息。
2.流程之間的通信,使用生產者將項目列表推入訂閱模式。redis具有特殊的命令,使用這些用例更加的可靠和高效。
3.每次用戶發佈新照片,我們都可以將其ID添加到列表中。
4.當用戶訪問主頁時,我們通過LRANGE 0 9命令獲取最新的10個項目。
三.Redis Hashes
我們可以將Redis Hashes看為使用'哈希'作為對key/value的映射表。
添加和刪除操作都是O(1)(平均)的複雜度。hash類型特別適合用於存儲對象,但是放入的hash對象實際上的沒有限制(除了可用記憶體之外),因此在應用程式中可以以許多不同的方式使用散列。
在field的數量在限制的範圍內以及value的長度小於指定的位元組數,即小哈希中,會在記憶體中以特殊的方式編碼,會比較節省記憶體。
常用實例:
1.用於存儲關係數據表或對象信息:如 {name:'張三',age:17}
四.Redis Sets
Redis Sets是無序的字元串集合。我們可以用作元素集合存儲,也可以針對集合做其他操作。比如測試給定的元素是否存在,執行多個集合之間的交集,並集或差異等。
存儲的數據結構是哈希表,所以增刪改查的操作複雜度都是O(1)。
常見實例:
1.用於集合去重。
2.用於分散式鎖。
五.Redis Sorted Sets
Sorted Sets數據類型就像是set和hash的混合。與sets一樣,Sorted Sets是唯一的,不重覆的字元串組成。可以說Sorted Sets也是Sets的一種。
雖然在Sets內部元素沒有進行排序,但是Sorted Sets中每個元素都與浮點值相關聯,稱為分數(因為每個元素都映射到一個值,所以說有點類似hash)。
此外,Sorted Sets中的元素按順序排序,他們的規則如下:
1.如果A和B是兩個具有不同分數的元素,如果A.score > B.score,則 A > B。
2.如果A和B分數相同,如果A字元串在字典排序上大於B字元串,則A>B。在Sorted Sets中A、B字元串不能相等。
實現方式:Sorted Sets是通過Skip List(跳躍表)和hash Table(哈希表)的雙埠數據結構實現的,因此每次添加元素時,Redis都會執行O(log(N))操作。所以當我們要求排序的時候,Redis根本不需要做任何工作了,早已經全部排好序了。元素的分數可以隨時更新。
常見實例:
1.獲取排行集合:獲取第10-50名元素集合。
2.在分數範圍操作:獲取分數在60-80的元素集合。
3.Redis2.8後,在分數相同情況下,我們還可以根據字典順序進行排序。
4.可以獲取某個元素在集合中的名次。
六.Bitmaps
點陣圖不是實際的數據類型,而是String類型上定義了一組面向位的操作。由於字元串是二進位安全的blob ,並且他們的最大長度為512MB,所以他們最多適合2^32不同的位。
點陣圖的最大優勢之一就是他們在存儲信息時通常可以節省大量的空間。
常見實例:
1.各種實時分析。
2.存儲與對象ID關聯的節省空間但高性能的布爾信息。
七.HyperLogLogs
HyperLogLogs是用來做基數(不重覆元素)統計的演算法。HyperLogLog 的優點是,在輸入元素的數量或者體積非常非常大時,計算基數所需的空間總是固定 的、並且是很小的。
在 Redis 裡面,每個 HyperLogLog 鍵只需要花費 12 KB 記憶體,就可以計算接近 2^64 個不同元素的基 數。這和計算基數時,元素越多耗費記憶體就越多的集合形成鮮明對比。
但是,因為 HyperLogLog 只會根據輸入元素來計算基數,而不會儲存輸入元素本身,所以 HyperLogLog 不能像集合那樣,返回輸入的各個元素。
常見實例:
1.用來做基數統計的演算法
總結
通過上面的類型介紹,我們使用Redis時,通常會接觸Redis的5種對象類型(字元串、哈希、列表、集合、有序集合),而每一種數據類型都有著各自的特性,我們需要根據自己的應用場景選擇最合適的數據類型,利用最合適的特性,可以達到事半功倍的效果。
感謝您的閱讀,如果您覺得閱讀本文對您有幫助,請點一下“推薦”按鈕。本文歡迎各位轉載,但是轉載文章之後必須在文章頁面中給出作者和原文連接。