Redian新闻
>
Golang连接redis数据库,并操作Sort Set有序集合实现排行榜,使用结构体进行封装

Golang连接redis数据库,并操作Sort Set有序集合实现排行榜,使用结构体进行封装

公众号新闻


排行榜功能是一个很普遍的需求,对于这类需求如果数据总量过大用mysql实现的话会很浪费性能。


select * from rank_name order by score desc limit 0,10

这时候可以考虑使用redis中的有序集合来实现(以下是会用到的一些命令)


  • zrange 查看排行榜 (升序)

  • zrevrange 查看排行榜 (降序)

  • zadd 添加一个数据

  • zrem 删除一个数据

  • zrank 获取排名(升序)

  • zrevrank 获取排名 (降序)


以下是golang代码实现


c1,err := redis.Dial("tcp","127.0.0.1:6379")    if err != nil {        panic(err)    }    defer c1.Close()    _, err = c1.Do("zrange","rank_name","0","-1","withscores")    if err != nil {        return    }    for i := 0; i <100; i++ {        c1.Do("zadd","rank_name",rand.Intn(1000),"张"+strconv.Itoa(i))    }    do, err := redis.ByteSlices(c1.Do("zrange", "rank_name", 0, -1,"withscores"))    if err != nil {        return    }    for _, v := range do {        fmt.Println(string(v))    }

以下是运行结果,可以看到数据已经按照score排序了


其他例子,普通方式:使用参数


这种方式(method(conn, …))需要将其写在参数中,比较繁琐,也不便于找到其相关的方法,于是我们对其进行了结构体封装,请略过以下代码!


package main
import ( "fmt" "github.com/garyburd/redigo/redis")
func main() { conn := redisConnect() defer conn.Close()
setString(conn, "country", "China") getString(conn, "country")
}
// connect redisfunc redisConnect() redis.Conn { conn, err := redis.Dial("tcp", "127.0.0.1:6379") if err != nil { fmt.Println("connect redis error:", err) return nil } fmt.Println("connect redis success!")
return conn}
// setString SET filed valuefunc setString(conn redis.Conn, field string, value interface{}) { _, _ = conn.Do("SET", field, value)}
// getString GET fieldfunc getString(conn redis.Conn, field string) { res, _ := redis.String(conn.Do("GET", field)) fmt.Printf("Get %s: %s \n", field, res)}

使用结构体封装进行方法调用

使用这种方式(db.method(…))进行封装,不仅便于书写,而且也更容易找到相关的方法来调用
package main
import ( "fmt" "github.com/garyburd/redigo/redis" "log" "reflect")
func main() { conn := RedisConnect() defer conn.Close()
// 认证信息 // if _, err := conn.Do("username", "password"); err != nil { // conn.Close() // }
db := Conn{conn}
// 删:key键 // db.DelKey("score") // 删:单条数据 // db.DelSortSetByField("score", "Tom")
// 增 db.SetSortSet("score", 96, "Coulson") db.SetSortSet("score", 92, "Tom") db.SetSortSet("score", 97, "Jack") // 查:长度 fmt.Println(db.GetSortSetLength("score")) // 查:排名(asc: 升序, desc: 降序, int: 降序前n条数据) nameRank, scoreRank := db.RankSortSet("score", "asc") fmt.Println(nameRank, scoreRank) // 查:单条数据 fmt.Println(db.GetSortSetByField("score", "Tom"))
}
// RedisConnect connect redisfunc RedisConnect() redis.Conn { conn, err := redis.Dial("tcp", "127.0.0.1:6379") if err != nil { fmt.Println("connect redis error:", err) return nil } fmt.Println("connect redis success!")
return conn}
type Conn struct { redis.Conn}
func (conn *Conn) DelKey(key string) { _, err := conn.Do("DEL", key) if err != nil { log.Printf("Failed to del the key: %s \n", key) } fmt.Printf("success to del the key: %s! \n", key)}
// SetSortSet ZADD key ...func (conn *Conn) SetSortSet(key string, value int, field string) { _, err := conn.Do("ZADD", key, value, field) if err != nil { // error: WRONGTYPE Operation against a key holding the wrong kind of value log.Printf("Already exist duplicate keys: `%s` \n", key) panic(err) } log.Printf("success to set key: %s %d %s", key, value, field)}
// GetSortSetLength ZCARD keyfunc (conn *Conn) GetSortSetLength(key string) interface{} { res, err := conn.Do("ZCARD", key) if err != nil { panic(err) } return res}
// RankSortSet sortfunc (conn *Conn) RankSortSet(key string, limit interface{}) (nameArr []string, valueArr []string) { // ZRANGE score 0 -1 WITHSCORES # 递增排列 // ZRANGE salary 0 <n> WITHSCORES # [0, n) // fmt.Println(reflect.TypeOf(limit).Name()) cmd, index := "ZREVRANGE", -1 switch { case limit == "asc": cmd = "ZRANGE" index = -1 case limit == "desc": cmd = "ZREVRANGE" index = -1 case reflect.TypeOf(limit).Name() == "int" && int(reflect.ValueOf(limit).Int()) > 0: index = int(reflect.ValueOf(limit).Int()) - 1 default: cmd = "ZREVRANGE" index = -1 } // scoreMap, err := redis.StringMap(conn.Do("ZRANGE", "score", 0, -1, "withscores")) scoreMap, err := redis.StringMap(conn.Do(cmd, "score", 0, index, "withscores")) if err != nil { log.Printf("Failed to rank by key %s \n", key) } // sort for name := range scoreMap { nameArr = append(nameArr, name) valueArr = append(valueArr, scoreMap[name]) } return nameArr, valueArr}
// GetSortSetByField 获取单个数据func (conn *Conn) GetSortSetByField(field string, value interface{}) interface{} { res, err := redis.Int(conn.Do("ZSCORE", field, value)) if err != nil { log.Printf("can't find %v of %v \n", field, value) } return res}
// DelSortSetByField 删除单条数据func (conn *Conn) DelSortSetByField(field string, value interface{}) interface{} { res, err := conn.Do("ZREM", field, value) if err != nil { log.Printf("failed to del %v by %v \n", field, value) } return res}


链接:blog.csdn.net/weixin_56461542/article/details/125323800

(版权归原作者所有,侵删)


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
“天然叶酸”食物排行榜,防卒中,不痴呆,还有很多人不知道的!《山居续忆》:第三章:三叔祖礼耕先生 (五)在阿里达摩院搞了四年数据库,我来聊聊实际情况 | 卓越技术团队访谈录突发!澳国防部高层陷入其中,黑客袭击8家香格里拉酒店数据库,大量数据泄露我,PolarDB云原生数据库,5年来实现这些重磅技术创新后悔The Pet Industry Is Booming. So Are Its Horrific Breeding Mills.阿里云已将 Serverless 数据库大规模落地,这是否代表着数据库的新风向?最适合秋天吃的肉类排行榜,猪肉倒数第一,鸡肉第二,建议了解九大投行|Credit Suisse Securities Research Spring Program正在进行中!顶级投行|Credit Suisse 2023 Asset Management Analyst Program正在进行中!For Gen-Z, Entrepreneurship Represents a Ticket to Freedom全球最佳智慧医院排行榜,中国为何零上榜?程序员天梯排行榜,你在哪一级?动物交配时长排行榜,看完又自信了!如此的诗,你怎么看?最新全球各大城市物价排行榜,香港第1,特拉维夫第6,上海北京前10More Air Conditioning Workers Died This Summer: Media Report[视听] 承接R10P技术下放?瞧瞧HIFIMAN SUNDARA-C能否做个有潜力的耳机hǎo xiǎng “rua” 🤩名企排名|中国&全球投行排行榜,留学生求职必备!2022福布斯富豪排行榜,前400名富豪四分之一毕业于这11所美国大学!Young Chinese Are Overdosing on Cough Meds to Combat Stress14名纽约市议员提案,废除警局黑帮数据库,华人炸锅愤怒不已拉郎配​能让天津人放下煎饼馃子的,也就那碗捞(láo)面了!Tencent Halts E-Reader Service Following Kindle’s China Retreat给宝宝做IQ Test有必要吗?常用IQ Test有哪些?全国各省花钱排行榜,你拖后腿了吗KTV Fined for Offering Songs by ‘Tainted Artist’ Kris Wu数据库“焕然新生”:架构视角下,云原生数据库的创新实践 | Q推荐《西罗普郡一少年》:22: 街上传来士兵行进的声响零食添加剂排行榜,有你的最爱吗酸了!6大热点6篇5分+SCI,只需14个精准匹配数据库,赢麻了!More Chinese Minors Are Online But Fewer Addicted, Report Says
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。