java開發技術之Redis型別技能入門篇
字串
首先Redis資料儲存都會以key value 的形式進行存放, 所有的key都是字串型別。此處所說的型別特指的是value中存放的型別。下文所講的hash、列表都是基於value上進行講解的。Redis會根據傳入字串型別規則進行判斷,java培訓並採取相應的內部編碼進行儲存。數值型會採用8個位元組的長整型進行編碼儲存,小於等於39個位元組的字串採用emstr編碼儲存,大於39位元組的字串採用raw編碼儲存。如果需要檢視該鍵對應值的儲存型別可執行object encoding k1命令。
- 常用寫命令
1// 1. 設定鍵:k1 值 v1
2set k1 v1
3// 2. 與上一個set k1 v1 命令一致,且k1的失效時間為10s
4set k1 v1 ex 10 nx( k1 不存在才能設定成功) 或 set k1 v1 ex 10 xx ( k1 存在才能設定成功 )
5**** k1 不存在才能設定成功的 另一種寫法
6setnx k1 v1
7**** 設定k1 失效時間的另一種寫法
8setex k1 10 v1
9// 3. 批量設定鍵值
10mset k1 v1 k2 v2 k3 v3
11// 4. 對k1中的數值進行自增操作,如果k1中的值型別不為數值型別將會返回錯誤,如果不存在鍵k1,會按照初始值0進行自增
12incr k1
13// 5. 對k1中的值按2的長度進行自增操作。
14incrby k1 2
- 常用讀命令
1// 1. 獲取鍵 k1 的 值
2get k1
3// 2. 批量獲取 k1,k2,k3 的值
4mget k1 k2 k3 k4
注意:key一般我們都會採用業務名:物件名:屬性名的方式進行命名。
雜湊
雜湊型別在Redis中value是以{{key,value},{key,value}}的形式儲存,我們通過字元和雜湊型別的儲存模型圖來更直觀的認識它們兩者之間的關係,如圖1-1
圖1-1
Redis對於雜湊型別的儲存會根據雜湊型別個數(對應圖中的field個數)採取不同編碼進行儲存。如果雜湊型別個數小於hash-max-ziplist-entries(預設512個)且所有值的(對應圖中的value)儲存大小都小於hash-max-ziplist-value
當無法滿足ziplist條件的時候會採用hashtable編碼方式進行儲存。因為在節省記憶體方面ziplist比hashtable更優秀,但如果資料量上來後檢索效率不及hashtable。
- 常用寫命令
1// 1. 給regsiter:user:1 新增一對field:value
2hset register:user:1 name zhangmj
3//2. 給register:user:1 field(age)的value 增加2
4hincrby register:user:1 age 2
5//3. 批量給regist:user:1 設定多個field-value
6hmset register:user:1 name 'zhangmoujiang' age 12
7//4. 刪除 register:user:1 的name
8hdel register:user:1 name
- 常用讀命令
1// 1. 獲取 register:user:1 的name的value
2hget register:user:1 name
3// 2. 批量獲取 register:user:1 多個field的value
4hmget register:user:1 name age
5// 3. 獲取 register:user:1對應所有field
6hkeys register:user:1
7// 4. 獲取 register:user:1 對應所有field的value
8hvals register:user:1
9// 5. 獲取 register:user:1 所有 field 和value
10hgetall register:user:1
列表
Redis中列表型別的儲存模型如圖1-2:
圖1-2
列表型別中value最多的儲存元素為2^32-1個,可重複。value元素的內部編碼根據元素個數和大小會採取ziplist和linkedlist兩種編碼方式進行儲存。當value元素個數小於list-max-ziplist-entries(預設512),同時value中每個元素的大小小於list-max-ziplist-value(64位元組)會採取ziplist進行編碼。
當無法滿足ziplist的條件會採取linkedlist編碼。ziplist編碼對資料進行壓縮以減少記憶體,而linkedlist採用連結串列的資料結構來儲存資料。據說Redis3.2 版本之後提供了一個更合理的內部編碼 quicklist,它結合ziplist和linkedlist兩者的優勢。
- 常用寫命令
為了行文方便 對於從左往右我們用此圖示進行標記:➡️, 從右往左用此圖示標記⬅️,列表都特指user:1:message
1//1. ⬅️給列表插入元素
2rpush user:1:message 'piaoliang' '帥氣'
3//2. ⬅️給列表插入元素
4lpush user:1:message 'xx1' 'xx2'
5//3. 在元素xx2 之前插入 xx1.5
6linsert user:1:message before 'xx2' 'xx1.5'
7//4. 在元素xx2 之後插入 xx3
8linsert user:1:message after 'xx2' 'xx3'
9//5. 從列表左側彈出元素
10lpop user:1:message
11//6. 從列表右側彈出元素
12rpop user:1:message
13//7. 從左側彈出元素,如果列表不為空立即彈出,如果列表為空將阻塞3s後返回。該命令的基本格式:blpop key [key] timeout ,如果當timeout設為0且列表為空時,客戶端執行此命令將會一致阻塞等待下去。如果設定了多個key,只要有一個key列表中有元素會立即返回
14blpop user:1:message 3
15//8. 同brpop 只不過是 從右側彈出元素
16brpop user:1:message 3
17
18
19// 9. 從左往右刪除列表中等於xx2的2個元素
20// 該命令的基本格式為:lrem key count vlaue
21// 其中 count > 0 會從左往右刪除count個等於value的元素
22// count < 0 則會從右往左刪除count個等於value的元素
23// count =0 則會刪除列表中所有等於value的元素
24lrem user:1:message 2 xx2
25// 10. 保留列表中第2個元素和第4個元素,其他全刪除
26ltrim user:1:message 1 3
27// 11. 將列表中的第1個元素修改為xxx0
28lset user:1:message 0 xxx0
- 常用讀命令
1//1. ➡️ 獲取 第1個和第2個元素。
2lrange user:1:message 0 1
3//2. ⬅️獲取第1個和第2個元素
4// 假設列表元素為 g,f,h,k ,那麼會獲取 h,k 的元素
5lrange user:1:message -1 -2
6//3. 獲取列表中從右邊數,第1個元素
7lindex user:1:message -1
8//4. 獲取user:1:message列表元素的長度
9llen user:1:message
10// 其中➡️列表元素索引下標 [0,N-1] , ⬅️列表元素索引下標:【-1,-N】N 為列表元素個數
- 應用場景
- 通過lpush + brpop 命令 實現訊息佇列。
- 每個使用者都有屬於自己的文章列表,需要分頁顯示各個使用者的文章列表。
集合
集合型別的元素是可以重複的,如圖1-3為集合型別的儲存模型圖:
圖1-3
集合型別的內部編碼有兩種:
- intset, 當集合型別為整數且數量小於set-max-inset-entries(預設512),會採取該編碼方式
- 當無法滿足intset編碼的條件會採取hashtable
- 常用的寫命令
1// 1.新增tag1 、tag2 元素
2sadd user:1 tag1 tag2
3// 2.刪除tag2 元素,返回刪除成功的個數
4srem user:1 tag2
5// 3.從集合中隨機彈出一個元素 / 從集合 隨機彈出 n 個元素
6spop user:1
7// 4. 將集合【user:1】和【user:2】交集結果存放到destination
8sinterstore destination user:1 user:2
9// 5. 集合【user:1】 和 集合【user:2】並集結果存放到destination
10sunionstore destination user:1 user:2
11// 6. 集合【user:1】 和 集合【user:2】差集結果存放到destination
12sdiffstore destination user:1 user:2
- 常用的讀命令
1// 1.計算元素個數
2scard user:1
3// 2.集合中是否存在tag3元素
4sismember user:1 tag3
5// 3.從集合隨機返回一個元素 / 從集合隨機返回2個元素
6srandmember user:1 / srandmember user:1 2
7// 4.獲取集合中的所有元素,返回的結果是無序的
8smembers user:1
9
10// 5.求 集合【user:1】 和 集合【user:2】的交集
11sinter user:1 user:2
12// 6.求 集合【user:1】 和 集合【user:2】的並集
13sunion user:1 user:2
14// 7.求集合間的差集,即:user:2 集合的元素不在user:1中
15sdiff user:2 user:1
注意:當集合的元素過多的時候,使用smembers命令會有損效能,建議使用sscan命令來完成。
有序集合
有序集合型別的儲存模型如圖1-4:
圖1-4
它可以類比集合型別和雜湊型別的組合,其中value中包含兩個主要的欄位score和member,member中元素的值不能夠重複,而score中元素的型別為整型值能夠重複。通過score中元素的值我們能夠對member中的元素進行排序。
內部也採用了兩種編碼:
- ziplist (壓縮列表)
- skiplist (跳躍表)
- 寫操作命令
1// 1. 新增集合成員 ,(85 、 zmj)
2zadd users 85 zmj
3// 2. 新增集合成員 ,存在才能設定成功
4zadd users XX 87 zhangmoujiang
5// 3. 新增集合成員,不存在才能設定成功
6zadd users NX 87 zhangmoujiang
7// 4. 刪除集合內成員 caonimei
8zrem users caonimei
9// 5. 給成員xunini增加 1分,如果沒有成員會自動新增
10zincrby users 1 xuxnini
- 讀操作命令
1// 1. 獲取集合內成員數量
2zcard users
3// 2. 獲取集合內zmj成員的分數
4zscore users zmj
5// 3. 獲取集合內chenxiongshun成員分數的排名(分數從低到高)
6zrank users chenxiongshun
7// 4. 同zrank一樣 (分數從高到低)
8zrevrank users chenxiongshun
9// 5. 返回指定排名的範圍的成員(分數從低到高)
10zrange users 0 2 [withscores]
11// 6. 同zrange一樣 (分數從高到低)
12zrevrange users 0 1 [withscores]
13// 7. 按照指定分數從低到高返回成員
14// 基本格式 zrangebyscore key min max [withscores] [limit offset count]
15zrangebyscore users 50 90
16// 8. 返回指定分數的範圍內的成員個數
17zcount users 0 100
幾個管理鍵的常用命令
1//1. 當前資料庫的鍵數量
2dbsize
3//2. 隨機返回當前資料的一個鍵
4randomkey
5//3. 設定鍵key1 20 秒過期,如果鍵不存在返回結果為0。某個鍵設定了過期時間,然後執行了set命令,那麼該鍵的過期時間會被清除。
6expire key1 20
7//4. 檢視key1鍵還剩幾秒過去,返回數字的單位為秒。返回-2 表示已過期
8ttl key1
9//5. 移除鍵key1的過期時間
10persisit key1
11//6. 獲取所有鍵,keys後面可接類正則的表示式來匹配鍵的名稱
12keys *
13//7. 選擇0號資料庫,redis中預設有16個數據庫 ,編號從0開始...
14select 0
15//8. 清除當前資料庫資料
16flushdb
17//9. 清除所有資料庫資料
18flushall