Maison > base de données > Redis > le corps du texte

Comment utiliser Redis pour implémenter la fonction like

WBOY
Libérer: 2023-05-27 22:37:04
avant
2883 Les gens l'ont consulté

Avantages et inconvénients de MySQL et Redis

Tout d'abord, parlons des avantages et des inconvénients des deux méthodes : Prenons MySQL et Redis comme exemples.

1. Écrivez directement dans la base de données :

Avantages : Cette méthode est simple à mettre en œuvre, et ne nécessite que l'ajout, la suppression, la modification et l'interrogation de la base de données ;

Inconvénients : La base de données est soumise à une forte pression de lecture et d'écriture. Si un article populaire reçoit un grand nombre de likes en peu de temps, l'exploitation directe de la base de données exercera une grande pression sur la base de données et affecter l’efficacité.

2. Utilisez le cache Redis :

Avantages : hautes performances, vitesse de lecture et d'écriture rapide, atténuant la pression de lecture et d'écriture de la base de données

 ; Inconvénients : développement Il est complexe et ne peut pas garantir la sécurité des données, c'est-à-dire que les données seront perdues lorsque Redis se bloque. En même temps, si les données dans Redis ne sont pas synchronisées dans le temps, elles peuvent être éliminées lors du remplacement de la mémoire Redis. Cependant, nous n’avons pas besoin d’être aussi précis sur les données similaires, et perdre un peu de données n’est pas un gros problème.

Ce qui suit est une introduction détaillée à la fonction like sous les trois aspects suivants

•Conception du cache Redis

# 🎜 🎜#•Conception de base de données

•Activer le stockage persistant des tâches planifiées dans la base de données

1. Conception et mise en œuvre du cache Redis

Nous avons. Dans l'article précédent, j'ai présenté comment intégrer Redis, je ne le répéterai donc pas ici. Nous comprenons que lors de l'exécution d'une opération similaire, les données suivantes doivent être enregistrées : des enregistrements détaillés des utilisateurs appréciés par d'autres utilisateurs et des enregistrements d'opérations similaires. Afin de faciliter les requêtes et l'accès, j'ai utilisé une structure de hachage pour le stockage. La structure de stockage est la suivante :

(1) Enregistrements détaillés d'un utilisateur apprécié par d'autres utilisateurs : MAP_USER_LIKED<.> est la valeur clé, Identifiant de l'utilisateur apprécié : L'identifiant de l'utilisateur apprécié est déposé, 1 ou 0 est la valeur<p><code>MAP_USER_LIKED 为键值, 被点赞用户id::点赞用户id 为 filed, 1或者0 为 value

(2)某用户被点赞的数量统计: MAP_USER_LIKED_COUNT 为键值, 被点赞用户id 为 filed, count (2) Statistiques du nombre de likes pour un utilisateur : MAP_USER_LIKED_COUNT est la valeur clé, l'identifiant de l'utilisateur aimé est archivé, <code>count est la valeur

Une partie du code est la suivante

/**
* 将用户被其他用户点赞的数据存到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;
}
Copier après la connexion

Redis La structure de stockage est comme indiqué#🎜 🎜#

Comment utiliser Redis pour implémenter la fonction like

Comment utiliser Redis pour implémenter la fonction like

2. nous pouvons aimer directement De la même manière que stocker des données dans la base de données, concevoir deux tableaux :

(1) Enregistrements détaillés des utilisateurs appréciés par d'autres utilisateurs : 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 &#39;被点赞的用户id&#39;,
  `liked_post_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT &#39;点赞的用户id&#39;,
  `status` tinyint(1) NULL DEFAULT 1 COMMENT &#39;点赞状态,0取消,1点赞&#39;,
  `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT &#39;创建时间&#39;,
  `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT &#39;修改时间&#39;,
  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 = &#39;用户点赞表&#39; ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;
Copier après la connexion

(2 ) Utilisateurs appréciés Statistiques de quantité : 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;
Copier après la connexion

3. Activer le stockage persistant des tâches planifiées dans la base de données

Nous utilisons Quartz pour implémenter les tâches planifiées et stocker les données dans Redis dans le base de données. Afin de démontrer l'effet, nous pouvons définir les données à stocker pendant une minute ou deux minutes, en fonction de l'entreprise spécifique. Dans le processus de synchronisation des données, nous devons d'abord vérifier les données dans Redis dans la base de données et éliminer les données en double, afin que nos données soient plus précises.

Une partie du code est la suivante

//同步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);
        }
    });
}
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!