首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java 實現點贊防重複:資料庫設計與查詢邏輯

     編輯:程式設計綜合問答

錯誤表設計

Goods 表:
id | goods(贊數) | news_id | user_id
// 贊數冗余存放在關聯表,導致一致性難維護

正確設計:關聯表僅存關係

CREATE TABLE article_like (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    article_id BIGINT NOT NULL,   -- 對應 news_id
    user_id BIGINT NOT NULL,
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
    UNIQUE KEY uk_article_user (article_id, user_id) -- 唯一索引防重
);

業務邏輯實現


public boolean likeArticle(long articleId, long userId) {
    // 1. 嘗試插入,利用唯一索引防重
    String sql = "INSERT IGNORE INTO article_like (article_id, user_id) VALUES (?, ?)";
    int rows = jdbcTemplate.update(sql, articleId, userId);
    if (rows > 0) {
        // 2. 成功則原子增文章贊數
        jdbcTemplate.update("UPDATE article SET like_count = like_count + 1 WHERE id = ?", articleId);
        return true;
    }
    return false; // 已點贊
}

關鍵點解析

  • 唯一索引:uk_article_user 保証數據庫層面絕對不重複,無需應用層加鎖。
  • INSERT IGNORE:MySQL 語法,重複鍵不報錯只返回 0 行影響,簡化判斷邏輯。
  • 贊數冗余:文章表保留 like_count 字段供高頻讀取,由觸發器或應用層同步更新,避免每次 COUNT(*) 掃描大表。
  • 事務控制:插入關係與更新計數需在同一事務中,保證一致性。

擴展:取消點贊


public boolean unlikeArticle(long articleId, long userId) {
    int rows = jdbcTemplate.update("DELETE FROM article_like WHERE article_id=? AND user_id=?", articleId, userId);
    if (rows > 0) {
        jdbcTemplate.update("UPDATE article SET like_count = like_count - 1 WHERE id = ?", articleId);
        return true;
    }
    return false;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved