目錄
- 安裝Redis客戶端
- 連接redis
- 基本指令
- Keys():根據正則獲取keys
- Type():獲取key對應值得型別
- Del():洗掉快取項
- Exists():檢測快取項是否存在
- Expire(),ExpireAt():設定有效期
- TTL(),PTTL():獲取有效期
- DBSize():查看當前資料庫key的數量
- FlushDB():清空當前資料
- FlushAll():清空所有資料庫
- 字串(string)型別
- Set():設定
- SetEX():設定并指定過期時間
- SetNX():設定并指定過期時間
- Get():獲取
- GetRange():字串截取
- Incr():增加+1
- IncrBy():按指定步長增加
- Decr():減少-1
- DecrBy():按指定步長減少
- Append():追加
- StrLen():獲取長度
- 串列(list)型別
- LPush():將元素壓入鏈表
- LInsert():在某個位置插入新元素
- LSet():設定某個元素的值
- LLen():獲取鏈表元素個數
- LIndex():獲取鏈表下標對應的元素
- LRange():獲取某個選定范圍的元素集
- 從鏈表左側彈出資料
- LRem():根據值移除元素
- 集合(set)型別
- SAdd():添加元素
- SPop():隨機獲取一個元素
- SRem():洗掉集合里指定的值
- SSMembers():獲取所有成員
- SIsMember():判斷元素是否在集合中
- SCard():獲取集合元素個數
- SUnion():并集,SDiff():差集,SInter():交集
- 有序集合(zset)型別
- ZAdd():添加元素
- ZIncrBy():增加元素分值
- ZRange()、ZRevRange():獲取根據score排序后的資料段
- ZRangeByScore()、ZRevRangeByScore():獲取score過濾后排序的資料段
- ZCard():獲取元素個數
- ZCount():獲取區間內元素個數
- ZScore():獲取元素的score
- ZRank()、ZRevRank():獲取某個元素在集合中的排名
- ZRem():洗掉元素
- ZRemRangeByRank():根據排名來洗掉
- ZRemRangeByScore():根據分值區間來洗掉
- 哈希(hash)型別
- HSet():設定
- HMset():批量設定
- HGet():獲取某個元素
- HGetAll():獲取全部元素
- HDel():洗掉某個元素
- HExists():判斷元素是否存在
- HLen():獲取長度
安裝Redis客戶端
Go語言中使用第三方庫https://github.com/go-redis/redis連接Redis資料庫并進行操作,使用以下命令下載并安裝:
go get github.com/go-redis/redis/v8
注:匯入時指定了版本v8,忽略版本是一個常見錯誤
連接redis
說明:Background回傳一個非空的Context, 它永遠不會被取消,沒有值,也沒有期限, 它通常在main函式,初始化和測驗時使用,并用作傳入請求的頂級背景關系,
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
//Background回傳一個非空的Context, 它永遠不會被取消,沒有值,也沒有期限,
//它通常在main函式,初始化和測驗時使用,并用作傳入請求的頂級背景關系,
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
pong, err := rdb.Ping(ctx).Result()
if err != nil {
fmt.Printf("連接redis出錯,錯誤資訊:%v", err)
}
fmt.Println("成功連接redis")
}
基本指令
Keys():根據正則獲取keys
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
//*表示獲取所有的key
keys, err := rdb.Keys(ctx, "*").Result()
if err != nil {
panic(err)
}
fmt.Println(keys)
}
Type():獲取key對應值得型別
Type()方法用戶獲取一個key對應值的型別
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
vType, err := rdb.Type(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Println(vType) //string
}
Del():洗掉快取項
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
n, err := rdb.Del(ctx, "key1", "key2").Result()
if err != nil {
panic(err)
}
fmt.Printf("成功洗掉了 %v 個\n", n)
}
Exists():檢測快取項是否存在
Exists()方法用于檢測某個key是否存在
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
n, err := rdb.Exists(ctx, "key1").Result()
if err != nil {
panic(err)
}
if n > 0 {
fmt.Println("存在")
} else {
fmt.Println("不存在")
}
}
注:Exists()方法可以傳入多個key,回傳的第一個結果表示存在的key的數量,不過作業中我們一般不同時判斷多個key是否存在,一般就判斷一個key,所以判斷是否大于0即可,如果判斷判斷傳入的多個key是否都存在,則回傳的結果的值要和傳入的key的數量相等
Expire(),ExpireAt():設定有效期
需要在設定好了快取項后,在設定有效期
Expire()方法是設定某個時間段(time.Duration)后過期,ExpireAt()方法是在某個時間點(time.Time)過期失效
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
"time"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
res, err := rdb.Expire(ctx, "key", time.Minute * 2).Result()
if err != nil {
panic(err)
}
if res {
fmt.Println("設定成功")
} else {
fmt.Println("設定失敗")
}
res, err = rdb.ExpireAt(ctx, "key2", time.Now()).Result()
if err != nil {
panic(err)
}
if res {
fmt.Println("設定成功")
} else {
fmt.Println("設定失敗")
}
}
TTL(),PTTL():獲取有效期
TTL()方法可以獲取某個鍵的剩余有效期
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
"time"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
//設定一分鐘的有效期
rdb.Expire(ctx, "key", time.Minute)
//獲取剩余有效期,單位:秒(s)
ttl, err := rdb.TTL(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Println(ttl)
//獲取剩余有效期,單位:毫秒(ms)
pttl, err := rdb.PTTL(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Println(pttl)
}
DBSize():查看當前資料庫key的數量
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
num, err := rdb.DBSize(ctx).Result()
if err != nil {
panic(err)
}
fmt.Printf("資料庫有 %v 個快取項\n", num)
}
FlushDB():清空當前資料
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
//清空當前資料庫,因為連接的是索引為0的資料庫,所以清空的就是0號資料庫
res, err := rdb.FlushDB(ctx).Result()
if err != nil {
panic(err)
}
fmt.Println(res)//OK
}
FlushAll():清空所有資料庫
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
res, err := rdb.FlushAll(ctx).Result()
if err != nil {
panic(err)
}
fmt.Println(res)//OK
}
字串(string)型別
Set():設定
僅僅支持字串(包含數字)操作,不支持內置資料編碼功能,如果需要存盤Go的非字串型別,需要提前手動序列化,獲取時再反序列化,
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
"time"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
_, err := rdb.Ping(ctx).Result()
//fmt.Println(pong, err)
if err != nil {
fmt.Printf("連接redis出錯,錯誤資訊:%v", err)
return
}
//Set方法的最后一個引數表示過期時間,0表示永不過期
err = rdb.Set(ctx, "key1", "value1", 0).Err()
if err != nil {
panic(err)
}
//key2將會在兩分鐘后過期失效
err = rdb.Set(ctx, "key2", "value2", time.Minute * 2).Err()
if err != nil {
panic(err)
}
}
SetEX():設定并指定過期時間
設定鍵的同時,設定過期時間
示例:
package main
import (
"context"
"github.com/go-redis/redis/v8"
"time"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
err := rdb.SetEX(ctx, "key", "value", time.Hour * 2).Err()
if err != nil {
panic(err)
}
}
SetNX():設定并指定過期時間
注:SetNX()與SetEX()的區別是,SexNX()僅當key不存在的時候才設定,如果key已經存在則不做任何操作,而SetEX()方法不管該key是否已經存在快取中直接覆寫
介紹了SetNX()與SetEX()的區別后,還有一點需要注意的時候,如果我們想知道我們呼叫SetNX()是否設定成功了,可以接著呼叫Result()方法,回傳的第一個值表示是否設定成功了,如果回傳false,說明快取Key已經存在,此次操作雖然沒有錯誤,但是是沒有起任何效果的,如果回傳true,表示在此之前key是不存在快取中的,操作是成功的
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
"time"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
res, err := rdb.SetNX(ctx, "key", "value", time.Minute).Result()
if err != nil {
panic(err)
}
if res {
fmt.Println("設定成功")
} else {
fmt.Printf("key已經存在快取中,設定失敗")
}
}
Get():獲取
如果要獲取的key在快取中并不存在,Get()方法將會回傳redis.Nil
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
err := rdb.Set(ctx, "key", "value", 0).Err()
if err != nil {
panic(err)
}
val, err := rdb.Get(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Printf("key: %v\n", val)
val2, err := rdb.Get(ctx, "key-not-exist").Result()
if err == redis.Nil {
fmt.Println("key不存在")
} else if err != nil {
panic(err)
} else {
fmt.Printf("值為: %v\n", val2)
}
}
GetRange():字串截取
GetRange()方法可以用來截取字串的部分內容,第二個引數是下標索引的開始位置,第三個引數是下標索引的結束位置(不是要截取的長度)
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
err := rdb.Set(ctx, "key", "Hello World!", 0).Err()
if err != nil {
panic(err)
}
val, err := rdb.GetRange(ctx, "key", 1, 4).Result()
if err != nil {
panic(err)
}
fmt.Printf("key: %v\n", val) //截取到的內容為: ello
}
注:即使key不存在,呼叫GetRange()也不會報錯,只是回傳的截取結果是空"",可以使用fmt.Printf("%q\n", val)來列印測驗
Incr():增加+1
Incr()、IncrBy()都是運算元字,對數字進行增加的操作,incr是執行原子加1操作,incrBy是增加指定的數
所謂原子操作是指不會被執行緒調度機制打斷的操作:這種操作一旦開始,就一直運行到結束,中間不會有任何context witch(切換到另一個執行緒).
(1)在單執行緒中,能夠在單條指令中完成的操作都可以認為是“原子操作”,因為中斷只能發生于指令之間,
(2)在多執行緒中,不能被其它行程(執行緒)打算的操作叫原子操作,
Redis單命令的原子性主要得益于Redis的單執行緒
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
val, err := rdb.Incr(ctx, "number").Result()
if err != nil {
panic(err)
}
fmt.Printf("key當前的值為: %v\n", val)
}
IncrBy():按指定步長增加
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
val, err := rdb.IncrBy(ctx, "number", 12).Result()
if err != nil {
panic(err)
}
fmt.Printf("key當前的值為: %v\n", val)
}
Decr():減少-1
Decr()和DecrBy()方法是對數字進行減的操作,和Incr正好相反
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
val, err := rdb.Decr(ctx, "number").Result()
if err != nil {
panic(err)
}
fmt.Printf("key當前的值為: %v\n", val)
}
DecrBy():按指定步長減少
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
val, err := rdb.DecrBy(ctx, "number", 12).Result()
if err != nil {
panic(err)
}
fmt.Printf("key當前的值為: %v\n", val)
}
Append():追加
Append()表示往字串后面追加元素,回傳值是字串的總長度
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
err := rdb.Set(ctx, "key", "hello", 0).Err()
if err != nil {
panic(err)
}
length, err := rdb.Append(ctx, "key", " world!").Result()
if err != nil {
panic(err)
}
fmt.Printf("當前快取key的長度為: %v\n", length) //12
val, err := rdb.Get(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Printf("當前快取key的值為: %v\n", val) //hello world!
}
StrLen():獲取長度
StrLen()方法可以獲取字串的長度
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
err := rdb.Set(ctx, "key", "hello world!", 0).Err()
if err != nil {
panic(err)
}
length, err := rdb.StrLen(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Printf("當前快取key的長度為: %v\n", length) //12
}
如上所述都是常用的字串操作,此外,字串(string)型別還有MGet()、Mset()、MSetNX()等同時操作多個key的方法,詳見:https://pkg.go.dev/github.com/go-redis/redis/v8
串列(list)型別
LPush():將元素壓入鏈表
可以使用LPush()方法將資料從左側壓入鏈表
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
//回傳值是當前串列元素的數量
n, err := rdb.LPush(ctx, "list", 1, 2, 3).Result()
if err != nil {
panic(err)
}
fmt.Println(n)
}
也可以從右側壓如鏈表,對應的方法是RPush()
LInsert():在某個位置插入新元素
位置的判斷,是根據相對的參考元素判斷
示例:
package main
import (
"context"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
//在名為key的快取項值為100的元素前面插入一個值,值為123
err := rdb.LInsert(ctx, "key", "before", "100", 123).Err()
if err != nil {
panic(err)
}
}
注:即使key串列里有多個值為100的元素,也只會在第一個值為100的元素前面插入123,并不會在所有值為100的前面插入123,客戶端還提供了從前面插入和從后面插入的LInsertBefore()和LInsertAfer()方法
LSet():設定某個元素的值
示例:
package main
import (
"context"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
//下標是從0開始的
err := rdb.LSet(ctx, "list", 1, 100).Err()
if err != nil {
panic(err)
}
}
LLen():獲取鏈表元素個數
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
length, err := rdb.LLen(ctx, "list").Result()
if err != nil {
panic(err)
}
fmt.Printf("當前鏈表的長度為: %v\n", length)
}
LIndex():獲取鏈表下標對應的元素
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
val, err := rdb.LIndex(ctx, "list", 0).Result()
if err != nil {
panic(err)
}
fmt.Printf("下標為0的值為: %v\n", val)
}
LRange():獲取某個選定范圍的元素集
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
vals, err := rdb.LRange(ctx, "list", 0, 2).Result()
if err != nil {
panic(err)
}
fmt.Printf("從下標0到下標2的值: %v\n", vals)
}
從鏈表左側彈出資料
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
val, err := rdb.LPop(ctx, "list").Result()
if err != nil {
panic(err)
}
fmt.Printf("移除的元素為: %v\n", val)
}
與之相對的,從右側彈出資料的方法為RPop()
LRem():根據值移除元素
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
n, err := rdb.LRem(ctx, "list", 2, "100").Result()
if err != nil {
panic(err)
}
fmt.Printf("移除了: %v 個\n", n)
}
集合(set)型別
Redis set對外提供的功能與list類似是一個串列的功能,特殊之處在于set是可以自動排重的,當你需要存盤一個串列資料,又不希望出現重復資料,set是一個很好的選擇,并且set提供了判斷某個成員是否在一個set集合內的介面,這是也是list所不能提供了,
Redis的Set是string型別的無序集合,它底層其實是一個value為null的hash表,所以添加、洗掉、查找的復雜度都是O(1),
集合資料的特征:
- 元素不能重復,保持唯一性
- 元素無序,不能使用索引(下標)操作
SAdd():添加元素
示例:
package main
import (
"context"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
rdb.SAdd(ctx, "team", "kobe", "jordan")
rdb.SAdd(ctx, "team", "curry")
rdb.SAdd(ctx, "team", "kobe") //由于kobe已經被添加到team集合中,所以重復添加時無效的
}

SPop():隨機獲取一個元素
無序性,是隨機的
SPop()方法是從集合中隨機取出元素的,如果想一次獲取多個元素,可以使用SPopN()方法
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
val, err := rdb.SPop(ctx, "team").Result()
if err != nil {
panic(err)
}
fmt.Println(val)
}
SRem():洗掉集合里指定的值
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
n, err := rdb.SRem(ctx, "team", "kobe", "v2").Result()
if err != nil {
panic(err)
}
fmt.Println(n)
}
SSMembers():獲取所有成員
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
vals, err := rdb.SMembers(ctx, "team").Result()
if err != nil {
panic(err)
}
fmt.Println(vals)
}
SIsMember():判斷元素是否在集合中
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
exists, err := rdb.SIsMember(ctx, "team", "jordan").Result()
if err != nil {
panic(err)
}
if exists {
fmt.Println("存在集合中")
} else {
fmt.Println("不存在集合中")
}
}
SCard():獲取集合元素個數
獲取集合中元素個數
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
total, err := rdb.SCard(ctx, "team").Result()
if err != nil {
panic(err)
}
fmt.Printf("集合總共有 %v 個元素\n", total)
}
SUnion():并集,SDiff():差集,SInter():交集
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
rdb.SAdd(ctx, "setA", "a", "b", "c", "d")
rdb.SAdd(ctx, "setB", "a", "d", "e", "f")
//并集
union, err := rdb.SUnion(ctx, "setA", "setB").Result()
if err != nil {
panic(err)
}
fmt.Println(union)
//差集
diff, err := rdb.SDiff(ctx, "setA", "setB").Result()
if err != nil {
panic(err)
}
fmt.Println(diff)
//交集
inter, err := rdb.SInter(ctx, "setA", "setB").Result()
if err != nil {
panic(err)
}
fmt.Println(inter)
}

有序集合(zset)型別
Redis 有序集合和集合一樣也是string型別元素的集合,且不允許重復的成員,
不同的是每個元素都會關聯一個double型別的分數,redis正是通過分數來為集合中的成員進行從小到大的排序,
有序集合的成員是唯一的,但分數(score)卻可以重復,
集合是通過哈希表實作的,所以添加,洗掉,查找的復雜度都是O(1), 集合中最大的成員數為 232 - 1 (4294967295, 每個集合可存盤40多億個成員),
ZAdd():添加元素
添加6個元素1~6,分值都是0
package main
import (
"context"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
rdb.ZAdd(ctx, "zSet", &redis.Z{
Score: 0,
Member: 1,
})
rdb.ZAdd(ctx, "zSet", &redis.Z{
Score: 0,
Member: 2,
})
rdb.ZAdd(ctx, "zSet", &redis.Z{
Score: 0,
Member: 3,
})
rdb.ZAdd(ctx, "zSet", &redis.Z{
Score: 0,
Member: 4,
})
rdb.ZAdd(ctx, "zSet", &redis.Z{
Score: 0,
Member: 5,
})
rdb.ZAdd(ctx, "zSet", &redis.Z{
Score: 0,
Member: 6,
})
}

ZIncrBy():增加元素分值
分值可以為負數,表示遞減
package main
import (
"context"
"github.com/go-redis/redis/v8"
"math/rand"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
rdb.ZIncrBy(ctx, "zSet", float64(rand.Intn(100)), "1")
rdb.ZIncrBy(ctx, "zSet", float64(rand.Intn(100)), "2")
rdb.ZIncrBy(ctx, "zSet", float64(rand.Intn(100)), "3")
rdb.ZIncrBy(ctx, "zSet", float64(rand.Intn(100)), "4")
rdb.ZIncrBy(ctx, "zSet", float64(rand.Intn(100)), "5")
rdb.ZIncrBy(ctx, "zSet", float64(rand.Intn(100)), "6")
}

ZRange()、ZRevRange():獲取根據score排序后的資料段
根據分值排序后的,升序和降序的串列獲取
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
//獲取排行榜
//獲取分值(點擊率)前三的文章ID串列
res, err := rdb.ZRevRange(ctx, "zSet", 0, 2).Result()
if err != nil {
panic(err)
}
fmt.Println(res)
}

ZRangeByScore()、ZRevRangeByScore():獲取score過濾后排序的資料段
根據分值過濾之后的串列
需要提供分值區間
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
res, err := rdb.ZRangeByScore(ctx, "zSet", &redis.ZRangeBy{
Min: "40",
Max: "85",
}).Result()
if err != nil {
panic(err)
}
fmt.Println(res)
}
ZCard():獲取元素個數
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
count, err := rdb.ZCard(ctx, "zSet").Result()
if err != nil {
panic(err)
}
fmt.Println(count)
}
ZCount():獲取區間內元素個數
獲取分值在[40, 85]的元素的數量
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
n, err := rdb.ZCount(ctx, "zSet", "40", "85").Result()
if err != nil {
panic(err)
}
fmt.Println(n)
}
ZScore():獲取元素的score
獲取元素分值
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
score, err := rdb.ZScore(ctx, "zSet", "5").Result()
if err != nil {
panic(err)
}
fmt.Println(score)
}
ZRank()、ZRevRank():獲取某個元素在集合中的排名
ZRank()方法是回傳元素在集合中的升序排名情況,從0開始,ZRevRank()正好相反
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
res, err := rdb.ZRevRank(ctx, "zSet", "2").Result()
if err != nil {
panic(err)
}
fmt.Println(res)
}
ZRem():洗掉元素
ZRem()方法支持通過元素的值來洗掉元素
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
//通過元素值來洗掉元素
res, err := rdb.ZRem(ctx, "zSet", "2").Result()
if err != nil {
panic(err)
}
fmt.Println(res)
}
ZRemRangeByRank():根據排名來洗掉
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
//按照升序排序洗掉第一個和第二個元素
res, err := rdb.ZRemRangeByRank(ctx, "zSet", 0, 1).Result()
if err != nil {
panic(err)
}
fmt.Println(res)
}
ZRemRangeByScore():根據分值區間來洗掉
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
//洗掉score在[40, 70]之間的元素
res, err := rdb.ZRemRangeByScore(ctx, "zSet", "40", "70").Result()
if err != nil {
panic(err)
}
fmt.Println(res)
}
哈希(hash)型別
Redis hash 是一個 string 型別的 field(欄位) 和 value(值) 的映射表,hash 特別適合用于存盤物件,
Redis 中每個 hash 可以存盤 232 - 1 鍵值對(40多億),
當前服務器一般都是將用戶登錄資訊保存到Redis中,這里存盤用戶登錄資訊就比較適合用hash表,hash表比string更合適,如果我們選擇使用string型別來存盤用戶的資訊的時候,我們每次存盤的時候就得先序列化(json_encode()、serialize())成字串才能存盤redis,
從redis拿到用戶資訊后又得反序列化(UnMarshal()、Marshal())成陣列或物件,這樣開銷比較大,如果使用hash的話我們通過key(用戶ID)+field(屬性標簽)就可以操作對應屬性資料了,既不需要重復存盤資料,也不會帶來序列化和并發修改控制的問題,
HSet():設定
HSet()方法支持如下格式
package main
import (
"context"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
rdb.HSet(ctx, "user", "key1", "value1", "key2", "value2")
rdb.HSet(ctx, "user", []string{"key3", "value3", "key4", "value4"})
rdb.HSet(ctx, "user", map[string]interface{}{"key5": "value5", "key6": "value6"})
}

HMset():批量設定
示例:
package main
import (
"context"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
rdb.Del(ctx, "user")
rdb.HMSet(ctx, "user", map[string]interface{}{"name":"kevin", "age": 27, "address":"北京"})
}

HGet():獲取某個元素
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
address, err := rdb.HGet(ctx, "user", "address").Result()
if err != nil {
panic(err)
}
fmt.Println(address)
}
HGetAll():獲取全部元素
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
user, err := rdb.HGetAll(ctx, "user").Result()
if err != nil {
panic(err)
}
fmt.Println(user)
}
HDel():洗掉某個元素
HDel()支持一次洗掉多個元素
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
res, err := rdb.HDel(ctx, "user", "name", "age").Result()
if err != nil {
panic(err)
}
fmt.Println(res)
}
HExists():判斷元素是否存在
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
res, err := rdb.HExists(ctx, "user", "address").Result()
if err != nil {
panic(err)
}
fmt.Println(res)
}
HLen():獲取長度
示例:
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v8"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClient(&redis.Options{
Addr: "172.16.147.128:6379",
Password: "",
DB: 0,
})
res, err := rdb.HLen(ctx, "user").Result()
if err != nil {
panic(err)
}
fmt.Println(res)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/241197.html
標籤:Go
