国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

golang redis第三方庫github.com/go-redis/redis/v8實踐

這篇具有很好參考價值的文章主要介紹了golang redis第三方庫github.com/go-redis/redis/v8實踐。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Redis基本數(shù)據(jù)類型代碼示例#

這里示例使用 go-redis v8 ,不過 go-redis latest 是 v9

安裝v8:go get github.com/go-redis/redis/v8

Redis 5 種基本數(shù)據(jù)類型:

?string 字符串類型;list列表類型;hash哈希表類型;set集合類型;zset有序集合類型

?

最基本的Set/Get操作#

setget.go

package?main

import?(

"context"

"fmt"

"time"

"github.com/go-redis/redis/v8"

)

func?main()?{

rdb := redis.NewClient(&redis.Options{

Addr: ???????"localhost:6379",

Password: ???"",

DB: ?????????0,

IdleTimeout: 350,

PoolSize: ???50, // 連接池連接數(shù)量

})

ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)

defer?cancel()

_, err := rdb.Ping(ctx).Result() // 檢查連接redis是否成功

if?err != nil?{

fmt.Println("Connect Failed: %v \n", err)

panic(err)

}

ctx = context.Background()

// 設置 key 的值,0 表示永不過期

err = rdb.Set(ctx, "setkey-1", "value-1", 0).Err()

if?err != nil?{

panic(err)

}

// 設置 key 的值的過期時間為 30 秒

err = rdb.Set(ctx, "setkey-2", "value-2", time.Second*30).Err()

if?err != nil?{

panic(err)

}

// 獲取key的值

val, err := rdb.Get(ctx, "setkey-1").Result()

if?err == redis.Nil { // 如果返回 redis.Nil 說明key不存在

fmt.Println("key not exixt")

} else?if?err != nil?{

fmt.Println("Get Val error: ", err)

panic(err)

}

fmt.Println("Get Val: ", val)

val, _ = rdb.Get(ctx, "setkey-2").Result()

fmt.Println("Get Val setkey-2: ", val)

}

string(s)字符串類型#

可以從 redis docs 的?COMMANDS?查詢 string 的所有命令。

String 類型命令文檔:Commands | Redis?,
更具體的用法比如詳細語法,參數(shù)設置等,點擊每一個命令然后進去查看。
比如點進去后 SET 的詳細語法格式:

Copy

SET?key value?[NX |?XX] [GET] [EX seconds |?PX milliseconds |

??EXAT unix-time-seconds |?PXAT unix-time-milliseconds |?KEEPTTL]

具體命令用法可以搜索上面 command 然后點進去查看,這里主要是代碼示例,就不介紹具體命令用法了。

string 的底層是 SDS 數(shù)據(jù)結構,原理簡析可以看這篇文章:https://www.cnblogs.com/jiujuan/p/15828302.html。

string 常用命令:

1.SET/GET:設置獲取值。

2.SETNX/EXISTS:SETNX設置并指定過期時間僅key不存在,EXISTS 檢查某個 key 是否存在。

3.MSET/MGET:批量設置獲取值。

4.DEL:刪除值。

5.INCR/INCRBY - DECR/DECRBY:INCR 原子加1,INCRBY 加具體數(shù)值。DECR/DECRBY 剛好相反。

6.GetRange:字符串截取,返回字符串的總長度。

7.Expire/ExpireAt/TTL:設置值的過期時間端/點。TTL 獲取過期的時間。

8.StrLen:獲取key的值長度

  • 1、SET/GET:設置和獲取值,見最上面SET/GET例子
  • 2、SETNX/EXISTS

SETNX:設置并指定過期時間,僅當 key 不存在時候才設置有效。

EXISTS: 檢查某個 key 是否存在

Copy

package?main

import?(

"context"

"fmt"

"time"

"github.com/go-redis/redis/v8"

)

func?main()?{

rdb := redis.NewClient(&redis.Options{

Addr: ???????"localhost:6379",

Password: ???"",

DB: ?????????0,

IdleTimeout: 350,

PoolSize: ???50, // 連接池連接數(shù)量

})

ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)

defer?cancel()

_, err := rdb.Ping(ctx).Result() // 檢查連接redis是否成功

if?err != nil?{

fmt.Println("Connect Failed: %v \n", err)

panic(err)

}

ctx = context.Background()

// SetNX, 設置并指定過期時間,僅當 key 不存在時候才設置有效

err = rdb.SetNX(ctx, "setnx-key", "setnx-val", 0).Err()

if?err != nil?{

fmt.Println("setnx value failed: ", err)

panic(err)

}

// 這里用SetNX設置值,第二次運行后 val2 返回 false,因為第二次運行時 setnx-key2 已經存在

val2, err := rdb.SetNX(ctx, "setnx-key2", "setnx-val2", time.Second*20).Result()

if?err != nil?{

panic(err)

}

fmt.Printf("val2: %v \n", val2)

// Exists, 檢查某個key是否存在

n, _ := rdb.Exists(ctx, "setnx-key").Result()

if?n > 0?{

fmt.Println("n: ", n)

fmt.Println("set nx key exists")

} else?{

fmt.Println("set nx key not exists")

}

val, _ := rdb.Get(ctx, "setnx-key").Result()

fmt.Println(val)

}

  • 3、MSET/MGET:批量設置值,批量獲取值

Copy

ctx = context.Background()// MSet 設置值

err = rdb.MSet(ctx, "mset-key1", "mset-val1", "mset-key2", "mset-val2", "mset-key3", "mset-val3").Err()if?err != nil?{

????fmt.Println("MSet ERROR : ", err)

}// MGet 獲取值

vals, err := rdb.MGet(ctx, "mset-key1", "mset-key2", "mset-key3").Result()if?err != nil?{

????fmt.Println("MGet ERROR: ", err)

????panic(err)

}

fmt.Println("vals: ", vals)

  • 4、DEL:刪除操作,支持刪除多個 key 的操作

Copy

ctx = context.Background()

n, err := rdb.Del(ctx, "setkey", "setnx-key").Result()if?err != nil?{

????panic(err)

}

fmt.Println("del nums: ", n)

  • 5、INCR/INCRBY - DECR/DECRBY

INCR:對數(shù)字進行原子加 1 操作;INCRBY:加某個數(shù)值。

同理 DECR 都是相反操作

Copy

package?main

import?(

"context"

"fmt"

"time"

"github.com/go-redis/redis/v8"

)

func?main()?{

rdb := redis.NewClient(&redis.Options{

Addr: ???????"localhost:6379",

Password: ???"",

DB: ?????????0,

IdleTimeout: 350,

PoolSize: ???50, // 連接池連接數(shù)量

})

ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)

defer?cancel()

_, err := rdb.Ping(ctx).Result() // 檢查連接redis是否成功

if?err != nil?{

fmt.Println("Connect Failed: %v \n", err)

panic(err)

}

ctx = context.Background()

err = rdb.SetNX(ctx, "nums", 2, 0).Err()

if?err != nil?{

panic(err)

}

fmt.Println("set nums : ", 2)

// Incr

val, err := rdb.Incr(ctx, "nums").Result()

if?err != nil?{

panic(err)

}

fmt.Println("incr: ", val)

// IncrBy

val, err = rdb.IncrBy(ctx, "nums", 10).Result()

if?err != nil?{

panic(err)

}

fmt.Println("incrby: ", val)

//Decr

val, _ = rdb.Decr(ctx, "nums").Result()

fmt.Println("desc: ", val)

//DecrBy

val, _ = rdb.DecrBy(ctx, "nums", 5).Result()

fmt.Println("decrby: ", val)

}

  • 6、GetRange:字符串截取,返回字符串的總長度

Copy

// GetRange,字符串截取操作,返回字符串截取后的值

val, _ = rdb.GetRange(ctx, "setkey-1", 1, 3).Result()

fmt.Println("get range: ", val)

可以放到GET/SET代碼里去測試

  • 7、Expire/ExpireAt/TTL 設置過期時間

Expire:設置某個時間段后過期。

ExpireAt:設置某個時間點過期。

TTL:獲取剩余時間

Copy

package?main

import?(

"context"

"fmt"

"time"

"github.com/go-redis/redis/v8"

)

func?main()?{

rdb := redis.NewClient(&redis.Options{

Addr: ???????"localhost:6379",

Password: ???"",

DB: ?????????0,

IdleTimeout: 350,

PoolSize: ???50, // 連接池連接數(shù)量

})

ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)

defer?cancel()

_, err := rdb.Ping(ctx).Result() // 檢查連接redis是否成功

if?err != nil?{

fmt.Println("Connect Failed: %v \n", err)

panic(err)

}

ctx = context.Background()

rdb.Set(ctx, "setkey-expire-1", "value-expire-1", 0).Err()

rdb.Set(ctx, "setkey-expire-2", "value-expire-2", time.Second*40).Err()

// Expire, 設置key在某個時間段后過期

val1, _ := rdb.Expire(ctx, "setkey-expire-1", time.Second*20).Result()

fmt.Println("expire: ", val1)

// ExpireAt,設置key在某個時間點后過期

val2, _ := rdb.ExpireAt(ctx, "setkey-expire-2", time.Now().Add(time.Second*50)).Result()

fmt.Println("expire at: ", val2)

// TTL

expire, err := rdb.TTL(ctx, "setkey-expire-1").Result()

fmt.Println(expire, err)

}/**

expire: ?true

expire at: ?true

20s <nil>

**/

  • 8、StrLen 獲取key的值的長度

Copy

// STRLEN,獲取key的值的長度

strlen, _ := rdb.StrLen(ctx, "setkey-1").Result()

fmt.Println("strlen: ", strlen)

list列表類型#

list 類型的操作命令文檔:Commands | Redis?。

list 列表是一個字符串列表,可以從頭部或尾部插入元素。

list 的源碼簡析可以看這篇文章:https://www.cnblogs.com/jiujuan/p/15839269.html。

list 常用命令:

1.LPUSH:list頭部(左邊)插入值,最后的值在最前面。LPUSHX 僅當列表值存在時才插入值

2.LPOP:移除列表的頭部值并返回這個值

3.RPUSH:list尾部(右邊)插入值。RPUSHX 僅當列表值存在才插入值

4.RPOP:移除列表的尾部值并返回這個值

5.LRANGE:返回key列表指定區(qū)間的值

6.BLPOP: 語法?BLPOP key [key ...] timeout,從 key 列表頭部彈出一個值,沒有就阻塞 timeout 秒,如果 timeout=0 則一直阻塞

7.BRPOP:與上面 BLPOP 用法相似,只不過 BRPOP 是從尾部彈出一個值

8.LLEN:返回列表的長度

9.LINSERT:在指定位置插入數(shù)據(jù)

10.LREM:刪除列表中的數(shù)據(jù)

11.LINDEX:根據(jù)索引查詢列表中的值

12.LSET:根據(jù)索引設置列表中的某個值

Copy

package?main

import?(

"context"

"fmt"

"time"

"github.com/go-redis/redis/v8"

)

func?main()?{

rdb := redis.NewClient(&redis.Options{

Addr: ???????"localhost:6379",

Password: ???"",

DB: ?????????0,

IdleTimeout: 350,

PoolSize: ???50, // 連接池連接數(shù)量

})

ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)

defer?cancel()

_, err := rdb.Ping(ctx).Result() // 檢查連接redis是否成功

if?err != nil?{

fmt.Println("Connect Failed: %v \n", err)

panic(err)

}

ctx = context.Background()

// LPUSH 從頭部(左邊)插入數(shù)據(jù),最后的值在最前面

count, err := rdb.LPush(ctx, "listkeyone", "one", "two", "three", "four").Result()

if?err != nil?{

fmt.Println("lpush err:", err)

}

fmt.Println("lpush count: ", count)

// LRANGE 返回列表范圍數(shù)據(jù)。例子中返回 0 到 -1,就是返回所有數(shù)據(jù)

rangeval, err := rdb.LRange(ctx, "listkeyone", 0, -1).Result()

if?err != nil?{

panic(err)

}

fmt.Println("LRange values: ", rangeval)

// LLen 返回列表數(shù)據(jù)大小

len, err := rdb.LLen(ctx, "listkeyone").Result()

if?err != nil?{

panic(err)

}

fmt.Println("llen: ", len)

// LInsert 在指定位置插入數(shù)據(jù)

err = rdb.LInsert(ctx, "listkeyone", "before", "two", 2).Err()

if?err != nil?{

panic(err)

}

vals, _ := rdb.LRange(ctx, "listkeyone", 0, -1).Result()

fmt.Println("LInsert val: ", vals)

// RPUSH 在 list 尾部插入值

count, err := rdb.RPush(ctx, "listkeyone", "six", "five").Result()

if?err != nil?{

panic(err)

}

fmt.Println("RPush count: ", count)

// RPOP 刪除list列表尾部(右邊)值

val, err := rdb.RPop(ctx, "listkeyone").Result()

if?err != nil?{

panic(err)

}

fmt.Println("rpop val: ", val)

vals, _ = rdb.LRange(ctx, "listkeyone", 0, -1).Result()

fmt.Println("(rpop)lrange val: ", vals)

// LPOP 刪除list列表頭部(左邊)值

val, err = rdb.LPop(ctx, "listkeyone").Result()

fmt.Println("rpop val: ", val)

// LIndex 根據(jù)索引查詢值,索引是從0開始

val1, _ := rdb.LIndex(ctx, "listkeyone", 3).Result()

fmt.Println("LIndex val: ", val1)

// LSET 根據(jù)索引設置某個值,索引從0開始

val2, _ := rdb.LSet(ctx, "listkeyone", 3, "han").Result()

fmt.Println("lset: ", val2)

// LREM 刪除列表中的數(shù)據(jù)

del, err := rdb.LRem(ctx, "listkeyone", 1, 5) // 從列表左邊開始刪除值 5,出現(xiàn)重復元素只刪除一次

if?err != nil?{

panic(err)

}

fmt.Println("del : ", del)

rdb.LRem(ctx, "listkeyone", 2, 5) // 從列表頭部(左邊)開始刪除值 5,如果存在多個值 5,則刪除 2 個 5

rdb.LRem(ctx, "listkeyone", -3, 6) // 從列表尾部(右邊)開始刪除值 6,如果存在多個值 6, 則刪除 3 個 6

}

hash哈希表類型#

hash類型數(shù)據(jù)操作命令:Commands | Redis?,官方文檔

hash類型原理簡析:https://www.cnblogs.com/jiujuan/p/15944061.html?參考文檔

hash 數(shù)據(jù)結構圖:

hash 哈希表數(shù)據(jù)類型常用命令,redisdoc.com 這個地址把Redis分類列出來了,還有詳細解釋:

1.HSET 單個設置值。

2.HGET 單個獲取值。

3.HMSET 批量設置。

4.HMGET 批量獲取值。

5.HGETALL 獲取所有值。

6.HDEL 刪除字段,支持刪除多個字段。

7.HLEN 獲取hash表中key的值數(shù)量。

8.HEXISTS 判斷元素是否存在。

9.HINCRBY 根據(jù)key的field字段的整數(shù)值加減一個數(shù)值。

10.HSETNX 如果某個字段不存在則設置該字段值。

更多命令請查看:Commands | Redis

代碼示例:

Copy

package?main

import?(

"context"

"fmt"

"time"

"github.com/go-redis/redis/v8"

)

func?main()?{

rdb := redis.NewClient(&redis.Options{

Addr: ???????"localhost:6379",

Password: ???"",

DB: ?????????0,

IdleTimeout: 350,

PoolSize: ???50, // 連接池連接數(shù)量

})

ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)

defer?cancel()

_, err := rdb.Ping(ctx).Result() // 檢查連接redis是否成功

if?err != nil?{

fmt.Println("Connect Failed: %v \n", err)

panic(err)

}

ctx = context.Background()

// HSET,根據(jù)key設置field字段值

err = rdb.HSet(ctx, "hashkey", "field-val", "value-one").Err()

if?err != nil?{

panic(err)

}

_ = rdb.HSet(ctx, "hashkey", "field1", "value1", "field2", "value2").Err()

_ = rdb.HSet(ctx, "hashkey", map[string]interface{}{"field3": "value3", "field4": "value4"}).Err()

_ = rdb.HSet(ctx, "hashkey-two", []string{"field0", "value0", "field1", "value1"}).Err()

// HSETNX,如果某個字段不存在則設置值

ok, err := rdb.HSetNX(ctx, "hashkey", "field1", "oneval").Result() // 字段 field1 已存在,所以返回ok值為false

if?err != nil?{

panic(err)

}

fmt.Println("HSetNX bool: ", ok)

// HGET,根據(jù)key和field查詢值

val, err := rdb.HGet(ctx, "hashkey", "field-val").Result()

if?err != nil?{

panic(err)

}

fmt.Println("HGet: ", val)

val, _ = rdb.HGet(ctx, "hashkey-two", "field0").Result()

fmt.Println("HGet hashkey-two: ", val)

// HGETALL,獲取key的所有field-val值

fieldvals, err := rdb.HGetAll(ctx, "hashkey").Result()

if?err != nil?{

panic(err)

}

fmt.Println("HGetAll: ", fieldvals) // 返回 map 類型

// HMSET,根據(jù)hash key設置多個字段值,與上面的 HSet 設置多個值很像

fieldvalues := make(map[string]interface{})

fieldvalues["age"] = 23

fieldvalues["firstname"] = "Chare"

fieldvalues["lastname"] = "Jimmy"

err = rdb.HMSet(ctx, "hmsetkey", fieldvalues).Err()

if?err != nil?{

panic(err)

}

/*//也可以像上面HSet直接設置map值

rdb.HMSet(ctx, "hmsetkey", map[string]interface{}{"age":23,"firstname":"Chare","LastName":"Jimmy"}).Err()

*/文章來源地址http://www.zghlxwxcb.cn/news/detail-526230.html

// HMGET, 根據(jù)hash key和多個字段獲取值

vals, err := rdb.HMGet(ctx, "hmsetkey", "age", "lastname").Result()

if?err != nil?{

panic(err)

}

fmt.Println("HMGET vals: ", vals)

// HEXISTX,某個hashkey中字段field否存在

ok, _ = rdb.HExists(ctx, "hmsetkey", "lastname").Result()

fmt.Println("HExists: ", ok) // HExists: true

// HLen,獲取hashkey的字段多少

len, _ := rdb.HLen(ctx, "hashkey").Result()

fmt.Println("HLen hashkey: ", len) // HLen hashkey: 5

// HIncrBy,根據(jù)key的field字段的整數(shù)值加減一個數(shù)值

age, err := rdb.HIncrBy(ctx, "hmsetkey", "age", -3).Result()

if?err != nil?{

panic(err)

}

fmt.Println("HIncrBy : ", age) // HIncrBy : ?20

// HDel,刪除字段,支持刪除多個字段

rdb.HSet(ctx, "hashkeydel", map[string]interface{}{"field10": "value10", "field11": "value11", "field12": "value12", "field13": "value13"}).Err()

rdb.HDel(ctx, "hashkeydel", "field10", "field12") //刪除多個字段

delvals, err := rdb.HGetAll(ctx, "hashkeydel").Result()

if?err != nil?{

panic(err)

}

fmt.Println("HGetAll hashkeydel: ", delvals)

}

/**

HSetNX bool: ?false

HGet: ?value-one

HGet hashkey-two: ?value0

HGetAll: ?map[field-val:value-one field1:value1 field2:value2 field3:value3 field4:value4]

HMGET vals: ?[23 Jimmy]

HExists: ?true

HLen hashkey: ?5

HIncrBy : ?20

HGetAll hashkeydel: ?map[field11:value11 field13:value13]

?* */

set集合類型#

Redis 中的 set 集合類型是一個無序的唯一值集合,也就是說一個set集合中的值唯一,它的存儲順序不會按照插入順序進行存儲。

set與list的區(qū)別:

  1. list 可以存儲重復的元素,而 set 不能
  2. list 可以按照元素先后順序存儲,而 set 不能

set 集合操作命令文檔:

1.Commands | Redis

2.集合 — Redis 命令參考

set 常用命令:

  1. SADD:SADD key member [member...],將一個或多個元素數(shù)據(jù)添加到集合 key 中
  2. SISMEMBER: SISMEMBER key member,判斷 member 是否是集合 key 的成員
  3. SMEMBERS: SMEMBERS key,獲取 key 中的所有元素數(shù)據(jù)
  4. SREM:SREM key member [member ...],刪除 key 中的一個或多個數(shù)據(jù)
  5. SPOP:SPOP key,隨機移除集合中的一個數(shù)據(jù)并返回
  6. SCARD:SCARD key,獲取集合 key 中元素的數(shù)量
  7. SDIFF:SDIFF key [key...],計算多個集合的差集
  8. SUNION:SUNION key [key...],計算多個集合的并集
  9. SINTER:SINTER key [key...],計算多個集合的交集

代碼例子:

Copy

package?main

import?(

"context"

"fmt"

"time"

"github.com/go-redis/redis/v8"

)

func?main()?{

rdb := redis.NewClient(&redis.Options{

Addr: ???????"localhost:6379",

Password: ???"",

DB: ?????????0,

IdleTimeout: 350,

PoolSize: ???50, // 連接池連接數(shù)量

})

ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)

defer?cancel()

_, err := rdb.Ping(ctx).Result() // 檢查連接redis是否成功

if?err != nil?{

fmt.Println("Connect Failed: %v \n", err)

panic(err)

}

ctx = context.Background()

// SADD,將一個或多個元素數(shù)據(jù)添加到集合中

err = rdb.SAdd(ctx, "setkey:1", 20, "dog").Err()

if?err != nil?{

panic(err)

}

rdb.SAdd(ctx, "setkey:1", []string{"hanmeimei", "lilei", "tom", "dog", "one"}) // 切片增加數(shù)據(jù),dog只有一個數(shù)據(jù)

rdb.SAdd(ctx, "setkey:2", []string{"jimmy", "pig", "dog", "lilei"})

// SMEMBERS,獲取集合中的所有元素數(shù)據(jù)

smembers, err := rdb.SMembers(ctx, "setkey:1").Result()

if?err != nil?{

panic(err)

}

fmt.Println("SMembers,setkey:1: ", smembers)

// SCARD,獲取集合中的元素數(shù)量

scards, err := rdb.SCard(ctx, "setkey:2").Result()

if?err != nil?{

panic(err)

}

fmt.Println("SCard,setkey:2: ", scards)

// SPOP,隨機移除一個數(shù)據(jù)并返回這個數(shù)據(jù)

rdb.SAdd(ctx, "setkey:3", []string{"one", "two", "three", "four", "six"})

spop, _ := rdb.SPop(ctx, "setkey:3").Result()

res, _ := rdb.SMembers(ctx, "setkey:3").Result()

fmt.Println("spop: ", spop, ", SMembers: ", res)

// SPOPN,隨機移除多個元素并返回

spopn, _ := rdb.SPopN(ctx, "setkey:3", 2).Result()

res, _ = rdb.SMembers(ctx, "setkey:3").Result()

fmt.Println("spopn: ", spopn, ", SMembers: ", res)

// SISMEMBER,判斷元素是否在集合中

ok, err := rdb.SIsMember(ctx, "setkey:3", "two").Result()

if?err != nil?{

panic(err)

}

fmt.Println("SIsMember, two : ", ok)

// SDIFF,差集,SDIFF key1,key2 與 SDIFF key1,key2 差集是不同,看下面的例子

diff, _ := rdb.SDiff(ctx, "setkey:1", "setkey:2").Result()

fmt.Println("sdiff: ", diff)

diff2, _ := rdb.SDiff(ctx, "setkey:2", "setkey:1").Result()

fmt.Println("sdiff2: ", diff2)

// SUNION,并集

union, _ := rdb.SUnion(ctx, "setkey:1", "setkey:2").Result()

fmt.Println("union: ", union)

// SINTER,交集

inter, _ := rdb.SInter(ctx, "setkey:1", "setkey:2").Result()

fmt.Println("inter: ", inter)

// SREM , 刪除值,返回刪除元素個數(shù)

rdb.SAdd(ctx, "setkey:4", []string{"one", "two", "three"})

count, err := rdb.SRem(ctx, "setkey:4", "one", "three").Result()

if?err != nil?{

panic(err)

}

fmt.Println("SRem: ", count)

}

/*

SMembers,setkey:1: ?[20 hanmeimei one lilei tom dog]

SCard,setkey:2: ?4

spop: ?six , SMembers: ?[four three one two]

spopn: ?[one two] , SMembers: ?[four three]

SIsMember, two : ?false

sdiff: ?[tom 20 hanmeimei one]

sdiff2: ?[jimmy pig]

union: ?[hanmeimei one jimmy lilei tom dog 20 pig]

inter: ?[lilei dog]

SRem: ?2

*/

zset有序集合類型#

zset 是一個不重復值的有序集合,與 set 集合一樣值是不能重復。

zset 排序集是按照相關分數(shù)排序的唯一字符串(成員)的集合。它的底層數(shù)據(jù)結構是由壓縮列表或跳表(skiplist)實現(xiàn)的。

如果有序集合元素個數(shù)小于 128 且每個元素值小于 64 字節(jié),redis 會使用 壓縮列表作為 zset 類型的底層數(shù)據(jù)結構;如果不滿足上面的條件,那么就用跳表作為底層數(shù)據(jù)結構。

跳表的原理簡析:https://www.cnblogs.com/jiujuan/p/12884824.html

zset 有序集合命令列表:

  • Commands | Redis
  • ZADD key score member [[score member] [score member] …] — Redis 命令參考

zset有序集合圖:

zset 有序集合常用命令:

  1. ZADD:ZADD key score member [[score member] [score member] …],將一個或多個member元素以及score加入到有序集合key中
  2. ZSCORE:ZSCORE key member,返回集合 key 中 member 成員的分數(shù)
  3. ZRANGE:ZRANGE key start stop [WITHSCORES],返回集合 key 中指定區(qū)間的元素,score 從小到大排序,start 和 stop 都是 0 開始。
  4. ZREVRANGE:ZREVRANGE key start stop [WITHSCORES],與 zrange 相反,返回集合 key 中指定區(qū)間元素,score 從大到小排序。
  5. ZRANGEBYSCORE:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count],返回結果的數(shù)量區(qū)間,score 從小到大排序,LIMIT 參數(shù)指定返回結果集的數(shù)量和區(qū)間,后面可選的 [limit offset count] 像 SQL 中的 select ... limit offset,count。
  6. ZREVRANGEBYSCORE:與上面 ZRANGEBYSCORE 幾乎相同,不同是 score 是從大到小排序
  7. ZREVRANGEBYSCOREWITHSCORES:和 ZRANGEBYSCORE 一樣,區(qū)別是它不僅返回集合元素,也返回元素對應分數(shù)
  8. ZREM:刪除元素
  9. ZREMRANGEBYRank:根據(jù)索引范圍刪除
  10. ZREMRANGEBYSCORE:根據(jù)分數(shù)區(qū)間刪除

還有 ZCOUNT 獲取區(qū)間內元素個數(shù);ZCARD 獲取元素個數(shù);ZINCRBY 增加元素分數(shù);ZRANK 根據(jù)元素查詢在集合中的排名,分數(shù)從小到大排序查詢。

代碼示例:

Copy

package?main

import?(

"context"

"fmt"

"time"

"github.com/go-redis/redis/v8"

)

func?main()?{

rdb := redis.NewClient(&redis.Options{

Addr: ???????"localhost:6379",

Password: ???"",

DB: ?????????0,

IdleTimeout: 350,

PoolSize: ???50, // 連接池連接數(shù)量

})

ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)

defer?cancel()

_, err := rdb.Ping(ctx).Result() // 檢查連接redis是否成功

if?err != nil?{

fmt.Println("Connect Failed: %v \n", err)

panic(err)

}

ctx = context.Background()

// ZADD,添加一個或多個數(shù)據(jù)到集合中

//* 添加一個*/

n, err := rdb.ZAdd(ctx, "zsetkey", &redis.Z{23.0, "tom"}).Result()

/* 或把字段寫上

member := &redis.Z{

Score: ?23.0,

Member: "tom",

}

n, err := rdb.ZAdd(ctx, "zsetkey", member).Result()

if err != nil {

panic(err)

}

*/

fmt.Println("zadd: ", n)

val, _ := rdb.ZRange(ctx, "zsetkey", 0, -1).Result()

fmt.Println("ZRange, zsetkey: ", val)

//* ZADD批量增加*/

fruits_price_z := []*redis.Z{

&redis.Z{Score: 5.0, Member: "apple"},

&redis.Z{Score: 3.5, Member: "orange"},

&redis.Z{Score: 6.0, Member: "banana"},

&redis.Z{Score: 9.1, Member: "peach"},

&redis.Z{Score: 19.0, Member: "cherry"},

}

num, err := rdb.ZAdd(ctx, "fruits_price", fruits_price_z...).Result()

if?err != nil?{

panic(err)

}

fmt.Println("zadd : ", num)

// ZRANGE,索引范圍返回元素,分數(shù)從小到大, 0 到 -1 就是所有元素

vals, err := rdb.ZRange(ctx, "fruits_price", 0, -1).Result()

if?err != nil?{

panic(err)

}

fmt.Println("ZRange,fruits_price: ", vals)

// ZREVRANGE,分數(shù)從大到小

vals, err = rdb.ZRevRange(ctx, "fruits_price", 0, -1).Result()

if?err != nil?{

panic(err)

}

fmt.Println("ZRevRange,fruits_price: ", vals)

// ZRANGEBYSCORE , offset 和 count 可用于分頁

rangbyscore := &redis.ZRangeBy{

Min: ???"3", // 最小分數(shù)

Max: ???"7", // 最大分數(shù)

Offset: 0, ??// 開始偏移量

Count: ?4, ??// 一次返回多少數(shù)據(jù)

}

vals, err = rdb.ZRangeByScore(ctx, "fruits_price", rangbyscore).Result()

if?err != nil?{

panic(err)

}

fmt.Println("ZRangeByScore: ", vals)

// ZCOUNT ,統(tǒng)計某個分數(shù)內的元素個數(shù)

count, _ := rdb.ZCount(ctx, "fruits_price", "3", "7").Result()

fmt.Println("ZCount: ", count)

// ZREVRANGEBYSCOREWITHSCORES, 和 ZRANGEBYSCORE 一樣,區(qū)別是它不僅返回集合元素,也返回元素對應分數(shù)

rangbyscorewithscores := &redis.ZRangeBy{

Min: ???"3", // 最小分數(shù)

Max: ???"7", // 最大分數(shù)

Offset: 0, ??// 開始偏移量

Count: ?4, ??// 一次返回多少數(shù)據(jù)

}

keyvals, err := rdb.ZRangeByScoreWithScores(ctx, "fruits_price", rangbyscorewithscores).Result()

if?err != nil?{

panic(err)

}

fmt.Println("ZRangeByScoreWithScores: ", keyvals)

// ZCRORE, 查詢集合中元素的分數(shù)

score, _ := rdb.ZScore(ctx, "fruits_price", "peach").Result()

fmt.Println("ZScore: ", score)

// ZRANK 根據(jù)元素查詢在集合中的排名,分數(shù)從小到大排序查詢

rank, _ := rdb.ZRank(ctx, "fruits_price", "peach").Result()

fmt.Println("ZRank: ", rank)

// ZREM,根據(jù)Member刪除值,一次可以刪除一個或多個

age_z := []*redis.Z{

&redis.Z{Score: 20, Member: "tom"},

&redis.Z{Score: 34, Member: "jim"},

&redis.Z{Score: 23, Member: "lilei"},

&redis.Z{Score: 43, Member: "hanxu"},

&redis.Z{Score: 30, Member: "jimmy"},

&redis.Z{Score: 55, Member: "MA"},

&redis.Z{Score: 50, Member: "MB"},

&redis.Z{Score: 52, Member: "MC"},

&redis.Z{Score: 54, Member: "MD"},

&redis.Z{Score: 59, Member: "ME"},

&redis.Z{Score: 70, Member: "MF"},

&redis.Z{Score: 75, Member: "MG"},

}

rdb.ZAdd(ctx, "people_age", age_z...).Err()

rdb.ZRem(ctx, "people_age", "jim").Err() // 刪除一個

// rdb.ZRem(ctx, "people_age", "jim", "jimmy").Err() // 刪除多個

agevals, _ := rdb.ZRange(ctx, "people_age", 0, -1).Result()

fmt.Println("ZRem, ZRange age: ", agevals)

//ZREMRANGEBYSCORE, 根據(jù)分數(shù)區(qū)間刪除

// rdb.ZRemRangeByScore("people_age", "20", "30").Err() ?// 刪除 20<=分數(shù)<=30

rdb.ZRemRangeByScore(ctx, "people_age", "20", "(30").Err() // 刪除 20<=分數(shù)<30

agevals, _ = rdb.ZRange(ctx, "people_age", 0, -1).Result()

fmt.Println("ZRemRangeByScore, ZRange age: ", agevals)

// ZREMRANGEBYRANK,根據(jù)分數(shù)排名刪除

// 從低分到高分進行排序,然后按照索引刪除

rdb.ZRemRangeByRank(ctx, "people_age", 6, 7) // 低分到高分排序,刪除第6個元素到第7個元素

agevals, _ = rdb.ZRange(ctx, "people_age", 0, -1).Result()

fmt.Println("ZRemRangeByRank, ZRange age: ", agevals)

// 如果寫成負數(shù),那么從高分開始刪除

// rdb.ZRemRangeByRank(ctx, "people_age", -6, -7)

// ZIncrBy, 增加分數(shù)

rdb.ZIncrBy(ctx, "people_age", 12, "MG").Err()

score, _ = rdb.ZScore(ctx, "people_age", "MG").Result()

fmt.Println("ZScore: ", score)

}

/*

zadd: ?0

ZRange, zsetkey: ?[tom]

zadd : ?0

ZRange,fruits_price: ?[orange apple banana peach cherry]

ZRevRange,fruits_price: ?[cherry peach banana apple orange]

ZRangeByScore: ?[orange apple banana]

ZCount: ?3

ZRangeByScoreWithScores: ?[{3.5 orange} {5 apple} {6 banana}]

ZScore: ?9.1

ZRank: ?3

ZRem, ZRange age: ?[tom lilei jimmy hanxu MB MC MD MA ME MF MG]

ZRemRangeByScore, ZRange age: ?[jimmy hanxu MB MC MD MA ME MF MG]

ZRemRangeByRank, ZRange age: ?[jimmy hanxu MB MC MD MA MG]

ZScore: ?87

*/

到了這里,關于golang redis第三方庫github.com/go-redis/redis/v8實踐的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【深入淺出 Spring Security(十二)】使用第三方(Github)授權登錄

    【深入淺出 Spring Security(十二)】使用第三方(Github)授權登錄

    (Github授權登錄的具體操作在目錄第三“章”) 下面是《深入淺出Spring Security》書中的一段概述: OAuth 是一個開放標準(現(xiàn)在所說的 OAuth 一般都是指 OAuth2,即 2.0 版本),可以理解為是一種協(xié)議,該標準允許用戶讓第三方應用訪問該用戶在某一網(wǎng)站上存儲的私密資源(如頭

    2024年02月10日
    瀏覽(33)
  • Spring Boot整合OAuth2實現(xiàn)GitHub第三方登錄

    Github OAuth 第三方登錄示例 第三方登錄的原理是借助OAuth授權來實現(xiàn),首先用戶先向客戶端提供第三方網(wǎng)站的數(shù)據(jù)證明自己的身份獲取授權碼,然后客戶端拿著授權碼與授權服務器建立連接獲得一個Access Token,之后客戶端就可以通過Access Token來與資源服務器進行交互。 使用O

    2024年02月08日
    瀏覽(92)
  • Go學習第十八章——Gin日志與第三方工具Logrus

    Go學習第十八章——Gin日志與第三方工具Logrus

    1.1 快速入門 在使用Gin框架的過程中,日志是一個重要的組成部分,它可以記錄框架和應用程序的運行情況,幫助開發(fā)者排查問題和監(jiān)控應用程序的性能。Gin框架提供了方便的方法來設置和使用日志。 默認日志 Gin框架默認使用的是標準庫的log包,將日志輸出到控制臺。可以通

    2024年02月07日
    瀏覽(22)
  • 【OAuth2】OAuth2概述及使用GitHub登錄第三方網(wǎng)站

    【OAuth2】OAuth2概述及使用GitHub登錄第三方網(wǎng)站

    我們在瀏覽器上可以訪問成百上千個網(wǎng)站,使用每個網(wǎng)站的服務一般都要先注冊賬號,那么我們?yōu)榱烁玫赜洃?,一般都會在多個網(wǎng)站使用相同的賬號和密碼進行注冊。那么問題就來了,如果在你注冊的網(wǎng)站中有某些個網(wǎng)站的系統(tǒng)設計不夠嚴謹和安全,數(shù)據(jù)庫的用戶信息使用

    2024年01月19日
    瀏覽(59)
  • 工具-Obsidian生產力工具,安裝第三方插件(GitHub)教程,以安裝Syntax Highlight(代碼高亮)為例

    工具-Obsidian生產力工具,安裝第三方插件(GitHub)教程,以安裝Syntax Highlight(代碼高亮)為例

    在GitHub的搜索框中,直接搜索obsidian +插件名,obsidian+Syntax Highlight 點進頁面 一定要選擇release版本的! 只需要下載css json js 文件,點擊直接下載 個人習慣,每個插件,新建一個文件夾,命名好名字,放置路徑為你的obsidian 工作區(qū) 的.obsidian 文件 進入到plugins文件中 新建立文件

    2023年04月22日
    瀏覽(41)
  • redis(其它操作、管道)、django中使用redis(通用方案、 第三方模塊)、django緩存、celery介紹(celery的快速使用)

    redis(其它操作、管道)、django中使用redis(通用方案、 第三方模塊)、django緩存、celery介紹(celery的快速使用)

    1 redis其它操作 2 redis管道 3 django中使用redis 3.1 通用方案 3.2 第三方模塊 4 django緩存 5 celery介紹 5.1 celery的快速使用

    2024年02月07日
    瀏覽(26)
  • go-redis

    go-redis

    在官網(wǎng)下載redis.conf配置文件 redis官網(wǎng):http://www.redis.cn/download.html 將下載后的壓縮包解壓得到redis.conf文件,放到自己的目錄,我的是/home/yi/Project/redis/redis.conf 同時在redis目錄下創(chuàng)建data文件夾用于存放redis數(shù)據(jù) redis.conf 主流配置 bind 127.0.0.1 #注釋掉這部分,使redis可以外部訪問

    2024年02月12日
    瀏覽(49)
  • Go Redis 管道和事務之 go-redis

    Redis pipelines(管道) 允許一次性發(fā)送多個命令來提高性能,go-redis支持同樣的操作, 你可以使用go-redis一次性發(fā)送多個命令到服務器,并一次讀取返回結果,而不是一個個命令的操作。 Go Redis 管道和事務: https://redis.uptrace.dev/zh/guide/go-redis-pipelines.html 管道 Watch 監(jiān)聽 事務 通過 g

    2024年02月09日
    瀏覽(17)
  • Go語言之 go-redis 基本使用

    Redis:https://redis.io/ Redis 中文網(wǎng):https://www.redis.net.cn/ REmote DIctionary Server(Redis) 是一個由Salvatore Sanfilippo寫的key-value存儲系統(tǒng)。 Redis是一個開源的使用ANSI C語言編寫、遵守BSD協(xié)議、支持網(wǎng)絡、可基于內存亦可持久化的日志型、Key-Value數(shù)據(jù)庫,并提供多種語言的API。 它通常被稱為

    2024年02月09日
    瀏覽(24)
  • Python第三方庫安裝教程、什么是第三方庫

    Python有一個全球社區(qū):https://pypi.org/,在這里我們可以搜索任何主題的Python第三方庫。PyPI全稱是Python Package Index,指的是Python包的索引,它由PSF(Python Software Foundation)來維護,并且展示全球Python計算生態(tài)。 我們需要學會利用PyPI的主站檢索,找到我們使用和關心的Python第三方

    2024年02月03日
    瀏覽(94)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包