溫馨提示×

溫馨提示×

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

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

redis應用場景(1)一個文字投票網(wǎng)站

發(fā)布時間:2020-07-23 01:49:11 來源:網(wǎng)絡 閱讀:2450 作者:randy_shandong 欄目:數(shù)據(jù)庫

構(gòu)建一個文章投票網(wǎng)站,一般具備下面幾個功能

發(fā)布文章

文章投票評分(按投票多少進行評分)

文章排序(按發(fā)布時間,按評分高低)

文章分組(如專題)

...

1.關(guān)系型數(shù)據(jù)庫設計

redis應用場景(1)一個文字投票網(wǎng)站

其中用戶,組兩個表簡單化處理了。業(yè)務實現(xiàn)起來也相當簡單。不再贅述。重點是如何使用redis實現(xiàn)類似的業(yè)務邏輯。

由于redis是基于key-value管理,屬于列式數(shù)據(jù)庫。和關(guān)系型數(shù)據(jù)庫實現(xiàn)方式差異較大,值得研究。

redis的設計,最重要的一部分工作就是key的命名以及鍵值數(shù)據(jù)類型的選擇上。

2.Redis設計

關(guān)系型數(shù)據(jù)庫屬于二維,數(shù)據(jù)關(guān)系主要通過在行和列兩者說明,而redis中的數(shù)據(jù)關(guān)系,則通過key鍵值描述,所以要求redis鍵值具備層次性。

redis應用場景(1)一個文字投票網(wǎng)站

2.1文章發(fā)布

redis應用場景(1)一個文字投票網(wǎng)站

實現(xiàn)代碼

private static final int ONE_WEEK_IN_SECONDS = 7 * 86400;
private static final int VOTE_SCORE = 432;
public String postArticle(Jedis conn, String user, String title, String link) {
    String articleId = String.valueOf(conn.incr("article:"));

    String voted = "voted:" + articleId;
    conn.sadd(voted, user);
    conn.expire(voted, ONE_WEEK_IN_SECONDS);//一周的有效期

    long now = System.currentTimeMillis() / 1000;
    String article = "article:" + articleId;
    HashMap<String,String> articleData = new HashMap<String,String>();
    articleData.put("title", title);
    articleData.put("link", link);
    articleData.put("user", user);
    articleData.put("now", String.valueOf(now));
    articleData.put("votes", "1");
    conn.hmset(article, articleData);
    //維護兩個排序集合,是為了解決文章排序的兩種方式
    //如果還有三種排序方式,對不起,還需要另外維護一個排序集合
    conn.zadd("score:", now + VOTE_SCORE, article);//維護文章的評分信息
    conn.zadd("time:", now, article);//維護文章的發(fā)布時間信息
    return articleId;
}

2.2文章投票

redis應用場景(1)一個文字投票網(wǎng)站

實現(xiàn)代碼

public void articleVote(Jedis conn, String user, String article) {
    long cutoff = (System.currentTimeMillis() / 1000) - ONE_WEEK_IN_SECONDS;
    if (conn.zscore("time:", article) < cutoff){
        return;
    }

    String articleId = article.substring(article.indexOf(':') + 1);
    //維護投票的一次性
    if (conn.sadd("voted:" + articleId, user) == 1) {
        conn.zincrby("score:", VOTE_SCORE, article);
        conn.hincrBy(article, "votes", 1l);
    }
}


2.3返回文章列表

兩種排序策略:按發(fā)布時間,按文章評分。

支持分頁排序。

redis的實現(xiàn)排序方式和關(guān)系型數(shù)據(jù)庫中的實現(xiàn)方式有很大差別,這也是key-value數(shù)據(jù)庫的一大特點。

基于key操作。

public List<Map<String,String>> getArticles(Jedis conn, int page, String order) {
    int start = (page - 1) * ARTICLES_PER_PAGE;
    int end = start + ARTICLES_PER_PAGE - 1;
    //從排序集合中獲取id列表
    Set<String> ids = conn.zrevrange(order, start, end);
    List<Map<String,String>> articles = new ArrayList<Map<String,String>>();
    //遍歷id列表,逐條初始化
    for (String id : ids){
        Map<String,String> articleData = conn.hgetAll(id);
        articleData.put("id", id);
        articles.add(articleData);
    }
    //注意:返回的信息中,沒有列表總數(shù)
    return articles;
}

2.4 文章分組

這一塊邏輯相對獨立,僅僅是文章的一個分析維度而已,操作起來相對簡單。就是維護groups:${group}集合。

public void addGroups(Jedis conn, String articleId, String[] toAdd) {
    String article = "article:" + articleId;
    for (String group : toAdd) {
        conn.sadd("group:" + group, article);
    }
}
//排序麻煩些
public List<Map<String,String>> getGroupArticles(Jedis conn, String group, int page, String order) {
    String key = order + group;
//60秒的有效期
   if (!conn.exists(key)) {
        ZParams params = new ZParams().aggregate(ZParams.Aggregate.MAX);
        conn.zinterstore(key, params, "group:" + group, order);
        //有序集合,與group的交集,生成新的集合
        conn.expire(key, 60);
        //60秒的有效期,性能和實時性的平衡,需要具體情況具體分析
    }
    return getArticles(conn, page, key);
}

zinterstore API

public java.lang.Long zinterstore(java.lang.String dstkey,
                                  redis.clients.jedis.ZParams params,
                                  java.lang.String... sets)

參照資源

《redis in action》

向AI問一下細節(jié)

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

AI