Redis系列(二):Redis的資料型別及命令操作
Redis 中常用命令
Redis 官方的文件是英文版的,當然網上也有大量的中文翻譯版,例如:Redis 命令參考。這裡只列舉常用到幾個基本命令。
命令 | 行為 |
---|---|
set key value | 設定 key 值為 value |
get key | 讀取 key 的值 |
del key | 刪除 key |
expire key seconds | 設定 key 的生存時間(seconds 秒後自動刪除) |
ttl key | 檢視 key 剩餘生存時間 |
exists key | 判斷 key 是否存在 |
ping | 測試與服務端是否聯通 |
keys * | 匹配資料庫中所有 key |
dbsize | 查詢當前資料庫中 key 的數量 |
info | 返回關於 Redis 伺服器的各種資訊和統計數值 |
flushdb | 清空當前資料庫中的所有 key |
flushall | 清空整個 Redis 伺服器的資料( 刪除所有資料庫的所有 key ) |
quit | 請求伺服器關閉與當前客戶端的連線( 斷開連線 ) |
Redis資料型別簡介
資料型別 | 儲存的值 | 讀寫能力 |
---|---|---|
String | 字串,整數或浮點數 | 對字串或一部分字串執行操作;對整數進行自增和自減操作等 |
Hash | 包含鍵值對的無序散列表 | 對單個 元素進行增、刪、改;獲取所以的鍵值對等 |
List | 連結串列上的節點字串元素 | 推入、彈出元素;修剪、查詢、移除元素等 |
Set | 各不相同的字串元素 | 對單個 元素進行增、刪、改;計算集合 交,並補集等 |
Sorted Set | 帶分數的有序集合 | 對單個 元素進行增、刪、改;按照分數範圍查元素等 |
字串型別(String)
redis string 介紹
雖然 redis 是用 C 編寫的,但是在 redis 中沒有使用 C 語言的字串,而是自定義了一個數據結構叫 SDS (simple dynamic string) ——簡單動態字串。是可以修改的,類似java中的 ArrayList。同時它也不像 C 中的字串那樣遇到 \0
字元就認為字串結束,他不會對儲存進去的字串資料進行任何處理,因此 redis 中的字串也是二進位制安全的。
redis 的 string 型別可以包含任意資料,包括圖片等二進位制或者序列化的物件等。單個 value
的值最大上限為 1G
位元組。
純字串操作命令
注:#
後面是命令的註釋,不可執行
127.0.0.1:6379> set key1 'hello redis' # 存值
OK
127.0.0.1:6379> get key1 # 取值
"hello redis"
127.0.0.1:6379> getset key1 redis # 將給定key1的值設為redis,並返回key1的舊值(old value)
"hello redis"
127.0.0.1:6379> get key1
"redis"
127.0.0.1:6379> del key1 # 刪除 key1
(integer) 1
整數自增自減操作命令
127.0.0.1:6379> set key2 10 # 存入一個值為10的整數字符串
OK
127.0.0.1:6379> incr key2 # 自增
(integer) 11
127.0.0.1:6379> incr key2 # 自增
(integer) 12
127.0.0.1:6379> incrby key2 5 # 自增指定數值 -- 5
(integer) 17
127.0.0.1:6379> decr key2 # 自減
(integer) 16
127.0.0.1:6379> decr key2 # 自減
(integer) 15
127.0.0.1:6379> decrby key2 5 # 自減指定數值 -- 5
(integer) 10
其他命令
127.0.0.1:6379> set key1 redis
OK
127.0.0.1:6379> append key1 hello # 將 hello 追加到 key1 原來的值的末尾,放回追加後字串長度
(integer) 10
127.0.0.1:6379> get key1
"redishello"
127.0.0.1:6379> strlen key1 # 返回 key1 所儲存的字串值的長度
(integer) 10
127.0.0.1:6379> mset key1 v1 key2 v2 key3 v3 # 批量同時設定一個或多個 key-value 對
OK
127.0.0.1:6379> mget key1 key2 key3 # 返回所有(一個或多個)給定 key 的值
1) "v1"
2) "v2"
3) "v3"
應用場景
- 商品編號,訂單號採用string 的遞增數字特性生成
雜湊型別(Hash)
redis hash介紹
hash 叫雜湊型別。等價於Java 中的 HashMap。但是在 redis 中 hash 的 key 必須是 string 型別。不支援其他型別。這個特性非常適合儲存物件。因為一個物件可以有很多屬性,儲存起來就是鍵值對形式的。在 Reids 中,每個 Hash 可以儲存多達 4 億個鍵值對。
相關操作命令
127.0.0.1:6379> hset user name zhangsan # 使用 hset 為 user 新增一個鍵值對 name = zhangsan
(integer) 1
127.0.0.1:6379> hset user age 18 # 使用 hset 為 user 新增一個鍵值對 age = 18
(integer) 1
127.0.0.1:6379> hget user name # 使用 hget 獲取 user 中鍵為 name 的值
"zhangsan"
127.0.0.1:6379> hget user age # 使用 hget 獲取 user 中鍵為 age 的值
"18"
127.0.0.1:6379> hgetall user # 使用 hgetall 獲取 user 中所有的鍵值對
1) "name"
2) "zhangsan"
3) "age"
4) "18"
127.0.0.1:6379> hmset user name lisi age 20 # 使用 hmset 為 user 批量新增鍵值對
OK
127.0.0.1:6379> hmget user name age # 使用 hmget 批量獲取 user 中鍵的值
1) "lisi"
2) "20"
127.0.0.1:6379> hdel user name# 使用 hdel 刪除 user 一個(或多個)鍵值對
(integer) 1
127.0.0.1:6379> hexists user name # 使用 hexists 判斷 user 中 name 元素是否存在
(integer) 0
127.0.0.1:6379> hexists user age # 使用 hexists user 中 age 元素是否存在
(integer) 1
127.0.0.1:6379> hkeys user # 使用 hkeys 只獲得 user 中的欄位名
1) "age"
127.0.0.1:6379> hvals user # 使用 hvals 只獲得 user 中的欄位值
1) "20"
127.0.0.1:6379> hlen user # 使用 hlen 獲得 user 中欄位(鍵值對)數量
(integer) 1
其他特性
Redis 中的 Hash 結構有擴容
和縮容
特性,擴容主要應用在當 hash 內部比較擁擠的時候,容易產生 hash 碰撞,這時需要擴容 hash 。申請新的兩倍大小的陣列;而縮容與擴容恰恰相反,雖然原理一樣,但是申請的新陣列要比舊的小一倍。
應用場景
- 儲存大量的物件資料
列表型別(List)
redis list介紹
在 java 中,列表型別有兩種,一種是 ArrayList,實現方式是陣列
,所以根據索引查詢資料速度快,而插入或者刪除某個元素涉及到位移操作,會比較慢;另一種是 LinkedList,實現方式是雙向連結串列(double linked list)
,每個元素都記錄著前後元素的指標。所以在插入或刪除某個元素時只需要更改該元素的前後指標指向就行,非常快,但是在查詢上需要從頭索引,特別是當資料量大的時候,索引起來還是比較慢的。
在 Redis 中的 List 型別,其內部使用的是雙向連結串列
實現的,所以它具有雙向連結串列具有的相關特性。其常用操作就是向列表兩端新增或刪除元素。這使得 List 既可以當做棧(先進後出)
來使用,也可以當做佇列(先進先出)
來使用。
相關操作命令
127.0.0.1:6379> lpush list 1 2 3 4 # 使用 lpush 將 1 2 3 4 依次插入到 list 的左端
(integer) 4
127.0.0.1:6379> rpush list 5 6 7 8 # 使用 rpush 將 5 6 7 8 依次插入到 list 的右端
(integer) 8
127.0.0.1:6379> lrange list 0 -1 # 使用 lrange 獲取 指定區間上所有值(0 -1 表示獲取全部)
1) "4"
2) "3"
3) "2"
4) "1"
5) "5"
6) "6"
7) "7"
8) "8"
127.0.0.1:6379> lpop list # 使用 lpop 彈出 list 左端的一個值,並返回彈出的值
"4"
127.0.0.1:6379> lpop list
"3"
127.0.0.1:6379> rpop list # 使用 rpop 彈出 list 右端的一個值,並返回彈出的值
"8"
127.0.0.1:6379> rpop list
"7"
127.0.0.1:6379> lrange list 0 -1
1) "2"
2) "1"
3) "5"
4) "6"
127.0.0.1:6379> llen list # 使用 llen 獲取 list 中元素個數
(integer) 4
應用場景
- 商品,部落格,文章下面的評論列表。
集合型別(Set)
redis set 介紹
redis 中的 set 型別和 java 中的 HashSet 類似,其底層都是用HashMap 實現的,只不過所有的 value 都指向同一個物件。在 set 中,沒有重複的元素。並且沒有順序。其常用的操作就是向集合中加入或刪除一個元素、判斷某個元素是否在集合中。另外 redis 還提供了多個集合之間的 交集、並集、差集的運算。
相關操作命令
127.0.0.1:6379> sadd set a b c 1 2 3 # 使用 sadd 將 a b c 1 2 3 新增到 set 集合中
(integer) 6
127.0.0.1:6379> sadd set a b 2 # 新增重複元素,返回成功新增 0 個,說明 set 中元素不重複
(integer) 0
127.0.0.1:6379> srem set a b 1 # 使用 srem 刪除 set 集合中的 a b 1 三個元素
(integer) 3
127.0.0.1:6379> smembers set # 使用 smembers 獲取 set 集合中所以元素
1) "2"
2) "c"
3) "3"
127.0.0.1:6379> sismember set a # 使用 sismember 判斷 a 是否在 set 集合中
(integer) 0
127.0.0.1:6379> sismember set c # 使用 sismember 判斷 c 是否在 set 集合中
(integer) 1
集合間的相關運算
集合的並集運算 A ∪ B
127.0.0.1:6379> sadd seta 1 2 3
(integer) 3
127.0.0.1:6379> sadd setb 3 4 5
(integer) 3
127.0.0.1:6379> sunion seta setb # 使用 sunion 計算 seta 和 setb 的並集
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
集合的交集運算 A ∩ B
127.0.0.1:6379> sadd seta 1 2 3
(integer) 3
127.0.0.1:6379> sadd setb 3 4 5
(integer) 3
127.0.0.1:6379> sinter seta setb # 使用 sinter 計算 seta 和 setb 的交集
1) "3"
集合的差集運算 A - B
127.0.0.1:6379> sadd seta 1 2 3
(integer) 3
127.0.0.1:6379> sadd setb 3 4 5
(integer) 3
127.0.0.1:6379> sdiff seta setb # 使用 sdiff 計算 seta - setb (屬於seta 但不屬於 setb)
1) "1"
2) "2"
127.0.0.1:6379> sdiff setb seta # 使用 sdiff 計算 setb - setb (屬於setb 但不屬於 seta)
1) "4"
2) "5"
有序集合型別 (sorted set)
redis sorted set介紹
SortedSet(zset)
是 redis 提供的一個非常特別的資料結構,它在集合的基礎上為每一個元素都關聯了一個分數,這相當於 java 中的 Map<String,Double>
,可以給每一個元素賦予一個score
權重。另一方面又像TreeSet
,內部的元素會按照權重score
進行排序。
相關操作命令
127.0.0.1:6379> zadd board 81 java 75 python 90 c++ # 使用 zadd 增加一到多個value/score對,score 放在前面
(integer) 3
127.0.0.1:6379> zscore board java # 使用 zscore 獲取 java 的 score
"81"
127.0.0.1:6379> zrange board 0 -1 # 使用 zrange 獲取指定區間(0 -1 表示全部)上的降序排名
1) "python"
2) "java"
3) "c++"
127.0.0.1:6379> zrange board 0 -1 withscores # 帶上 winthscores 可以一併獲取元素的 score
1) "python"
2) "75"
3) "java"
4) "81"
5) "c++"
6) "90"
127.0.0.1:6379> zrevrange board 0 -1 withscores # 使用 zrevrange 獲取指定區間(0 -1 表示全部)上的升序排名
1) "c++"
2) "90"
3) "java"
4) "81"
5) "python"
6) "75"
127.0.0.1:6379> zrangebyscore board -inf +inf withscores # 使用 zrangebyscore 獲取 負無窮(-inf)到 正無窮(+inf)區間上所以元素的降序排名
1) "python"
2) "75"
3) "java"
4) "81"
5) "c++"
6) "90"
127.0.0.1:6379> zrevrangebyscore board +inf -inf withscores # 使用 zrevrangebyscore 獲取正無窮(+inf)到 負無窮(-inf)區間上所以元素的升序排名
1) "c++"
2) "90"
3) "java"
4) "81"
5) "python"
6) "75"
127.0.0.1:6379> zcard board # 使用 zcard 計算 board 集合的元素個數
(integer) 3
127.0.0.1:6379> zrem board java python # 使用 zrem 刪除 board 集合中的一個或多個元素
(integer) 2
應用場景
- 商品銷售,軟體下載等各種排行榜