構(gòu)建一個文章投票網(wǎng)站,一般具備下面幾個功能
創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),中方企業(yè)網(wǎng)站建設(shè),中方品牌網(wǎng)站建設(shè),網(wǎng)站定制,中方網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,中方網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。
發(fā)布文章
文章投票評分(按投票多少進(jìn)行評分)
文章排序(按發(fā)布時間,按評分高低)
文章分組(如專題)
...
1.關(guān)系型數(shù)據(jù)庫設(shè)計

其中用戶,組兩個表簡單化處理了。業(yè)務(wù)實現(xiàn)起來也相當(dāng)簡單。不再贅述。重點是如何使用redis實現(xiàn)類似的業(yè)務(wù)邏輯。
由于redis是基于key-value管理,屬于列式數(shù)據(jù)庫。和關(guān)系型數(shù)據(jù)庫實現(xiàn)方式差異較大,值得研究。
redis的設(shè)計,最重要的一部分工作就是key的命名以及鍵值數(shù)據(jù)類型的選擇上。
2.Redis設(shè)計
關(guān)系型數(shù)據(jù)庫屬于二維,數(shù)據(jù)關(guān)系主要通過在行和列兩者說明,而redis中的數(shù)據(jù)關(guān)系,則通過key鍵值描述,所以要求redis鍵值具備層次性。

2.1文章發(fā)布

實現(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);
//維護(hù)兩個排序集合,是為了解決文章排序的兩種方式
//如果還有三種排序方式,對不起,還需要另外維護(hù)一個排序集合
conn.zadd("score:", now + VOTE_SCORE, article);//維護(hù)文章的評分信息
conn.zadd("time:", now, article);//維護(hù)文章的發(fā)布時間信息
return articleId;
}2.2文章投票

實現(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);
//維護(hù)投票的一次性
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 文章分組
這一塊邏輯相對獨立,僅僅是文章的一個分析維度而已,操作起來相對簡單。就是維護(hù)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》
分享文章:redis應(yīng)用場景(1)一個文字投票網(wǎng)站
文章位置:http://chinadenli.net/article26/gejdjg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、服務(wù)器托管、ChatGPT、、網(wǎng)站改版、網(wǎng)站營銷
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)