Go語言中使用第三方庫https://github.com/go-redis/redis鏈接Redis數據庫並進行操做。使用如下命令下載並安裝:git
go get github.com/go-redis/redis/v8
注:導入時指定了版本v8,忽略版本是一個常見錯誤github
說明:Background返回一個非空的Context。 它永遠不會被取消,沒有值,也沒有期限。 它一般在main函數,初始化和測試時使用,並用做傳入請求的頂級上下文。redis
示例:shell
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") }
示例:數據庫
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對應值的類型json
示例:數組
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 }
示例:緩存
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()
方法用於檢測某個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()
方法是設置某個時間段(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()
方法能夠獲取某個鍵的剩餘有效期
示例:
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) }
示例:
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) }
示例:
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 }
示例:
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 }
僅僅支持字符串(包含數字)操做,不支持內置數據編碼功能。若是須要存儲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) } }
設置鍵的同時,設置過時時間
示例:
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()與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已經存在緩存中,設置失敗") } }
若是要獲取的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()
方法能夠用來截取字符串的部份內容,第二個參數是下標索引的開始位置,第三個參數是下標索引的結束位置(不是要截取的長度)
示例:
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()
、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) }
示例:
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()
和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) }
示例:
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()
表示往字符串後面追加元素,返回值是字符串的總長度
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()
方法能夠獲取字符串的長度
示例:
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
可使用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()
位置的判斷,是根據相對的參考元素判斷
示例:
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()方法
示例:
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) } }
示例:
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) }
示例:
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) }
示例:
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()
示例:
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) }
Redis set對外提供的功能與list相似是一個列表的功能,特殊之處在於set是能夠自動排重的,當你須要存儲一個列表數據,又不但願出現重複數據,set是一個很好的選擇,而且set提供了判斷某個成員是否在一個set集合內的接口,這是也是list所不能提供了。
Redis的Set是string類型的無序集合。它底層實際上是一個value爲null的hash表,因此添加、刪除、查找的複雜度都是O(1)。
集合數據的特徵:
示例:
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()
方法是從集合中隨機取出元素的,若是想一次獲取多個元素,可使用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) }
示例:
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) }
示例:
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) }
示例:
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("不存在集合中") } }
獲取集合中元素個數
示例:
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) }
示例:
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) }
Redis 有序集合和集合同樣也是string類型元素的集合,且不容許重複的成員。
不一樣的是每一個元素都會關聯一個double類型的分數。redis正是經過分數來爲集合中的成員進行從小到大的排序。
有序集合的成員是惟一的,但分數(score)
卻能夠重複。
集合是經過哈希表實現的,因此添加,刪除,查找的複雜度都是O(1)。 集合中最大的成員數爲 232 - 1 (4294967295, 每一個集合可存儲40多億個成員)。
添加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, }) }
分值能夠爲負數,表示遞減
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") }
根據分值排序後的,升序和降序的列表獲取
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) }
根據分值過濾以後的列表
須要提供分值區間
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) }
示例:
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) }
獲取分值在[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) }
獲取元素分值
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()
方法是返回元素在集合中的升序排名狀況,從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()
方法支持經過元素的值來刪除元素
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) }
示例:
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) }
示例:
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) }
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()
方法支持以下格式
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"}) }
示例:
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":"北京"}) }
示例:
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) }
示例:
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()
支持一次刪除多個元素
示例:
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) }
示例:
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) }
示例:
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) }