Redis实战运用之SET

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

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

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参数)个元素出来,这种功能做起来就非常简单了。

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

173029_p3Xh_3736695.png

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

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

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

141102_nbRN_3736695.png

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

那么问题就来了,如果用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] 
迭代集合中的元素

转载于:https://my.oschina.net/u/3736695/blog/1583460

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值