一、五大數據結構
Redis可以存儲鍵與5種不同數據結構類型之間的映射,這5種數據結構類型分別為:
STRING:字符串
LIST:列表
SET:集合
HASH:散列
ZSET:有序集合
TYPE命令
用來獲得鍵的數據類型,而不是鍵值的數據類型
返回值:
string:字符串類型
hash:散列類型
list:列表類型
set:集合類型
zet:有序集合類型
二、內部編碼
實際上每種數據結構都有自己底層的內部編碼實現,而且是多種實現, 這樣Redis會在合適的場景選擇合適的內部編碼,如下圖所示
關于這些數據結構的詳細介紹可以參閱后續的文章
Redis這樣設計有兩個好處:
第一,可以改進內部編碼,而對外的數據結構和命令沒有影響,這樣一旦開發出更優秀的內部編碼,無需改動外部數 據結構和命令,例如Redis3.2提供了quicklist,結合了ziplist和linkedlist兩者的優勢,為列表類型提供了一種更為優秀的內部編碼實現,而對外部用戶來 說基本感知不到
第二,多種內部編碼實現可以在不同場景下發揮各自的優勢,例如ziplist比較節省內存,但是在列表元素比較多的情況下,性能會有 所下降,這時候Redis會根據配置選項將列表類型的內部實現轉換為 linkedlist
OBJECT ENCODING命令
該命令用來返回數據結構的內部編碼
三、再說五種結構
這里我不會講的太深入,深入的內容會在后續章節,每個數據結構作為一個專題來具體講。
1.String 字符串類型
是redis中最基本的數據類型,一個key對應一個value。
String類型是二進制安全的,意思是 redis 的 string 可以包含任何數據。如數字,字符串,jpg圖片或者序列化的對象。
使用:get 、 set 、 del 、 incr、 decr 等
127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> get hello
"world"
127.0.0.1:6379> del hello
(integer) 1
127.0.0.1:6379> get hello
(nil)
127.0.0.1:6379> get counter
"2"
127.0.0.1:6379> incr counter
(integer) 3
127.0.0.1:6379> get counter
"3"
127.0.0.1:6379> incrby counter 100
(integer) 103
127.0.0.1:6379> get counter
"103"
127.0.0.1:6379> decr counter
(integer) 102
127.0.0.1:6379> get counter
"102"
實戰場景:
1.緩存:經典使用場景,把常用信息,字符串,圖片或者視頻等信息放到redis中,redis作為緩存層,mysql做持久化層,降低mysql的讀寫壓力。
2.計數器:redis是單線程模型,一個命令執行完才會執行下一個,同時數據可以一步落地到其他的數據源。
3.session:常見方案spring session + redis實現session共享,
?
2.Hash (哈希)
是一個Mapmap,指值本身又是一種鍵值對結構,如 value={{field1,value1},......fieldN,valueN}}
?
使用:所有hash的命令都是? h ??開頭的? ? ?hget ?、hset 、? hdel 等
127.0.0.1:6379> hset user name1 hao
(integer) 1
127.0.0.1:6379> hset user email1 hao@163.com
(integer) 1
127.0.0.1:6379> hgetall user
1) "name1"
2) "hao"
3) "email1"
4) "hao@163.com"
127.0.0.1:6379> hget user user
(nil)
127.0.0.1:6379> hget user name1
"hao"
127.0.0.1:6379> hset user name2 xiaohao
(integer) 1
127.0.0.1:6379> hset user email2 xiaohao@163.com
(integer) 1
127.0.0.1:6379> hgetall user
1) "name1"
2) "hao"
3) "email1"
4) "hao@163.com"
5) "name2"
6) "xiaohao"
7) "email2"
8) "xiaohao@163.com"
實戰場景:
1.緩存:能直觀,相比string更節省空間,的維護緩存信息,如用戶信息,視頻信息等。
?
?3.鏈表?
List 說白了就是鏈表(redis 使用雙端鏈表實現的 List),是有序的,value可以重復,可以通過下標取出對應的value值,左右兩邊都能進行插入和刪除數據。
使用列表的技巧
lpush+lpop=Stack(棧)
lpush+rpop=Queue(隊列)
lpush+ltrim=Capped Collection(有限集合)
lpush+brpop=Message Queue(消息隊列)
?
使用:
?
127.0.0.1:6379> lpush mylist 1 2 ll ls mem
(integer) 5
127.0.0.1:6379> lrange mylist 0 -1
1) "mem"
2) "ls"
3) "ll"
4) "2"
5) "1"
127.0.0.1:6379>
實戰場景:
1.timeline:例如微博的時間軸,有人發布微博,用lpush加入時間軸,展示新的列表信息。
?
4.Set? ?集合
集合類型也是用來保存多個字符串的元素,但和列表不同的是集合中? 1. 不允許有重復的元素,2.集合中的元素是無序的,不能通過索引下標獲取元素,3.支持集合間的操作,可以取多個集合取交集、并集、差集。
?
?
使用:命令都是以s開頭的? sset 、srem、scard、smembers、sismember
?
127.0.0.1:6379> sadd myset hao hao1 xiaohao hao
(integer) 3
127.0.0.1:6379> SMEMBERS myset
1) "xiaohao"
2) "hao1"
3) "hao"
127.0.0.1:6379> SISMEMBER myset hao
(integer) 1
實戰場景;
1.標簽(tag),給用戶添加標簽,或者用戶給消息添加標簽,這樣有同一標簽或者類似標簽的可以給推薦關注的事或者關注的人。
2.點贊,或點踩,收藏等,可以放到set中實現
?
5.zset? 有序集合
有序集合和集合有著必然的聯系,保留了集合不能有重復成員的特性,區別是,有序集合中的元素是可以排序的,它給每個元素設置一個分數,作為排序的依據。
(有序集合中的元素不可以重復,但是score 分數 可以重復,就和一個班里的同學學號不能重復,但考試成績可以相同)。
?
使用:有序集合的命令都是 以? z ?開頭? ? zadd 、 zrange、 zscore
?
127.0.0.1:6379> zadd myscoreset 100 hao 90 xiaohao
(integer) 2
127.0.0.1:6379> ZRANGE myscoreset 0 -1
1) "xiaohao"
2) "hao"
127.0.0.1:6379> ZSCORE myscoreset hao
"100"
實戰場景:
1.排行榜:有序集合經典使用場景。例如游戲的每日排行,周排行榜,以及一個系統模塊,玩法的排行榜,榜單可以按照用戶的分數,更新時間等做權重,做排行。