返回顶部
首页 > 资讯 > 数据库 >redis应用场景(1)一个文字投票网站
  • 615
分享到

redis应用场景(1)一个文字投票网站

2024-04-02 19:04:59 615人浏览 泡泡鱼
摘要

构建一个文章投票网站,一般具备下面几个功能发布文章文章投票评分(按投票多少进行评分)文章排序(按发布时间,按评分高低)文章分组(如专题)...1.关系型数据库设计其中用户,组两个表简单化处理了。业务实现起来

构建一个文章投票网站,一般具备下面几个功能

发布文章

文章投票评分(按投票多少进行评分)

文章排序(按发布时间,按评分高低)

文章分组(如专题)

...

1.关系型数据库设计

redis应用场景(1)一个文字投票网站

其中用户,组两个表简单化处理了。业务实现起来也相当简单。不再赘述。重点是如何使用Redis实现类似的业务逻辑。

由于redis是基于key-value管理,属于列式数据库。和关系型数据库实现方式差异较大,值得研究。

redis的设计,最重要的一部分工作就是key的命名以及键值数据类型的选择上。

2.Redis设计

关系型数据库属于二维,数据关系主要通过在行和列两者说明,而redis中的数据关系,则通过key键值描述,所以要求redis键值具备层次性。

redis应用场景(1)一个文字投票网站

2.1文章发布

redis应用场景(1)一个文字投票网站

实现代码

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);//维护文章的发布时间信息
    return articleId;
}

2.2文章投票

redis应用场景(1)一个文字投票网站

实现代码

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返回文章列表

两种排序策略:按发布时间,按文章评分。

支持分页排序。

redis的实现排序方式和关系型数据库中的实现方式有很大差别,这也是key-value数据库的一大特点。

基于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);
    }
    //注意:返回的信息中,没有列表总数
    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》

您可能感兴趣的文档:

--结束END--

本文标题: redis应用场景(1)一个文字投票网站

本文链接: https://lsjlt.com/news/43164.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • redis应用场景(1)一个文字投票网站
    构建一个文章投票网站,一般具备下面几个功能发布文章文章投票评分(按投票多少进行评分)文章排序(按发布时间,按评分高低)文章分组(如专题)...1.关系型数据库设计其中用户,组两个表简单化处理了。业务实现起来...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作