您的位置:首页 > 数据库 > Redis

Redis实战运用之SET

2017-12-01 00:00 197 查看
今天状态有点不佳,发生了点事情,让我深切的感受到,自身的无奈和痛苦。但也正因为如此,让我认识到自己的不足,也给我前进的动力和目标。曾子曰:“吾日三省吾身——为人谋而不忠乎?与朋友交而不信乎?传不习乎?”,曾子的确说的确对。^_^

好了废话差不多了,进入正题今天仔细、更用心一点,写好这篇博客。

3、redis数据结构:SET集合的运用

简单来说就像你把一袋土豆放到一个盆里,那么这个盆子,就可以说是一个集合。当然这个盆子里面的土豆,每一颗都是不一样的(不要跟我争^_^)。这个土豆呢,就可以说是集合的一个元素,redis里面这个元素就只是一个字符串。至此应该就大概已经明白了,把不重复的字符串,放在同一个容器中,而这个容器就是redis的集合。

既然明白了集合是什么,那么就能想到怎么来运用它,对此redis对于集合提供了很多的具体操作方法,例如:sadd添加元素,scard获取集合中元素数量、smembers获取所有元素、srandmember随机获取元素,srem删除元素,还有就是多个集合取交集、取并集,取差集等等。具体详细的操作方法我会贴在本文的最下边。

在来聊下集合的具体使用场景,例如我的果图网(www.guotuw.com)每个明星关联的写真现在其实不多,具体可以看一下这个页面http://www.guotuw.com/meinv/19298.html关联的写真这块,也不要求排序。

具体实现代码该贴上了:

$portrayIds = [1,3,5,2,34,2,32];//范例数据。
foreach ($portrayIds as $portrayId){
Yii::$app->get('redis')->sadd('starPortrays:'.$starId,$portrayId);
}
//这样我就把明星关联的写真数据设置好了

//明星详情页
public function actionInfo(){
$starId = (int)Yii::$app->request->get('id');
$starInfo = Star::getStarInfoById($starId);  //这里的代码之前讲HASH的时候,贴过。

if(!$starInfo){
//TODO 404
}

//添加浏览量
Star::incrView($starId);//同上贴过方法体

//相关写真
$portrays = Portray::getStarAllPortrays($starId,['id','title']); //看下面

return $this->render('info',[
'star' => $starInfo,
'portrays' => $portrays,
]);
}

class Portray
{
//获取明星写真
public static function getStarAllPortrays($starId = 0,$fields=[]){
$starId = intval($starId);
$portrayIds = Yii::$app->get('redis')->smembers('tagPortraySet:'.$starId);

return static::formatPortrays($portrayIds,$fields);
}

//根据ID批量格式化写真数据。
//至于getPortrayById这个方法其实就是根据ID获取hash数据,前天专门写过一篇HASH的文章可以去看下哟。
public static function formatPortrays($portrayIds = [],$fields = []){
$rs = [];

if($portrayIds){
empty($fields) && $fields = static::$fields;

foreach ($portrayIds as $id){
$portrayInfo = static::getPortrayById($id,$fields);
$portrayInfo && $rs[] = $portrayInfo;
}
}

return $rs;
}

}

上面的代码中其实也只运用了sadd和smembers这两个方法,只是一个简单的范例。还有更多具体的方法操作自己可以多折腾下,

例如:我的果图网各个地方的随机推荐写真,随机推荐明星这些功能的时候,我就会用到srandmember这个功能,随机抽取count(srandmember参数)个元素出来,这种功能做起来就非常简单了。

再例如:我的果图网写真美女大全页面,如果用集合来实现。如图:



假设用户想要查找:韩国美女 同时是 处女座 同时是 平面模特 同时是 甜美型 同时是 养眼 的美女,那么就只需要对这五个标签对应的美女数据去交集即可。这里就会用到sinter或者sinterstore函数,sinter是直接返回交集数据,而sinterstore会取交的结果节放到一个新的集合中去,直接用smembers读取新集合也能得到结果。就这么简单,这个页面的查询功能就搞定了,而且木有数据库查询。

sinterstore 其实这个函数把交集数据放到新集合其实就是做结果集的缓存啦,通过redis基本的expire或者expireat函数控制结果集的过期时间,释放内存。如果有用户请求相同的数据,也是这些查询条件,那么是不是就可以直接读取结果集了,还能避开redis去交集的运算,感觉挺爽,刺激。

如果你去我的果图网看了美女大全这个页面,看到了下图这一块:



这个页面的数据居然还能根据美女的浏览量排名,下面还有那么明显的一个分页。

那么问题就来了,如果用SET,数据根本就木有办法排序,也木有办法排序,怎么解?

此时此刻,SortedSet走到你面前昂首挺胸的对SET说,这些对我来说都是小case,一脸懵逼的SET立马怂回去依据:YOU CAN,YOU UP。

。。。。就这样。。。。SortedSet 闪亮登场。。。。。

预支后事如何,请听下回分解。下一篇讲SortedSet ,明天上。

本来是准备写在一起的,但是有事情来了。^_^

附上SET相关方法详细:

序号命令及描述
1SADD key member1 [member2]
向集合添加一个或多个成员
2SCARD key
获取集合的成员数
3SDIFF key1 [key2]
返回给定所有集合的差集
4SDIFFSTORE destination key1 [key2]
返回给定所有集合的差集并存储在 destination 中
5SINTER key1 [key2]
返回给定所有集合的交集
6SINTERSTORE destination key1 [key2]
返回给定所有集合的交集并存储在 destination 中
7SISMEMBER key member
判断 member 元素是否是集合 key 的成员
8SMEMBERS key
返回集合中的所有成员
9SMOVE source destination member
将 member 元素从 source 集合移动到 destination 集合
10SPOP key
移除并返回集合中的一个随机元素
11SRANDMEMBER key [count]
返回集合中一个或多个随机数
12SREM key member1 [member2]
移除集合中一个或多个成员
13SUNION key1 [key2]
返回所有给定集合的并集
14SUNIONSTORE destination key1 [key2]
所有给定集合的并集存储在 destination 集合中
15SSCAN key cursor [MATCH pattern] [COUNT count]
迭代集合中的元素
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  redis set redis实战