Heim  >  Artikel  >  Datenbank  >  So implementieren Sie die Like-Funktion mit Redis

So implementieren Sie die Like-Funktion mit Redis

WBOY
WBOYnach vorne
2023-05-27 22:37:042908Durchsuche

Vor- und Nachteile von MySQL und Redis

Lassen Sie uns zunächst über die Vor- und Nachteile der beiden Methoden sprechen: Nehmen wir MySQL und Redis als Beispiele.

1. Schreiben Sie direkt in die Datenbank:

Vorteile: Diese Methode ist einfach zu implementieren und muss nur das Hinzufügen, Löschen, Ändern und Abfragen der Datenbank abschließen;

Nachteile: Die Datenbank steht unter großem Lese- und Schreibdruck. Wenn ein beliebter Artikel in kurzer Zeit viele Likes erhält, übt der direkte Betrieb der Datenbank einen großen Druck auf die Datenbank aus die Effizienz beeinträchtigen.

2. Verwenden Sie den Redis-Cache:

Vorteile: hohe Leistung, schnelle Lese- und Schreibgeschwindigkeit, wodurch der Druck beim Lesen und Schreiben von Datenbanken verringert wird; Nachteile: Die Entwicklung ist komplex und kann die Datensicherheit nicht garantieren, d. Allerdings müssen wir bei den Like-Daten nicht so genau sein, und der Verlust einiger Daten ist kein großes Problem.

Das Folgende ist eine detaillierte Einführung in die Like-Funktion aus den folgenden drei Aspekten

•Redis-Cache-Design

# 🎜 🎜#•Datenbankdesign

•Persistente Speicherung geplanter Aufgaben in der Datenbank aktivieren

1. Redis-Cache-Design und -Implementierung

Wir haben Wie man Redis integriert, wurde im vorherigen Artikel vorgestellt, daher werde ich die Anweisungen hier nicht wiederholen. Wir sind uns darüber im Klaren, dass bei der Durchführung eines Like-Vorgangs die folgenden Daten aufgezeichnet werden müssen: detaillierte Aufzeichnungen über Benutzer, die von anderen Benutzern geliked wurden, und Aufzeichnungen über Like-Vorgänge. Um die Abfrage und den Zugriff zu erleichtern, habe ich eine Hash-Struktur für die Speicherung verwendet. Die Speicherstruktur ist wie folgt:

(1) Detaillierte Aufzeichnungen darüber, wie ein Benutzer anderen Benutzern gefällt: MAP_USER_LIKED ist der Schlüsselwert, Liked-Benutzer-ID:: Die Liked-Benutzer-ID wird abgelegt, 1 oder 0 ist der Wert<p></p> (2) Statistik der Anzahl der Likes für einen Benutzer: <code>MAP_USER_LIKED_COUNT ist der Schlüsselwert, die Like-Benutzer-ID wird abgelegt, <code>count ist der Wert

MAP_USER_LIKED 为键值, 被点赞用户id::点赞用户id 为 filed, 1或者0 为 value

(2)某用户被点赞的数量统计: MAP_USER_LIKED_COUNT 为键值, 被点赞用户id 为 filed, countEin Teil des Codes lautet wie folgt

/**
* 将用户被其他用户点赞的数据存到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 Die Speicherstruktur ist wie gezeigt Wir können direkt liken. Entwerfen Sie wie beim Speichern von Daten in der Datenbank zwei Tabellen:

(1) Detaillierte Aufzeichnungen der Benutzer, die von anderen Benutzern geliked wurden: 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;

(2 ) Gefällt mir Benutzeranzahl Statistiken: user_like_countSo implementieren Sie die Like-Funktion mit Redis

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. Aktivieren Sie die dauerhafte Speicherung geplanter Aufgaben in der Datenbank

So implementieren Sie die Like-Funktion mit RedisWir verwenden Quartz, um geplante Aufgaben zu implementieren und Daten in Redis zu speichern Um den Effekt zu demonstrieren, können wir festlegen, dass die Daten je nach Unternehmen eine oder zwei Minuten lang gespeichert werden. Beim Synchronisieren von Daten müssen wir zunächst die Daten in Redis in der Datenbank überprüfen und doppelte Daten verwerfen, damit unsere Daten genauer sind.

Ein Teil des Codes lautet wie folgt

//同步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);
        }
    });
}

Das obige ist der detaillierte Inhalt vonSo implementieren Sie die Like-Funktion mit Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen