# 六角鼠年鐵人賽 Week 21 - Spring Boot - Redis 資料結構介紹 ==大家好,我是 "為了拿到金角獎盃而努力著" 的文毅青年 - Kai== ## Jerry Sloan :::info Hopefully this gives us some confidence to try to get better. That's the biggest thing. ::: ## 主題 上週已經介紹了安裝與環境設定的變數,這週就來學學 Redis 提供的五種資料結構的操作指令。 如同操作 RDBMS 一樣,我們會送許多指令到 Redis 執行,因此對於這些指令能夠有所了解是一件重要的事情,當然這不是說要你背下來,而是你必須知道有這些事務可以操作,詳細的方法再查教學文件即可。 ## Key Redis 是一個 Key-Value 形式的 NoSQL,因此除了資料結構外,最重要的便是針對 Key 的操作。 Redis 提供以下操作方法: | 指令 | 描述 | 備註 | | ---- | ---- | ---- | | SET [keyName] [keyValue] | 設定一個 Key-Value | 根據資料結構的不同,有可能用不同的 Set 指令,例如: Hash 使用 HMSET 的指令 | | DEL [keyName] | 刪除一個存在的 Key | 若不存在則不做任何動作 | | DUMP [keyName] | 返回該 Key 的序列化 Value || | EXISTS [keyName] | 檢查該 Key 是否存在 || | EXPIRE [keyName] [seconds] | 設定該 Key 的有效時間 | 單位為秒;返回 0 or 1;0 表示 Key 不存在或未超時;1 表示該 Key 存在且超時 | | EXPIRE [keyName] [timeStamp] | 設定該 Key 的有效時間 | Unix時間戳格式;其餘與上述效果一樣 | | PEXPIRE [keyName] [milliSeconds] | 設定該 Key 的有效時間 | 單位為毫秒 | | PEXPIRE [keyName] [milliSeconds-timeStamp] | 設定該 Key 的有效時間 | Unix毫秒時間戳格式 | | KEYS [pattern] | filter 查詢 Key |例如現在有 test1 "hello world", test2 "hi world", test3 "greeting world" 三筆資料,可以使用 KEYS test* 一次將三筆資料搜索出 | | MOVE [keyName] [DB Number] | 將該 Key 移動到指定 DB 中 | 可以在 redis-cli 使用 SELECT [DB Number] 方式,跳轉到指定 DB | | PERSIST [keyName] | 移除過期的 Key || | PTTL [keyName] | 檢視該 Key 的到期剩餘時間(返回單位為毫秒) | 返回值若為 -1 表示該 Key 尚未到期;-2 表示該 Key 不存在 | | TTL [keyName] | 檢視該 Key 的到齊剩餘時間(返回單位為秒) | 與上述效果一樣 | | RANDOMKEY | 隨機取得一個 Key || | RENAME [keyName] [New Name] | 更動該 Key 名稱 | 若新的 Key Name 已存在,則會覆蓋已存在的 Key Name 的 Value;若 更動前後名稱一樣或原本的 Key 不存在則返回 error | | RENAMENX [keyName] [New Name] | 更動該 Key 名稱 | 若新的 Key Name 已存在則不進行更新,並返回 0;若更動成功則返回 1| | TYPE [keyName] | 返回該 Key 的 Value 的型態| | FLUSHALL | 刪除所有 redis 保存的資料 | 不建議正式環境使用,測試可以常用 | ## String 字串是最常見的資料結構,在 Redis 中並不支援數值類型的資料型態,因此就算輸入的值沒有用雙引號括起來,還是會在儲存的時候被轉為字串儲存。 下列是關於字串的操作指令: | 指令 | 描述 | 備註 | | ---- | ---- | ---- | | SET [keyName] [keyValue] | 設定一個 Key-Value | 無論有無使用雙引號,全部會轉為字串儲存 | | SETBIT [keyName] [offset] [keyValue] | 設置一個 Key-Value,並設定 bit 位置的值為 0 or 1 || | SETEX [keyName] [seconds] [keyValue] | 設置一個 Key-Value,並有到期時間 | 單位為秒 | | PSETEX [keyName] [milliSeconds] [keyValue] | 設置一個 Key-Value,並有到期時間| 單位為毫秒 | | SETNX [keyName] [keyValue] | 設置一個 Key-Value 前會先檢查該 Key 是否存在,若不存在則建立,並返回 1,若存在則不覆蓋,並返回 0 || | SETRANGE [keyName] [start Number] [keyValue] | 使用新值去覆蓋一個 Key 的 Value,會從 start Number 的位置開始覆蓋 | 長度計算從 0 開始| | GET [keyName] | 取得該 Key 的 Value || | GETRANGE [keyName] [start Number] [end Number] | 取得該 Key 從 start Number 到 end Number 位置的值 | 長度計算從 0 開始;若 end Number 為 -1,表示全部取出 | | GETSET [keyName] [keyValue] | 設置該 Key 新的 Value,並同時返回舊 Value | 舊 Value 僅能取得一次,因為已經被覆蓋為新值 | | GETBIT [keyName] [offset] | 取得該 Key 的 bit 位置的值 || | STRLEN [keyName] | 取得該 Key 的 Value 字串長度 || | MSET [keyName1] [keyValue1] [keyName2] [keyValue2]... | 設置多個 Key-Value,若 Key 存在則會將已經存在的 Key 覆蓋 || | MSETNX [keyName1] [keyValue1] [keyName2] [keyValue2]... | 設置多個 Key-Value,當只有 Key 不存在的時候才會建立 || | INCR [keyName] | 當 Value 可以轉為整數數值型態時,進行 +1 的動作 | 限制可為 64位元帶符號整數 | | INCRBY [keyName] [increment] | 當 Value 可以轉為整數數值型態時,進行 +increment 的動作 | 限制可為 64位元帶符號整數 | | INCRBYFLOAT [keyName] [increment] | 當 Value 可以轉為浮點束束值型態時,進行 +increment 的動作 | 限制可為 64位元帶符號浮點數 | | DECR [keyName] | 當 Value 可以轉為整數數值型態時,進行 -1 的動作 | 限制可為 64位元帶符號整數 | | DECRBY [keyName] [decrement] | 當 Value 可以轉為整數數值型態時,進行 -decrement 的動作 | 限制可為 64位元帶符號整數 | | APPEND [keyName] [keyValue] | 串接新的值到該 Key 的尾端 | 並不會針對數值型態做相加的動作 | | SCAN [keyName] [cursor] ["match" pattern] ["count" LimitNumber] | filter 查詢所有 Key 的方式| cursor 可設為 0;若有使用 match 功能,則指令為 match [keyName pattern];若有使用 Limit 功能,則指另為 count [LimitNumber]| > Redis 並沒有提供 DECRBYFLOAT 指令,是因為這個操作可以藉由 INCRBYFLOAT -0.5 的方式達成,同理諸多指令其實可以統一使用 INCR 完成即可 ## Hash Redis 提供關於 Hash 的處理,下方列出相關操作指令: | 指令 | 描述 | 備註 | | ---- | ---- | ---- | | HSET [keyName] [field] [keyValue] | 設置一個 Hash Key,並把值放入 field 內,若 field 已存在,則覆蓋原有 field 的 Value || | HMSET [keyName] [field1] [keyValue1] [field2] [keyValue2] | 設置一個 Hash Key,並設置多個 field 與其 Value,若 field 已存在則會進行覆蓋 || | HSETNX [keyName] [field] [keyValue] | 設置一個 Hash Key,並檢查 field 是否存在,不存在則建立,若存在則不做任何動作 || | HGET [keyName] [field] | 獲取該 Key 中的 field 的 Value|| | HMGET [keyName] [field1] [field2]...| 獲取該 Key 中指定的 field 的 Value|| | HGETALL [keyName] | 獲取該 Key 的所有 field 與 Value || | HDEL [keyName] | 刪除該 Hash Key || | HEXISTS [keyName] [field] | 檢查該 Key 中的 field 是否存在 |返回 1 表示該 field 包含值;返回 0 表示該 field 不包含值或不存在| | HINCBY [keyName] [field] [increment] | 若該 field 中的值可轉為整數數值型態,則進行 +increment 的動作|| | HICRBYFLOAT [keyName] [field] [increment] | 若該 field 中的值可轉為浮點數數值型態,則進行 +increment 的動作 || | HKEYS [keyName] | 獲取該 Key 中所有的 field || | HVALS [keyName] | 獲取該 key 中的所有 Value || | HLEN [keyName] | 獲取該 key 中的 field 數量 || | HSCAN [keyName] [cursor] ["match" pattern] ["count" LimitNumber] | filter 查詢所有 Key 的方式| cursor 可設為 0;若有使用 match 功能,則指令為 match [keyName pattern];若有使用 Limit 功能,則指另為 count [LimitNumber]|| ## List List 是 Redis 中常見的資料結構,我們常會用來儲存各式各樣的一組資料在許多的 List 中,下面是操作指令: | 指令 | 描述 | 備註 | | ---- | ---- | ---- | | LPUSH [keyName] [keyValue1] [keyValue2]... | 將一個或多個新值,從該 key 的首位開始塞入值,意即為最後一個塞入的值將會是該 List 第一筆資料 || | LPUSHX [keyName] [keyValue1] [keyValue2]... | 如上述,僅會在該 Key 存在時進行動作 || | LLEN [keyName] | 取得該 Key 的陣列長度 || | LPOP [keyName] | 取得該 Key 的首位值 || | BLPOP [keyName1] [keyName2]... [seconds] | 當 Key 的陣列為空或者無可以 POP 的值時,進行阻塞讓該 Key 無法被使用,直到有可以 POP 的值或是設定的時間超過為止 | 此動作可以避免輪詢的時候佔用太多資源 | | RPOPLPUSH [keyName] [KeyName2] | 將該 Key 尾端的值 POP 出,並將其值塞入 key2 的首位 || | LINDEX [keyName] [index] | 取得該 Key 的 index 位置的值 || | LINSERT [keyName] BEFORE/AFTER [targetValue] [keyValue] | 針對該 Key 在 targetValue 的前後增加新的值 || | LRANGE [keyName] [start Number] [end Number] | 列出陣列從 start 開始一直到 end 位子的值 | 也可以用 -1 -2 表示從尾端數來的值位子 | | LREM [keyName] [count] [keyValue] | 從首位開始刪除與輸入的 KeyValue 相等的值,當 count > 0 表示從頭的該位數到尾端;count < 0 表示從尾的該位數到首端;0 表示全部 || | LSET [keyName] [index] [keyValue] | 將該 Key 的 index 位置設置新的 value 進去覆蓋 | 若超出原先的陣列長度的位置則會返回錯誤 | | LTRIM [keyName] [start Number] [end Number] | 針對該 Key 從首端開始的 start 到 end 位置的值都將去除 || > 上述 L 開頭的指令通通可以換成 R 開頭,指令的意義即是從首位開始處理的方式變成從尾端開始處理 ## 集合 | 指令 | 描述 | 備註 | | ---- | ---- | ---- | | SADD [keyName] [keyValue1] [keyValue2]... | 增加一個或多個新值進入該集合中|若新值已存在集合中則會覆蓋舊值;若 key 不存在則會自動建立包含新值的集合;若 key 不是集合類的資料結構會返回錯誤| | SISMEMBER [keyName] [value] | 判斷該 Value 是否為該 key 集合中的成員|返回 1 表示是集合成員;返回 0 表示不是集合成員或該 Key 不存在| | SPOP [keyName] | 取得該 key 中隨機一個成員,並且將其在集合中移除|| | SRANDMEMBER [keyName] [count] | 取得該 Key 中隨機 count 數的成員 |當 count > 0 則出現成員不重複; count < 0 則出現成員會有重複| | SREM [keyName] [keyValue1] [keyValue2]... | 移除該集合中指定的 value 成員| 在 Redis 2.4 版本以前,一次只能指定一個 keyValue| | SMOVE [keyName1] [keyName2] [keyValue] | 將 key1 的 value 成員移動到 key2 |返回 1 表示移動成功;返回 0 表示 key1 or key2 不存在或 value 並非 key1 的成員| | SCARD [keyName] | 返回該 Key 集合成員數目 |返回 0 表示沒有資料或是該 key 不存在| | SMEMBERS [keyName] |返回該 Key 集合成員 |空白表示為空集合或該 Key 不存在| | SSCAN [keyName] [cursor] ["match" pattern] ["count" LimitNumber] |filter 查詢所有 集合成員的方式| cursor 可設為 0;若有使用 match 功能,則指令為 match [keyName pattern];若有使用 Limit 功能,則指另為 count [LimitNumber]|| | SINTER [keyName1] [keyName2]...| 返回兩個或兩個以上集合的交集成員 || | SINTERSTORE [keyName1] [keyName2]...| 返回兩個或兩個以上集合的交集成員數量 || | SUNION [keyName1] [keyName2]...|返回兩個或兩個以上集合的聯集成員|| | SUNIONSTORE [keyName1] [keyName2]...|返回兩個或兩個以上集合的聯集成員數量|| | SDIFF [keyName1] [keyName2]...|返回兩個或兩個以上集合的差集的成員|| | SDIFFSTORE [keyName1] [keyName2]...|返回兩個或兩個以上集合的差集的成員數量|| ## 有序集和 | 指令 | 描述 | 備註 | | ---- | ---- | ---- | | ZADD [keyName] [score1] [keyValue1] [score2] [keyValue2]... | 將一個或多個 Value 給予 score 後加入到 key 中| score 可以為整數或雙精度浮點數| | ZSCORE [keyName] [keyValue]| 返回該 value 在 key 中被給予的 score 值| score 值以字串顯示| | ZINCRBY [keyName] [increment] [keyValue] | 將 key 中的該 Value 增加 increment 數的 score || | ZCARD [keyName] | 返回該 key 中的成員數量 || | ZCOUNT [keyName] [min] [max] | 返回該 key 中 score 大於 min 且小於 max 的成員數目|| | ZRANGE [keyName] [start] [stop] ["WITHSCORES"] | 返回該 key 中從 start 位置到 stop 位置的值,若有使用 WITHSCORES 參數則會一併帶出該值的 score|| | ZREVRANGE [keyName] [start] [stop] ["WITHSCORES"] | 與上述效果相同,差別在返回的順序剛好相反|| | ZRANGEBYSCORE [keyName] [min] [max] ["WITHSCORES"] ["LIMIT offset count"] | 返回該 key 中 score 大於 min 且小於 max 的成員,若有使用 WITHSCORES 參數則會一併帶出該值的 score,LIMIT 可以用來控制返回值的數量|min 和 max 可以用 -inf 和 +inf 取代,意即最小無限制和最大無限制,但這樣可能會造成查找資源的使用過多| | ZREVRANGEBYSCORE [keyName] [min] [max] ["WITHSCORES"] ["LIMIT offset count"]| 與上述效果相同,差別在返回的順序剛好相反|| | ZRANK [keyName] [keyValue]| 返回該成員在集合中的排名 | 以 score 由小到大,排名為 0 ~ n - 1| | ZREVRANK [keyName] [keyValue]|返回該成員在集合中的排名| 以 score 由大到小,排名為 0 ~ n - 1| | ZREM [keyName] [keyValue1] [keyValue2]... | 將一個或多個 value 從 key 中移除|返回值為成功移除的成員數目| | ZREMRANGEBYRANK [keyName] [start] [stop] | 以 rank 由小到大,移除排名在 start 到 stop 之間的所有成員|| | ZREMRANGEBYSCORE [keyName] [min] [max]| 移除 score 在 start 到 stop 之間的所有成員|| | ZRANGEBYLEX [keyName] [min] [max] ["LIMIT offset count"] | 當該 Key 成員間具有相同的 score 時,則返回 value 在 min 和 max 之間的成員| mix 和 max 必須要用 "(" 或 "[" 明確標示範圍或字符;"(" 表示不包含值;"[" 表示包含該值| | ZLEXCOUNT [keyName] [min] [max]|與上述效果相同,差別在於返回符合的成員數量|| | ZREMRANGEBYLEX |與上上述效果相同,差別在於移除符合的成員| 返回值為移除的成員數量 | | ZSCAN [keyName] [cursor] ["match" pattern] ["count" LimitNumber]|filter 查詢所有 集合成員的方式| cursor 可設為 0;若有使用 match 功能,則指令為 match [keyName pattern];若有使用 Limit 功能,則指另為 count [LimitNumber]|| | ZUNIONSTORE [keyName1] [number keys] [keyName2] [keyName3] [weight1] [weight2] |將 number keys 數的 key2 和 key3 放入 key1 中,放入時針對 score 的部分各別乘上 weight1 和 weight2 的權重 | 返回為處理完成的 key1 成員數目 || | ZINTERSTORE [keyName1] [number keys] [keyName2] [keyName3] [weight1] [weight2] | 將 number keys 數的 key2 和 key3 放入 key1 中,放入時針對相同 value 的成員,其 score 會做相加的動作 | 返回處理完成的 key1 成員數目| ## 結語 :::danger 這週主要就是介紹所有我們會用到的 Redis 資料結構,這樣在使用上就可以有最基本的掌握,已經可以搭配程式開始處理一些比較棘手的 Cache 問題了 ~~下一篇將會繼續分享關於 Redis 幾個好用的功能~~ 下一篇將來分享 Java 與 Redis 的簡單結合使用範例 [六角鼠年鐵人賽 Week 22 - Spring Boot - Java & Redis 範例](/F2UaokVRRWmGVrvkKc7Ofw) ::: 首頁 [Kai 個人技術 Hackmd](/2G-RoB0QTrKzkftH2uLueA) ###### tags: `Redis`,`w3HexSchool`