1. 程式人生 > 實用技巧 >PHP+Redis有序集合(zset)實現部落格園閱讀排行榜功能

PHP+Redis有序集合(zset)實現部落格園閱讀排行榜功能

許多網站都有排行榜的功能,比如球員人氣榜單、閱讀排行榜,對於一些小網站,通過查資料庫就能實現排行榜的功能,但是對於稍微有點使用者量而且還是實時排名的網站,使用一些關係型資料庫如(MySQL、Oracle)等來實現就有點力不從心了,而且對資料庫的壓力也很大,體驗也不好,更好的選擇是使用Redis就是來做排行榜功能,因為Redis提供的有序集合(zset)非常適合做實時排行榜這個業務。

示例:今天我們就來使用PHP+Redis的zset來實現部落格園網站的閱讀排行榜功能,部落格園的文章閱讀排行榜頁面如下

假設現在有8篇文章,文章ID分別是1101、1102、1103、1104、1105、1106、1107、1108,我們使用redis的有序集合(zset)的score作為閱讀次數來記錄每篇文章的閱讀量,view_nums作為記錄閱讀量的key

現在,文章ID為1101、1102、1103、1104、1105、1106、1107、1108的文章分別被讀者閱讀了12次、245次、6次、99次、1267次、23次,456次,9999次

我們使用PHP程式碼來實現記錄閱讀次數,使用的是zIncrBy()方法

$redis = new Redis();
if (!$redis->connect('127.0.0.1', 6379)) {
    trigger_error('Redis連接出錯!!!', E_USER_ERROR);
} else {
    echo '連線正常<br>';
}
//引數1: key(鍵)
//引數2: score(分數,本示例表示閱讀量)
//引數3: member(成員,本示例表示文章ID)
$redis->zIncrBy('view_nums', 12, 1101);
$redis->zIncrBy('view_nums', 245, 1102);
$redis->zIncrBy('view_nums', 6, 1103);
$redis->zIncrBy('view_nums', 99, 1104);
$redis->zIncrBy('view_nums', 1267, 1105);
$redis->zIncrBy('view_nums', 23, 1106);
$redis->zIncrBy('view_nums', 456, 1107);
$redis->zIncrBy('view_nums', 9999, 1108);

$redis->close();

上面的這串程式碼應該放到文章詳情頁接口裡,正常來說每次點選詳情頁score都應該加1,這裡為了演示,一次就增加了很多數。

我們通過Redis Desktop Manager軟體來檢視目前的閱讀量情況

可以發現在redis的view_nums有序集合中,已經按照score的大小預設升序排序了。

現在我們要寫一個閱讀量前五的文章列表,這裡需要使用zRevRange()方法

//1.初始化Redis連線
$redis = new Redis();
if (!$redis->connect('127.0.0.1', 6379)) {
    trigger_error('Redis連接出錯!!!', E_USER_ERROR);
} else {
    echo '連線正常<br>';
}

//2.獲取倒序的view_nums的前5個,下標從0開始,所以是[0~4],第四個引數表示是否使用score排名
$list = $redis->zRevRange('view_nums', 0, 4, true);

//3.關閉redis連線
$redis->close();

var_dump($list);

通過列印的結果可以看到,輸出結果是以文章ID為key,值為閱讀量的一個數組,並且是按照閱讀量降序排序的。

拿到結果之後,我們就可以提取出文章ID,然後從資料庫中取出這個幾個文章的標題

//獲取文章ID
$ids = array_keys($list);

//將文章ID轉成字串,以逗號分隔
$idStr = implode(',', $ids);

//拼接SQL
$sql = "select id, title from article where id in($idStr)";
//使用PDO連線MySQL查詢出結果,並將結果返回給客戶端

這裡寫的是虛擬碼,具體留給你們自己實現吧