There is a very special data type in redis - ordered set. The concept of a set we learned before is that all elements in the set are unique and unordered. But why does an ordered set appear here, and how does it achieve order?
The elements in the ordered set are still unique, but a socre (score) is set for each element, and ordering is achieved through this score. As shown in the figure below:
Ordered Set API
The following introduces several ordered sets API, you need to know the usage of these APIs to implement the ranking function.
zAdd
We want to set up an ordered list of player 2k ability values, using the player name element and the ability value as scores.
Curry's shooting ability is 100, James is 92, Harden is 96, Paul is 97
sadd can add 1 or more elements at a time
127.0.0.1:6379[1]> zadd 2kplayer:shoot 100 curry (integer) 1 127.0.0.1:6379[1]> zadd 2kplayer:shoot 92 james 96 harden 97 paul (integer) 3
zIncrBy
In the past month, Harden has been booming and scoring crazy high scores. So, 2k decided to increase his shooting ability by 2 points
127.0.0.1:6379[1]> zincrby 2kplayer:shoot 2 harden "98"
zRange, zRevRange
Now we want to know who the top 3 players are.
127.0.0.1:6379[1]> zrange 2kplayer:shoot 0 2 withscores 1) "james" 2) "92" 3) "paul" 4) "97" 5) "harden" 6) "98"
Redis uses positive order by default, and the scores are sorted from small to large. So we need to use zRevRange
127.0.0.1:6379[1]> zrevrange 2kplayer:shoot 0 2 withscores 1) "curry" 2) "100" 3) "harden" 4) "98" 5) "paul" 6) "97"
zUnionStore
2k ability value has many aspects, shooting is only one of them, speed, layup etc. are all part of the ability value.
127.0.0.1:6379[1]> zadd 2kplayer:speed 99 james 90 paul 90 curry 93 harden (integer) 4
At this time, if you want to know the player's comprehensive ability value, you need to add up the scores for each item
127.0.0.1:6379[1]> zunionstore 2kplayer 2 2kplayer:shoot 2kplayer:speed (integer) 4 127.0.0.1:6379[1]> zrange 2kplayer 0 -1 withscores 1) "paul" 2) "187" 3) "curry" 4) "190" 5) "harden" 6) "191" 7) "james" 8) "191"
Implement the ranking system
The scenario is as follows: a video on demand system with many people watching it every day. The system has a list function that displays the most viewed videos. It is divided into today's list, three-day list, weekly ranking and monthly list.
Idea: First, count the number of video views by day, and then count the today's list, three-day list, etc.
The pseudocode for counting the number of video views is as follows:
// 观看视频 function view ($videoId) { $key = 'video:view:'.date('Y-m-d'); if (!$redis->exists($key)) { $redis->zIncrBy($key, 1, $videoId); $redis->expire($key, 86400 * 30); } $redis->zIncrBy($key, 1, $videoId); }
Today’s Hottest
Today’s Hottest There is one thing to note , when a new day just starts, the data may be empty or very little. Therefore, we can combine today's and yesterday's data, but weight today's data higher.
The pseudo code for implementing today’s most popular functions is as follows:
function todayHot () { $tokeyKey = 'video:view:'.date('Y_m_d'); $yesKey = 'video:view:'. date('Y_m_d', time() - 86400); $keyUnion = "view:rank:today"; $redis->zUnionStore($keyUnion, [$tokeyKey, $yesKey], [10, 1]); // 取前100名 return $redis->zRevRange($keyUnion, 0, 99); }
Three-day list
function threeHot () { $keyUnion = 'view:rank:three'; $unionKeys = []; for ($i=0; $i < 3; $i++) { $unionKeys[] = 'video:view:'.date('Y_m_d', time() - 86400 *$i); } $redis->zUnionStore($keyUnion, $unionKeys); return $redis->zRevRange($keyUnion, 0, 99, true); }
Weekly list, monthly list The list and other ideas are the same as the three-day list, so I won’t post the code.
The above is the detailed content of Use Redis to complete the ranking system. For more information, please follow other related articles on the PHP Chinese website!