1. 程式人生 > >Redis 實戰 —— 04. Redis 資料結構常用命令簡介

Redis 實戰 —— 04. Redis 資料結構常用命令簡介

#### 字串 `P39` Redis 的字串是一個有位元組組成的序列,可以儲存以下 3 種類型的值:位元組串(byte string)、整數、浮點數。 在需要的時候, Redis 會將整數轉換成浮點數。整數的取值範圍和系統的長整型(long)的相同,浮點數取值範圍和精度與 IEEE 754 標準下的雙精度浮點數(double)的相同。 ##### Redis 中的自增命令和自減命令 `P39` | 命令 | 格式 | 描述 | | ----------- | ------------------------- | ---------------------------------------- | | INCR | INCR key | 將鍵儲存的數字值加上 1 | | DECR | DECR key | 將鍵儲存的數字值減去 1 | | INCRBY | INCRBY key increment | 將鍵儲存的數字值加上整數增量 increment | | DECRBY | DECRBY key decrement | 將鍵儲存的數字值減去整數減量 decrement | | INCRBYFLOAT | INCRBYFLOAT key increment | 將鍵儲存的數字值加上浮點數增量 increment | 相關演示程式碼如下(`main` 及 `handleResult` 定義見:[01. Redis 資料結構簡介](https://mp.weixin.qq.com/s/vUsOfARXsM8H1ts6mC5tmA)): ```go // 執行字串型別數字相關操作 func executeNumberOperation(conn redis.Conn) { // 刪除原有值 handleResult(redis.Int(conn.Do("DEL", "number"))) // 獲取值,輸出 -> ERROR: redigo: nil returned handleResult(redis.Int(conn.Do("GET", "number"))) // 自增 1,返回自增後的值 -> 1 handleResult(redis.Int(conn.Do("INCR", "number"))) // 自增 2,返回自增後的值 -> 3 handleResult(redis.Int(conn.Do("INCRBY", "number", "2"))) // 自減 1,返回自減後的值 -> 2 handleResult(redis.Int(conn.Do("DECR", "number"))) // 自減 2,返回自減後的值 -> 0 handleResult(redis.Int(conn.Do("DECRBY", "number", "2"))) // 自增 1.5,返回自增後的值 -> 1.5 handleResult(redis.Float64(conn.Do("INCRBYFLOAT", "number", "1.5"))) // 自增 -1.3,返回自增後的值 -> 0.2 handleResult(redis.Float64(conn.Do("INCRBYFLOAT", "number", "-1.3"))) } ``` ##### 供 Redis 處理子串和二進位制位的命令 `P40` | 命令 | 格式 | 描述 | | -------- | ------------------------------------- | ------------------------------------------------------------ | | APPEND | APPEND key value | 將 value 追加到 key 當前值的末尾 | | GETRANGE | GETRANGE key start end | 返回 [start, end] 範圍內子串 | | SETRANGE | SETRANGE key offset value | 將子串 [offset, offset + len(value)) 設定為 value | | GETBIT | GETBIT key offset | 將字串看作是二進位制位串,獲取 offset 上的位 | | SETBIT | SETBIT key offset value | 將字串看作是二進位制位串,設定 offset 上的位為 value | | BITCOUNT | BITCOUNT key [start end] | 統計 [start, end] 範圍內子串在二進位制下有多少個 1 | | BITOP | BITOP operation destkey key [key ...] | operation 可選位運算 AND , OR , XOR , NOT ,將一個或多個二進位制位串執行的操作結果存到 destkey 中 | 相關演示程式碼如下: ```go // 執行字串型別字串相關操作 func executeStringOperation(conn redis.Conn) { // 刪除原有值 handleResult(redis.Int(conn.Do("DEL", "string"))) // 追加串,返回當前字串長度 -> 6,值變為 -> append handleResult(redis.Int(conn.Do("APPEND", "string", "append"))) // 獲取子串,返回 -> en handleResult(redis.String(conn.Do("GETRANGE", "string", 3, 4))) // 設定子串,返回當前字串長度 -> 6,值變為 -> appled handleResult(redis.Int(conn.Do("SETRANGE", "string", 3, "le"))) // 設定子串,返回當前字串長度 -> 11,值變為 -> application handleResult(redis.Int(conn.Do("SETRANGE", "string", 3, "lication"))) // 獲取二進位制位,返回 -> 1 // (獲取第 7/8 個字元 a 在二進位制下第 7%8 位上的二進位制位,即 0110 0001 的第 7 位 1) handleResult(redis.Int(conn.Do("GETBIT", "string", 7))) // 設定二進位制位,返回原來的二進位制位 -> 0,值變為 -> cpplication // (設定第 6/8 個字元 a 在二進位制下第 6%8 位上的二進位制位為1,即 0110 0001 變為 0110 0011) handleResult(redis.Int(conn.Do("SETBIT", "string", 6, 1))) // 統計二進位制位,返回 -> 7 // (統計 [0, 1] 範圍內子串 cp 在二進位制下 0110 0011 0111 0000 二進位制位為 1 的數量) handleResult(redis.Int(conn.Do("BITCOUNT", "string", 0, 1))) handleResult(redis.String(conn.Do("SET", "aKey", "aa"))) handleResult(redis.String(conn.Do("SET", "bKey", "b"))) // 對 aa(0110 0001 0110 0001) 和 b(0110 0010 0000 0000) 進行 按位或,結果儲存到 cKey 中 // 返回字串長度 -> 2,值為 ca(0110 0011 0110 0001), handleResult(redis.Int(conn.Do("BITOP", "OR", "cKey", "aKey", "bKey"))) } ``` Redis 可以通過使用子串操作和二進位制位操作,配合 `WATCH` 、`MULTI` 和 `EXEC` 命令(後面會初步介紹,以後將深入講解),構建任何想要的資料結構。 #### 列表 `P42` ##### 一些常用的列表命令 `P42` | 命令 | 格式 | 描述 | | ------ | --------------------------- | ---------------------------------------------- | | RPUSH | RPUSH key value [value ...] | 依次將一個或多個 value 從列表右端插入 | | LPUSH | LPUSH key value [value ...] | 依次將一個或多個 value 從列表左端插入 | | RPOP | RPOP key | 移除並返回列表最右端的元素 | | LPOP | LPOP key | 移除並返回列表最左端的元素 | | LINDEX | LINDEX key offset | 返回列表左端開始偏移量為 offset 的元素 | | LRANGE | LRANGE key start end | 返回列表左端開始 [start, end] 範圍內的所有元素 | | LTRIM | LTRIM key start end | 移除列表左端開始 [start, end] 範圍外的所有元素 | 相關演示程式碼如下: ```go // 執行列表型別相關操作 func executeListOperation(conn redis.Conn) { // 刪除原有值 handleResult(redis.Int(conn.Do("DEL", "list"))) // 右端插入一次插入 a, b, c,返回當前列表長度 -> 3,列表變為 -> a b c handleResult(redis.Int(conn.Do("RPUSH", "list", "a", "b", "c"))) // 左端插入一次插入 d, e, f,返回當前列表長度 -> 6,列表變為 -> f e d a b c handleResult(redis.Int(conn.Do("LPUSH", "list", "d", "e", "f"))) // 彈出並返回列表最右端的值,返回 -> c,列表變為 -> f e d a b handleResult(redis.String(conn.Do("RPOP", "list"))) // 彈出並返回列表最左端的值,返回 -> f,列表變為 -> e d a b handleResult(redis.String(conn.Do("LPOP", "list"))) // 返回左端開始下標偏移量為 offset 的值,返回 -> d handleResult(redis.String(conn.Do("LINDEX", "list", 1))) // 移除列表左端開始 [1, 2] 範圍外的所有元素,列表變為 -> d a handleResult(redis.String(conn.Do("LTRIM", "list", 1, 2))) } ``` 利用 `LTRIM` 命令可以原子地彈出多個元素。 `P43` ##### 阻塞式的列表彈出命令以及在列表之間移動元素的命令 `P43` | 命令 | 格式 | 描述 | | ---------- | ------------------------------------- | ------------------------------------------------------------ | | BLPOP | BLPOP key [key ...] timeout | 從第一個非空列表中彈出最左端的元素,或者在 timeout 秒內阻塞並等待可彈出的元素出現,返回被彈出的列表名及元素, timeout 為 0 表示無限等待 | | BRPOP | BRPOP key [key ...] timeout | 從第一個非空列表中彈出最右端的元素,或者在 timeout 秒內阻塞並等待可彈出的元素出現,返回被彈出的列表名及元素, timeout 為 0 表示無限等待 | | RPOPLPUSH | RPOPLPUSH source destination | 從 source 列表中彈出最右端的元素,然後將這個元素退出 destination 列表的最左端,並返回這個元素 | | BRPOPLPUSH | BRPOPLPUSH source destination timeout | 從 source 列表中彈出最右端的元素,然後將這個元素退出 destination 列表的最左端,並返回這個元素;如果 source 列表為空,則在 timeout 秒內阻塞並等待可彈出元素出現 | 相關演示程式碼如下: ```go // 執行列表型別阻塞相關操作 func executeListBlockOperation(conn redis.Conn) { // 刪除原有值 handleResult(redis.Int(conn.Do("DEL", "source", "destination"))) // 從第一個非空列表中彈出並返回列表最左端的值,最多等待 1秒,輸出 -> ERROR: redigo: nil returned handleResult(redis.Strings(conn.Do("BLPOP", "source", "destination", 1))) // 初始化 handleResult(redis.Int(conn.Do("RPUSH", "source", "a", "b", "c"))) handleResult(redis.Int(conn.Do("RPUSH", "destination", "d", "e", "f"))) // 從第一個非空列表中彈出並返回列表最左端的值,無限等待,返回 -> a,source 變為 -> b c,destination 變為 -> d e f handleResult(redis.Strings(conn.Do("BLPOP", "source", "destination", 0))) // 從第一個非空列表中彈出並返回列表最右端的值,無限等待,返回 -> f,source 變為 -> b c,destination 變為 -> d e handleResult(redis.Strings(conn.Do("BRPOP", "destination", "source", 0))) // 從 source 彈出最右端元素,然後推入到 destination 最左端,並返回這個元素 // 返回 -> c,source 變為 -> b,destination 變為 -> c d e handleResult(redis.String(conn.Do("RPOPLPUSH", "source", "destination"))) // 從 source 彈出最右端元素,然後推入到 destination 最左端,並返回這個元素,無限等待 // 返回 -> b,source 變