十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
构建一个文章投票网站,一般具备下面几个功能
创新互联公司是一家集网站建设,中方企业网站建设,中方品牌网站建设,网站定制,中方网站建设报价,网络营销,网络优化,中方网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
发布文章
文章投票评分(按投票多少进行评分)
文章排序(按发布时间,按评分高低)
文章分组(如专题)
...
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
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》