中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么利用Redis實現點贊功能

發布時間:2022-06-29 14:26:49 來源:億速云 閱讀:207 作者:iii 欄目:開發技術

這篇文章主要介紹“怎么利用Redis實現點贊功能”,在日常操作中,相信很多人在怎么利用Redis實現點贊功能問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么利用Redis實現點贊功能”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

MySQL 和 Redis優缺點

首先我們來說一下兩種方法各自的優缺點:我們以 MySQL 和 Redis 為例。

1、直接寫入數據庫:

優點:這種方法實現簡單,只需完成數據庫的增刪改查就行;

缺點:數據庫讀寫壓力大,如果遇到熱門文章在短時間內被大量點贊的情況,直接操作數據庫會給數據庫帶來巨大壓力,影響效率。

2、使用 Redis 緩存:

優點:性能高,讀寫速度快,緩解數據庫讀寫的壓力;

缺點:開發復雜,不能保證數據安全性即 redis 掛掉的時候會丟失數據, 同時不及時同步 redis 中的數據, 可能會在 redis 內存置換的時候被淘汰掉。不過對于點贊數據我們不需要那么精確,丟失一點數據問題不大。

接下來就從以下三個方面對點贊功能做詳細的介紹

•Redis 緩存設計

•數據庫設計

•開啟定時任務持久化存儲到數據庫

1、Redis 緩存設計及實現

Redis 的整合我們在上一篇文章中已經介紹過了,此處就不再贅述了。我們了解到,我們在做點贊的時候需要記錄以下幾類數據:一類是某用戶被其他用戶點贊的詳細記錄,一類是。考慮到查詢與存取方便快捷,我這邊采用 Hash 結構進行存儲,存儲結構如下:

(1)某用戶被其他用戶點贊的詳細記錄: MAP_USER_LIKED 為鍵值, 被點贊用戶id::點贊用戶id 為 filed, 1或者0 為 value

(2)某用戶被點贊的數量統計: MAP_USER_LIKED_COUNT 為鍵值, 被點贊用戶id 為 filed, count 為 value

部分代碼如下

/**
* 將用戶被其他用戶點贊的數據存到redis
*/
@Override
public void saveLiked2Redis(String likedUserId, String likedPostId) {
    String key = RedisKeyUtils.getLikedKey(likedUserId, likedPostId);
    redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED,key, LikedStatusEnum.LIKE.getCode());
}

//取消點贊
@Override
public void unlikeFromRedis(String likedUserId, String likedPostId) {
    String key = RedisKeyUtils.getLikedKey(likedUserId, likedPostId);
    redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED,key,LikedStatusEnum.UNLIKE.getCode());
}

/**
* 將被點贊用戶的數量+1
*/
@Override
public void incrementLikedCount(String likedUserId) {
    redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT,likedUserId,1);
}

//-1
@Override
public void decrementLikedCount(String likedUserId) {
    redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, likedUserId, -1);
}

/**
* 獲取Redis中的用戶點贊詳情記錄
*/
@Override
public List<UserLikeDetail> getLikedDataFromRedis() {
    Cursor<Map.Entry<Object,Object>> scan = redisTemplate.opsForHash().scan(RedisKeyUtils.MAP_KEY_USER_LIKED, ScanOptions.NONE);
    List<UserLikeDetail> list = new ArrayList<>();
    while (scan.hasNext()){
        Map.Entry<Object, Object> entry = scan.next();
        String key = (String) entry.getKey();
        String[] split = key.split("::");
        String likedUserId = split[0];
        String likedPostId = split[1];
        Integer value = (Integer) entry.getValue();
        //組裝成 UserLike 對象
        UserLikeDetail userLikeDetail = new UserLikeDetail(likedUserId, likedPostId, value);
        list.add(userLikeDetail);
        //存到 list 后從 Redis 中刪除
        redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED, key);
    }
    return list;
}

/**
* 獲取Redis中的用戶被點贊數量
*/
@Override
public List<UserLikCountDTO> getLikedCountFromRedis() {
    Cursor<Map.Entry<Object,Object>> cursor = redisTemplate.opsForHash().scan(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, ScanOptions.NONE);
    List<UserLikCountDTO> list = new ArrayList<>();
    while(cursor.hasNext()){
        Map.Entry<Object, Object> map = cursor.next();
        String key = (String) map.getKey();
        Integer value = (Integer) map.getValue();
        UserLikCountDTO userLikCountDTO = new UserLikCountDTO(key,value);
        list.add(userLikCountDTO);
        //存到 list 后從 Redis 中刪除
        redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT,key);
    }
    return list;
}

Redis 存儲結構如圖

怎么利用Redis實現點贊功能

怎么利用Redis實現點贊功能

2、數據庫設計

這里我們可以和直接將點贊數據存到數據庫一樣,設計兩張表:

(1)用戶被其他用戶點贊的詳細記錄:user_like_detail

DROP TABLE IF EXISTS `user_like_detail`;
CREATE TABLE `user_like_detail`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `liked_user_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '被點贊的用戶id',
  `liked_post_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '點贊的用戶id',
  `status` tinyint(1) NULL DEFAULT 1 COMMENT '點贊狀態,0取消,1點贊',
  `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '創建時間',
  `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改時間',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `liked_user_id`(`liked_user_id`) USING BTREE,
  INDEX `liked_post_id`(`liked_post_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用戶點贊表' ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

(2)用戶被點贊的數量統計:user_like_count

DROP TABLE IF EXISTS `user_like_count`;
CREATE TABLE `user_like_count`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `like_num` int(11) NULL DEFAULT 0,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

3、開啟定時任務持久化存儲到數據庫

我們使用 Quartz 來實現定時任務,將 Redis 中的數據存儲到數據庫中,為了演示效果,我們可以設置一分鐘或者兩分鐘存儲一遍數據,這個視具體業務而定。在同步數據的過程中,我們首先要將 Redis 中的數據在數據庫中進行查重,舍棄重復數據,這樣我們的數據才會更加準確。

部分代碼如下

//同步redis的用戶點贊數據到數據庫
@Override
@Transactional
public void transLikedFromRedis2DB() {
    List<UserLikeDetail> list = redisService.getLikedDataFromRedis();
    list.stream().forEach(item->{
        //查重
        UserLikeDetail userLikeDetail = userLikeDetailMapper.selectOne(new LambdaQueryWrapper<UserLikeDetail>()
           .eq(UserLikeDetail::getLikedUserId, item.getLikedUserId())
           .eq(UserLikeDetail::getLikedPostId, item.getLikedPostId()));
        if (userLikeDetail == null){
            userLikeDetail = new UserLikeDetail();
            BeanUtils.copyProperties(item, userLikeDetail);
            //沒有記錄,直接存入
            userLikeDetail.setCreateTime(LocalDateTime.now());
            userLikeDetailMapper.insert(userLikeDetail);
        }else{
            //有記錄,需要更新
            userLikeDetail.setStatus(item.getStatus());
            userLikeDetail.setUpdateTime(LocalDateTime.now());
            userLikeDetailMapper.updateById(item);
        }
    });
}

@Override
@Transactional
public void transLikedCountFromRedis2DB() {
    List<UserLikCountDTO> list = redisService.getLikedCountFromRedis();
    list.stream().forEach(item->{
        UserLikeCount user = userLikeCountMapper.selectById(item.getKey());
        //點贊數量屬于無關緊要的操作,出錯無需拋異常
        if (user != null){
            Integer likeNum = user.getLikeNum() + item.getValue();
            user.setLikeNum(likeNum);
            //更新點贊數量
            userLikeCountMapper.updateById(user);
        }
    });
}

到此,關于“怎么利用Redis實現點贊功能”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

扶余县| 抚顺市| 渑池县| 新蔡县| 牙克石市| 鄂托克旗| 河曲县| 新郑市| 平乐县| 来安县| 博野县| 阆中市| 内乡县| 江城| 民勤县| 普定县| 南部县| 绥中县| 高陵县| 宜黄县| 嘉黎县| 深水埗区| 全椒县| 丹江口市| 东兴市| 屏山县| 加查县| 神木县| 秦安县| 日喀则市| 湘阴县| 定南县| 宁德市| 徐州市| 杭州市| 敖汉旗| 晴隆县| 内丘县| 永德县| 将乐县| 靖州|