千家信息网

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

发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,构建一个文章投票网站,一般具备下面几个功能发布文章文章投票评分(按投票多少进行评分)文章排序(按发布时间,按评分高低)文章分组(如专题)...1.关系型数据库设计其中用户,组两个表简单化处理了。业务实
千家信息网最后更新 2025年02月02日redis应用场景(1)一个文字投票网站

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

发布文章

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

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

文章分组(如专题)

...

1.关系型数据库设计

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

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

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

2.Redis设计

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

2.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 articleData = new HashMap();    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文章投票

实现代码

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> getArticles(Jedis conn, int page, String order) {    int start = (page - 1) * ARTICLES_PER_PAGE;    int end = start + ARTICLES_PER_PAGE - 1;    //从排序集合中获取id列表    Set ids = conn.zrevrange(order, start, end);    List> articles = new ArrayList>();    //遍历id列表,逐条初始化    for (String id : ids){        Map 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> 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》

文章 排序 数据 数据库 投票 方式 评分 有效 信息 时间 有效期 设计 业务 两个 代码 就是 逻辑 分析 分组 在行 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 克州智能云服务器 网络安全防护工作机制网络 北京所有互联网科技公司名称 软件开发文档封面简笔画 数据库的对象实例名 腾讯云助手怎么登录服务器 饥荒服务器无响应原因 籍贯的英文在数据库是什么 服务器执行指令卡死 打印服务器尺寸设置不能生效 内蒙古崖柏艺术雕刻数据库图片 嵌入式软件开发考研方向 服务器忘记密码怎样登录 网络安全方面的隐患 我们如何保护国家网络安全 陕西加固服务器虚拟主机 网络安全基础知识答题答案 倪光南说中国网络安全 邯郸办公系统软件开发哪家可靠 5g网络技术的发展趋势 松江区品质软件开发咨询热线 网络安全项目中标资讯 阿里云oracle数据库导出 网络安全工程师考证学什么 苹果账号服务器失败 如何查看服务器是不是阿里云 网络安全风险相关件案例 芯片和网络安全有哪些股票 如何自己租服务器翻墙 狮子座互联网科技培训
0