目 录CONTENT

文章目录
Go

go-redis操作redis数据库

Hello!你好!我是村望~!
2023-02-17 / 0 评论 / 0 点赞 / 155 阅读 / 1,580 字
温馨提示:
我不想探寻任何东西的意义,我只享受当下思考的快乐~

参考链接

Redis应用场景

  • 缓存系统,减轻主数据库(MySQL)的压力。
  • 计数场景,比如微博、抖音中的关注数和粉丝数。
  • 热门排行榜,需要排序的场景特别适合使用ZSET。
  • 利用 LIST 可以实现队列的功能。
  • 利用 HyperLogLog 统计UV、PV等数据。
  • 使用 geospatial index 进行地理位置相关查询。

Redis 有 6 种基础数据结构,

它们分别是:string(字符串)list(列表)hash(字典)set(集合) 、 **zset(有序集合)**和 Stream(流)

这 6 种是 Redis 相关知识中最基础、最重要的部分。

环境准备

同样使用 docker 启动一个 redis 的服务,比较方便,下面是 docker-compose 文件!

# Use root/example as user/password credentials
version: '3.1'

services:
  redisDb:
    container_name: redisDB
    image: redis
    restart: always
    ports:
      - 6379:6379
    volumes:
      - /Users/hope/sdy/temp_go_test/redis:/data

启动测试

❯ docker-compose up -d
Recreating go-dirver-mysql-test ... done
Creating redisDB                ... done

❯ docker container ls -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                               NAMES
d2d8acf11d79   mysql     "docker-entrypoint.s…"   16 seconds ago   Up 15 seconds   0.0.0.0:3306->3306/tcp, 33060/tcp   go-dirver-mysql-test
e54abf029737   redis     "docker-entrypoint.s…"   20 seconds ago   Up 18 seconds   0.0.0.0:6379->6379/tcp              redisDB

那么环境就准备好了!

安装&连接

使用以下命令下安装 go-redis 库。

go get -u github.com/go-redis/redis

引入使用!

封装到初始化模块! initialization

package initialization

import (
	"fmt"

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

func InitRedisDB() (rdb *redis.Client, err error) {
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // 没有密码设置 no password set
		DB:       0,  // 默认 db use default DB
	})
	sc := rdb.Ping()
	if sc.Err() != nil {
		return nil, sc.Err()
	}
	fmt.Println("redis connect successfully!")
  return //tips:这里的返回值中有有变量名,所以直接return就行了!
}

main 中执行初始化!

package main

import (
	"gotest/initialization"

	"github.com/go-redis/redis"
	"github.com/jmoiron/sqlx"
)

var sqlxDB *sqlx.DB
var err error
var rdb *redis.Client

func main() {
	sqlxDB, err = initialization.InitSqlxDB()
	if err != nil {
		panic("数据库连接失败" + err.Error())
	}
	defer sqlxDB.Close()

	rdb, err = initialization.InitRedisDB()
	if err != nil {
		panic("redis 连接失败" + err.Error())
	}
	defer rdb.Close()
}

执行 go 程序! Ok 的!

❯ go run main.go
data base connect successfully! 
redis connect successfully!

redis set/get 存string(字符串)

func TestGetSet() {
	s, err := rdb.Set("test", "1", time.Hour).Result()
	if err != nil {
		panic(err)
	}
	fmt.Println(s)
	s, err = rdb.Get("test").Result()
  //  rdb.Get("test").Val() 也可以直接返回值!
	if err != nil {
		panic(err)
	}
	fmt.Println(s)
}

执行

❯ go run main.go
data base connect successfully! 
redis connect successfully!
OK
1

RDM 中查看数据!

image-20230217164248443

redis hashSet/hashGet 存 hash(字典)

  • HSet(target,key,value).Result()
  • HGet(key,value).Result() || ( HGet(key,value).Val() 直接返回值!)
  • HGetAll(target).Result() -> map 返回完整的 target 字典 map类型!
  • HMGetAll(target,...fields) -> 返回字段在 target hash字典中对应的值,这些值是放在一个slice切片中!
func TestHashGetSet() {
	_, err = rdb.HSet("family", "dad", "jack").Result()
	_, err = rdb.HSet("family", "mom", "marry").Result()
	_, err = rdb.HSet("family", "son", "tom").Result()
	if err != nil {
		panic(err)
	}
	r1, err := rdb.HGet("family", "dad").Result()
	if err != nil {
		panic(err)
	}
	r2, err := rdb.HGet("family", "mom").Result()
	if err != nil {
		panic(err)
	}
	r3 := rdb.HGet("family", "son").Val()
	if err != nil {
		panic(err)
	}
	r4, err := rdb.HGetAll("family").Result()
	if err != nil {
		panic(err)
	}
	r5, err := rdb.HMGet("family", "mom", "son").Result()
	fmt.Println(r1)
	fmt.Println(r2)
	fmt.Println(r3)
	fmt.Println(r4)
	fmt.Println(r5)
}

执行

❯ go run main.go
data base connect successfully! 
redis connect successfully!
jack
marry
tom
map[dad:jack mom:marry son:tom]
[marry tom]

RDM 中查看数据!

image-20230217165031188

redis 操作 zset 有序集合

常用 redis zset 操作命令

redis.Z 结构体

redis.Z 是 go-redis 提供的一个结构体!用来初始化一个根据 Score 排序 (sorted) 的集合!

// Z represents sorted set member.
type Z struct {
	Score  float64
	Member interface{}
}

ZAdd 添加 zset 集合 到 redis

// Redis `ZADD key score member [score member ...]` command.
func (c *cmdable) ZAdd(key string, members ...Z) *IntCmd 

添加 zset 集合 到 redis

// key
zsetKey := "language_rank"
languages := []redis.Z{
	{Score: 90.0, Member: "Golang"},
	{Score: 98.0, Member: "Java"},
	{Score: 95.0, Member: "Python"},
	{Score: 97.0, Member: "JavaScript"},
	{Score: 99.0, Member: "C/C++"},
}

i, err := rdb.ZAdd(zsetKey, languages...).Result()
if err != nil {
	panic(err.Error())
}
fmt.Print(i) // 5

RDM 查看一下!

image-20230217172442180

ZIncrBy 修改redis.Z成员的Score

func (c *cmdable) ZIncrBy(key string, increment float64, member string) *FloatCmd 

increment 传入正数代表+传入负数代表-

func TestZset() {
	// key
	zsetKey := "language_rank"
	languages := []redis.Z{
		{Score: 90.0, Member: "Golang"},
		{Score: 98.0, Member: "Java"},
		{Score: 95.0, Member: "Python"},
		{Score: 97.0, Member: "JavaScript"},
		{Score: 99.0, Member: "C/C++"},
	}

	i, err := rdb.ZAdd(zsetKey, languages...).Result()
	if err != nil {
		panic(err.Error())
	}
  
	fmt.Println(i) // 5
  
	f := rdb.ZIncrBy(zsetKey, 10, "Golang").Val() // Val 返回加后的值!
	if err != nil {
		panic(err.Error())
	}
	fmt.Println(f) // 100
}

image-20230217174148769

注意这个操作只能对已经添加到redis 的 set 值生效!

zsetKey := "language_rank"
languages := []redis.Z{
	{Score: 90.0, Member: "Golang"},
	{Score: 98.0, Member: "Java"},
	{Score: 95.0, Member: "Python"},
	{Score: 97.0, Member: "JavaScript"},
	{Score: 99.0, Member: "C/C++"},
}

// 先修改
f := rdb.ZIncrBy(zsetKey, 10, "Golang").Val()
if err != nil {
	panic(err.Error())
}
fmt.Println(f) 

// 然后 add 
i, err := rdb.ZAdd(zsetKey, languages...).Result()
if err != nil {
	panic(err.Error())
}
fmt.Println(i) 

可以看到这种情况没有修改成功!

image-20230217174901764

ZRevRangeWithScores 从大到小取指定个数元素

func (c *cmdable) ZRevRangeWithScores(key string, start, stop int64)

有序集成员按分数值递减**(从大到小)**的次序排列,取 [start-stop]的元素!注意元素索引从 0 开始!

z, err := rdb.ZRevRangeWithScores(zsetKey, 0, 3).Result() // [0,1,2,3]
if err != nil {
	panic(err.Error())
}
fmt.Print(z) // [   {100 Golang}   {99 C/C++}   {98 Java}   {97 JavaScript}  ] 

ZRangeByScore 取指定区间的元素

对应 Redis Zrangebyscore 命令

使用方式:

// 找到 95-98分之间!
r, err := rdb.ZRangeByScore(zsetKey, redis.ZRangeBy{
	Min: "95",
	Max: "98",
}).Result()
if err != nil {
	panic(err.Error())
}
fmt.Print(r) // [Python JavaScript Java]

更多的,以后再业务场景参考redis命令!

0

评论区