国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python--Redis實戰(zhàn):第一章:初識Redis:第三節(jié):你好Redis-文章投票試煉

Meils / 2601人閱讀

摘要:為了防止用戶對同一篇文章進行多次投票,網(wǎng)站需要為每一篇文章記錄一個已投票用戶名單。上一篇文章實戰(zhàn)第一章初識第二節(jié)數(shù)據(jù)結構簡介下一篇文章實戰(zhàn)第二章使用構建應用第一節(jié)登錄和緩存

上一篇文章: Python--Redis實戰(zhàn):第一章:初識Redis:第二節(jié):Redis數(shù)據(jù)結構簡介
下一篇文章:Python--Redis實戰(zhàn):第二章:使用Redis構建Web應用:第一節(jié):登錄和cookie緩存

在對Redis提供的5種結構有了基本的了解后,現(xiàn)在是時候來學習一下怎樣使用這些結構來解決實際問題了。

最近幾年,越來越多的網(wǎng)站開始提供對網(wǎng)頁鏈接、文章或者穩(wěn)贏進行投票的功能,這些網(wǎng)站會根據(jù)文章的發(fā)布時間和文章獲得的投票數(shù)量計算出一個評分,然后根據(jù)這個評分來決定如何排序和展示文章。

本節(jié)將展示如何使用Redis來構建一個簡單的文章投票網(wǎng)站的后端。

1、對文章進行投票

要構建一個文章投票網(wǎng)站,我們首先要做的就是為了這個網(wǎng)站設置一些數(shù)值和限制條件:如果一篇文章獲得了至少200張支持票,那么久認為這篇文章是【有趣的】。假如這個網(wǎng)站每天發(fā)布1000篇文章,而其中的50篇符合網(wǎng)站對【有趣】文章的要求,那么網(wǎng)站要做的就是把這50篇文章放到文章放到文章列表前100位至少一天;另外,這個網(wǎng)站暫時不提供投反對票的功能。

為了產(chǎn)生一個能夠隨著時間流逝而不斷減少的評分,程序需要根據(jù)文章的發(fā)布時間和當前時間來計算文章的評分,具體的計算方法為:將文章得到的支持票數(shù)乘以一個常量,然后加上文章的發(fā)布時間,得出的結果就是文章的評分。

我們使用從UTC時區(qū)1970年1月1日到現(xiàn)在為止所經(jīng)過的秒數(shù)來計算文章的評分,這個值通常被成為Unix時間。之所以選擇使用Unix時間,是因為所有能夠運行Redis的平臺上面,使用編程語言獲取這個值都是非常簡單的事情。另外,計算評分時與支持數(shù)量相乘的常量為432,這個常量是通過將一天的秒數(shù)(86400)除以文章展示一天所需的支持票數(shù)量(200得出的):文章沒獲得一張支持票,程序就需要將程序的評分增加432分。

構建文章投票網(wǎng)站除了需要計算文章評分之外,還需要使用Redis結構存儲網(wǎng)站上的各種信息。對于網(wǎng)站里的每一篇文章,程序都使用了一個散列來存儲文章的標題、指向文章的網(wǎng)址、發(fā)布文章的用戶、文章的發(fā)布時間、文章得到的投票數(shù)量等信息。

我們的文章投票網(wǎng)站將使用兩個有序集合來存儲文章:

第一個有序集合的成員為:文章ID、文章的發(fā)布時間,該有序集合可以使網(wǎng)站按照發(fā)布時間先后展示文章

第二個有序集合的成員為:文章ID、文章的評分,該有序集合可以使網(wǎng)站按照評分高低展示文章。

為了防止用戶對同一篇文章進行多次投票,網(wǎng)站需要為每一篇文章記錄一個已投票用戶名單。為此,需要創(chuàng)建一個存儲所有已經(jīng)投票的用戶ID。

為了盡量節(jié)約內(nèi)存,我們規(guī)定當一篇文章發(fā)布期滿一周之后,用戶將不能再對它進行投票,文章的評分將被固定下來,而積累文章已經(jīng)投票用戶名單的集合會被刪除。

既然我們已經(jīng)知道了網(wǎng)站計算文章評分的方法,也知道了網(wǎng)站存儲數(shù)據(jù)所需的數(shù)據(jù)結構,那么現(xiàn)在是時候實際的實現(xiàn)這個投票功能了!

當用戶嘗試對一篇文章進行投票時,程序需要使用zscore命令來檢查記錄文章發(fā)布時間的有序集合,判斷文章的發(fā)布時間是否未超過一周。

如果文章仍然處于可以投票的時間范圍之內(nèi),那么程序將使用sadd命令,嘗試將用戶添加到記錄文章已經(jīng)投票用戶名單集合里。

如果添加操作執(zhí)行成功的話,那么說明用戶是第一次對這篇文章進行投票,程序將使用zincrby命令為文章的評分增加432分(zincrby命令用于對有序集合成員的分值進行自增操作),并使用hincrby命令對散列記錄的文章投票數(shù)量進行更新(hincrby命令用于對散列存儲的值執(zhí)行自增操作)。

投票功能實現(xiàn)代碼:
import time

ONE_WEEK_IN_SECONDS=7*86400  #一周秒數(shù)
VOTE_SCORE=432  #點贊一次增加的分值

#投票
def article_vote(conn,user,article):
    cutoff=time.time()-ONE_WEEK_IN_SECONDS
    #提示:本案例使用冒號作為分隔符
    if conn.zscore("time:",article)
2、發(fā)布并獲取文章

發(fā)布一篇文章首先需要創(chuàng)建一個新的文章ID,這項工作可以通過對一個計數(shù)器(counter)執(zhí)行incr命令來完成。

接著程序需要使用sadd將文章發(fā)布者的ID添加到記錄文章已投票用戶名單的集合里面,并使用expire命令為這個集合設置一個過期時間,讓Redis在文章發(fā)布期滿一周之后自動刪除這個集合。

之后,程序會使用hmset命令來存儲文章的相關信息,并執(zhí)行兩個zadd命令,將文章的初始評分(initial score)和發(fā)布時間分別添加到兩個相應的有序集合里面。

#發(fā)布文章
def post_article(conn,user,title,link):
    article_id=str(conn.incr("article:"))

    voted="voted:"+article_id

    conn.sadd(voted,user)
    conn.expire(voted,ONE_WEEK_IN_SECONDS)

    now=time.time()
    article="article:"+article_id
    conn.hmset(article,{
        "title":title,#文章標題
        "link":link,#文章鏈接
        "poster":user,
        "time":now,
        "votes":1
    })

    conn.zadd("score:",article,now+VOTE_SCORE)
    conn.zadd("time",article,now)

    return article_id

好了,我們已經(jīng)陸續(xù)實現(xiàn)了文章的投票功能和文章發(fā)布功能,接下來要考慮的就是如何取出評分最高的文章已經(jīng)如何取出最新發(fā)布的文章。

為了實現(xiàn)這兩個功能,

首先需要使用zrevrange命令取出多個文章ID

然后再對每個文章ID執(zhí)行一次hgetall命令來取出文章的詳細信息。

這個方法既可以用于取出評分最高的文章,又可以用于取出最新發(fā)布的文章。

注意:因為有序集合根據(jù)成員的分值從小到大排列,所以使用zrevrange命令,以【分值從大到小】的排列順序取出文章ID才是正確的做法。
ARTICLES_PER_PAGE=25 #每頁展示數(shù)量

def get_articls(conn,page,order="score:"):
    start=(page-1)*ARTICLES_PER_PAGE  #設置文章的起始索引
    end=start+ARTICLES_PER_PAGE-1     #設置文章的結束索引

    ids=conn.zrevrange(order,start,end) #獲取多個文章ID

    articles=[]

    for id in ids:
        article_data=conn.hgetall(id)
        article_data["id"]=id
        articles.append(article_data)
    return articles

雖然我們構建的網(wǎng)站現(xiàn)在已經(jīng)可以展示最新發(fā)布的文章和評分最高的文章了,但它還不具備目前很多投票網(wǎng)站都支持的群組【group】功能:可以讓用戶看見與特定話題有關的文章,比如:【可愛的動物】、【歷史】、【政治】等等。

3、對文章進行分組

群組功能由兩個部分組成,一個部分負責記錄文章屬于哪個群組,另一部分負責取出群組里面的文章。為了記錄各個群組都保存了哪些文章,網(wǎng)站需要為每個群組創(chuàng)建一個集合,并將所有同屬一個群組的文章ID都記錄到那個集合里面。

#將文章添加到群組里面的方法,以及從群組里面移除文章的方法
def add_remove_groups(conn,article_id,to_add=[],to_remove=[]):
    article="article:"+article_id
    for group in to_add:
        conn.sadd("group:"+group,article) #將文章添加到它所屬的群組里面
    for group in to_remove:
        conn.srem("group:"+group,article) #從群組里面移除文章

初看上去,可能會有讀者覺得使用集合來記錄群組文章并沒有多大用處。到目前為止,我們只看到了集合結構檢查某個元素是否存在的能力,但實際上Redis不僅可以對多個集合執(zhí)行操作,甚至在一些情況下,還可以在集合和有序集合之間執(zhí)行操作。

為了能夠根據(jù)評分對群組文章進行排序和分頁,網(wǎng)站需要將同一個群組里面的所有文章都按照評分有序的存儲到一個有序集合里面。Redis的zinterstore命令可以接受多個集合和多個有序集合作為輸入,找出所有同時存在于集合和有序集合的成員,并以幾種不同的方式來合并【combine】這些成員的分值(所有集合成員的分值都會被視為:1)。對于我們的文章投票網(wǎng)站來說,程序需要使用zinterstore命令選出相同成員中最大的那個分值來作為交集成員的分值:取決于所使用的排序選項,這些分值既可以是文章的評分,也可以是文章的發(fā)布時間。

通過對存儲群組文章的集合和存儲文章評分的有序集合執(zhí)行zinterstore命令,程序可以得到按照文章評分順序的群組文章;

而通過對存儲群組文章的集合和存儲文章發(fā)布時間的有序集合執(zhí)行zinterstore命令,程序則可以得到按照文章發(fā)布時間排序的群組文章。如果群組包含的文章非常多,那么執(zhí)行zinterstore命令就會比較花時間,為了盡量減少Redis的工作量,程序會將這個命令的計算結果緩存60秒。

#分頁并獲取群組文章
def get_group_articles(conn,group,page,order="score:"):
    key=order+group #為每個群組的每種排列順序都創(chuàng)建一個鍵
    #檢查是否已有緩存的排序結果,如果沒有的話現(xiàn)在就進行排序
    if not conn.exists(key):
        conn.zinterstore(key,
                         ["group:"+group,order],
                         aggregate="max")
        conn.expire(key,60) #讓redis在60秒后自動刪除這個有序集合
    return get_articls(conn,page,key)
友情提示,上面只是部分代碼,無法直接運行,只需要先理解思路就行。

上一篇文章: Python--Redis實戰(zhàn):第一章:初識Redis:第二節(jié):Redis數(shù)據(jù)結構簡介
下一篇文章:Python--Redis實戰(zhàn):第二章:使用Redis構建Web應用:第一節(jié):登錄和cookie緩存

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/42570.html

相關文章

  • Python--Redis實戰(zhàn)一章初識Redis:第二節(jié):Redis數(shù)據(jù)結構簡介

    摘要:上一篇文章實戰(zhàn)第一章初識第一節(jié)簡介下一篇文章實戰(zhàn)第一章初識第三節(jié)你好文章投票試煉可以存儲鍵與種不同的數(shù)據(jù)結構類型之間的映射,這中數(shù)據(jù)結構類別分別是字符串列表集合散列和有序集合。 上一篇文章:Python--Redis實戰(zhàn):第一章:初識Redis:第一節(jié):Redis簡介下一篇文章:Python--Redis實戰(zhàn):第一章:初識Redis:第三節(jié):你好Redis-文章投票試煉 Redis可...

    ghnor 評論0 收藏0
  • Python--Redis實戰(zhàn):第二章:使用Redis構建Web應用:第一節(jié):登錄和cookie緩存

    摘要:需要在服務中存儲更多信息,如果使用的是關系數(shù)據(jù)庫,那么載入和存儲的的代價可能會很高。這次我們使用令牌來引用關系數(shù)據(jù)庫表中負責存儲用戶登錄信息的條目。而我們要做的就是適用重新實現(xiàn)登錄功能,取代由關系數(shù)據(jù)庫實現(xiàn)的登錄功能。 上一篇文章:Python--Redis實戰(zhàn):第一章:初識Redis:第三節(jié):你好Redis-文章投票試煉下一篇文章:Python--Redis實戰(zhàn):第二章:使用Redi...

    makeFoxPlay 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<