点赞
需要记录的信息:
- 被点赞的信息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中某个功能”
比如:有多少人表示喜欢,有多少人在线