Pertama sekali, mari kita bincangkan tentang kelebihan dan kekurangan kedua-dua kaedah: Mari kita ambil MySQL dan Redis sebagai contoh.
1. Tulis terus ke pangkalan data:
Kebaikan: Kaedah ini mudah dilaksanakan, dan hanya perlu melengkapkan penambahan, pemadaman, pengubahsuaian dan semakan pangkalan data
Kelemahan: Pangkalan data berada di bawah tekanan yang hebat untuk membaca dan menulis, jika artikel popular menerima jumlah suka yang besar dalam tempoh yang singkat, mengendalikan pangkalan data secara langsung akan memberi tekanan yang besar pada pangkalan data dan menjejaskan kecekapan.
2. Gunakan cache Redis:
Kelebihan: prestasi tinggi, kelajuan membaca dan menulis yang cepat, mengurangkan tekanan membaca dan menulis pangkalan data
Kelemahan: pembangunan kompleks, data keselamatan tidak dapat dijamin Masalahnya ialah data akan hilang apabila redis hang Pada masa yang sama, jika data dalam redis tidak disegerakkan dalam masa, ia mungkin dihapuskan apabila memori redis diganti. Walau bagaimanapun, kami tidak perlu begitu tepat tentang data yang serupa, dan kehilangan sedikit data bukanlah masalah besar.
Berikut ialah pengenalan terperinci kepada fungsi serupa daripada tiga aspek berikut
•Redis cache design
•Reka bentuk pangkalan data
•Dayakan penyimpanan berterusan tugas berjadual ke pangkalan data
Kami telah memperkenalkan cara mengintegrasikan Redis dalam artikel sebelumnya, di sini saya menang'. t ulangi penjelasan lagi. Kami faham bahawa apabila melakukan operasi serupa, data berikut perlu direkodkan: rekod terperinci pengguna yang disukai oleh pengguna lain dan rekod operasi serupa. Untuk memudahkan pertanyaan dan akses, saya menggunakan struktur Hash untuk storan Struktur storan adalah seperti berikut:
(1) Rekod terperinci pengguna yang disukai oleh pengguna lain: MAP_USER_LIKED
ialah nilai utama. , dan disukai Id pengguna:: Seperti id pengguna difailkan, 1 atau 0 ialah nilai
(2) Statistik bilangan suka untuk pengguna: MAP_USER_LIKED_COUNT
ialah nilai utama dan pengguna yang disukai id difailkan, count
Sebahagian daripada kod untuk nilai
/** * 将用户被其他用户点赞的数据存到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; }
Di sini kita boleh mereka bentuk dua jadual sama seperti menyimpan terus data seperti itu ke pangkalan data:
(1) Rekod terperinci pengguna sedang disukai oleh pengguna lain: 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) Statistik bilangan suka untuk pengguna: 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;
Kami menggunakan Kuarza untuk melaksanakan tugas berjadual dan menggunakan Redis Data dalam disimpan dalam pangkalan data Untuk menunjukkan kesannya, kami boleh menetapkan data untuk disimpan sekali dalam satu minit atau dua minit, bergantung pada perniagaan tertentu. Dalam proses penyegerakan data, kita mesti menyemak data dalam Redis dalam pangkalan data dan membuang data pendua, supaya data kita akan lebih tepat.
//同步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); } }); }
Atas ialah kandungan terperinci Cara menggunakan Redis untuk melaksanakan fungsi serupa. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!