redis:使用go-redis实现点赞投票功能

点赞

需要记录的信息:

  • 被点赞的信息ID
  • 点赞人
  • 点赞状态(点赞、取消点赞)

最后固定时间间隔【采用定时任务】取出 Redis 中所有点赞数据存入MYSQL中或者做持久化。

set实现

set中的数据特征是:无序,不重复,所以
如果当前用户点赞的话,判断set中是否有此成员。

  • 如果没有,就将当前用户的ID存储进入SET。
  • 如果有,将当前用户的ID移除。
127.0.0.1:6379> sismember like_id1 userID1
(integer) 0
127.0.0.1:6379> sadd like_id1 userID1
(integer) 1
127.0.0.1:6379> sismember like_id1 userID1
(integer) 1
127.0.0.1:6379> srem like_id1 userID1
(integer) 1
127.0.0.1:6379> sismember like_id1 userID1
(integer) 0
127.0.0.1:6379> SCARD like_id1 统计有多少用户点赞了这条ID
(integer) 4

package main

import (
	"fmt"
	"github.com/go-redis/redis"
)

func createClient() *redis.Client {
	client := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})

	// 通过 cient.Ping() 来检查是否成功连接到了 redis 服务器
	_, err := client.Ping().Result()
	if err != nil{
		panic(err)
	}

	return client
}
func is_like_id1(client *redis.Client, userID int){   //当前用户是否点赞
	val, err := client.SIsMember("like_id1", userID).Result()
	if err != nil{
		panic(err)
	}
	if val == false{
		fmt.Println("user don't like it")
	}

}
func like_id1_set(client *redis.Client, userID int){   //---点赞&&取消点赞
	val, err := client.SIsMember("like_id1", userID).Result()
	if err != nil{
		panic(err)
	}
	if val == false{
		_, err := client.SAdd("like_id1", userID).Result()
		if err != nil{
			panic(err)
		}
	}else{
		_, err := client.SRem("like_id1", userID).Result()
		if err != nil{
			panic(err)
		}
	}
}

func like_id1_count(client *redis.Client)(int64){   //--- 获赞次数
	val, err := client.SCard("like_id1").Result()
	if err != nil{
		panic(err)
	}
	return val
}
func main(){
	client := createClient()
	fmt.Println(client)

	like_id1_set(client, 3);
	like_id1_set(client, 4);

	fmt.Println(like_id1_count(client))
}

位图实现

bitmap是一连串的二进制数字(0,1),每一位所在的位置为偏移(offset),在bitmap上可以执行AND,OR,XOR以及其他操作。

127.0.0.1:6379> getbit like_id1 "oceanstar"  //因此位图只能是数字
(error) ERR bit offset is not an integer or out of range
127.0.0.1:6379> getbit like_id1 100   //查看ID为100的数字是否点赞
(integer) 0
127.0.0.1:6379> setbit like_id1 100 1   //点赞
(integer) 0
127.0.0.1:6379> getbit like_id1 100
(integer) 1
127.0.0.1:6379> setbit like_id1 100 0   //取消点赞
(integer) 1
127.0.0.1:6379> getbit like_id1 100
(integer) 0
127.0.0.1:6379> bitcount like_id1   //有多少人点赞
(integer) 0

位图还可以进行位操作:AND , OR,XOR,NOT。

package main

import (
	"fmt"
	"github.com/go-redis/redis"
)

func createClient() *redis.Client {
	client := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",
		DB:       0,
	})

	// 通过 cient.Ping() 来检查是否成功连接到了 redis 服务器
	_, err := client.Ping().Result()
	if err != nil{
		panic(err)
	}

	return client
}


func like_id1_bitmap(client *redis.Client, userID int64){
	val, err :=client.GetBit("like_id1", userID).Result()
	if err != nil{
		panic(err)
	}
	if val == 0{
		_, err =client.SetBit("like_id1", userID, 1).Result()
		if err != nil{
			panic(err)
		}
	}else{
		_, err =client.SetBit("like_id1", userID, 0).Result()
		if err != nil{
			panic(err)
		}
	}
}

func count_like_id1(client *redis.Client)(int64){
	var bit redis.BitCount
	bit.Start = 0
	bit.End = -1
	val, err := client.BitCount("like_id1", &bit).Result()
	if err != nil{
		panic(err)
	}
	return val

}
func main(){
	client := createClient()
	fmt.Println(client)

	like_id1_bitmap(client, 200)
	fmt.Println(count_like_id1(client))
}

总结:
位图是由bit组成的数组。Redis中的位图不是一种新的数据类型,它的底层是字符串。因为字符串本质上是二进制大对象blob,所以可以视为位图。同时因为位图存储的是布尔信息,所以在某些情况下可以节省大量的内存空间。

应用场景:

  • “用户是否曾经用过Relp中某个功能”
    比如:有多少人表示喜欢,有多少人在线
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值