Schema::create('items',function ($table) { $table->increments('id'); $table->text('message'); $table->integer('up_votes')->unsigned()->default(0); $table->integer('down_votes')->unsigned()->default(0); $table->timestamps(); });
用户可以每天投票/投票.当用户决定投票时,我将他的决定存储到memcached一天,并相应地增加其中一个字段(up_votes或down_votes).
$voteKey = sprintf('%s-%s',$request->ip(),$item->id); if (!Cache::has($voteKey)) { $vote = $request->get('vote'); $this->item->increment($vote ? 'up_votes' : 'down_votes'); Cache::put($voteKey,$vote,(60*24)); }
接下来,我想了解某些用户如何投票的信息.我在模型中创建了访问器:
public function getVoteAttribute($value) { $voteKey = sprintf('%s-%s',Request::ip(),$this->id); return $this->attributes['vote'] = Cache::get($voteKey); } protected $appends = ['vote'];
这样做是否明智?或者长列表是否会出现性能问题?如果返回100个项目,则每个用户有100个与memcached的连接.我怎样才能改进这一点,或者这是我不应该担心的事情,因为缓存服务器可以毫无问题地处理这么多连接.
>您正在使用IP地址来识别用户v / s,就像user_id一样简单.这是故意的吗?如果同一用户再次从另一个IP登录,您是否要显示不同的号码?
>在数据库中,你正在存储#up-votes&每个项目的下注,但在缓存中,您通过项目和IP地址(或用户ID)的组合存储投票类型(向上投票/向下投票).此外,缓存在24小时后过期.
因此,当您说Cache :: get($voteKey)时,它将返回向上投票或向下投票,但前提是用户在过去24小时内对此项目进行了投票(否则返回null).这是有意的吗?
何时使用Cache v / s DB
通常,您会使用缓存进行频繁查询(当您需要频繁执行特定的读操作但不经常编写时).如果不是这种情况,通常会回退到DB.
现在让我们假设您实际上想要按用户和项目的组合按项目和投票类型存储#up-votes / down-votes.想一想,哪个查询会更频繁? #up-votes / down-votes每个项目或投票类型的组合用户和&项目?当然,这将是第一个场景(如果有的话).但是,你正在做相反的事情.
You’re storing the more frequently accessed query in DB and the less
frequently accessed query in cache
这实际上会降低您应用的整体性能!
什么是正确的方法?
那么,这取决于用例.例如,假设您希望按项目ID存储用户ID和投票类型(典型用例,因为您不希望任何用户的投票在投票重铸时每个项目被计算多次).然后,我将把它存储在数据库中,并在缓存中按项目存储总的#up-votes / down-votes(仅当经常访问时 – 例如,您可以选择不存储所有项目的#potes)但仅限于具有至少X个视图的更受欢迎的项目)
对于上面的用例,我会建议这样的事情:
DB Schema
Schema::create('item_user',function ($table) { $table->increments('id'); $table->integer('user_id')->unsigned(); $table->integer('item_id')->unsigned(); $table->enum('vote_type',['up_vote','down_vote']); $table->unique(['user_id','item_id']); $table->timestamps(); });
投票控制器逻辑
$user = Auth::user(); $vote = $request->get('vote'); $voteType = $vote ? 'up_vote' : 'down_vote'; $voteKey = "{$voteType}_{$item->id}"; $item->users()->updateExistingPivot($user->id,['vote_type' => $voteType]); Cache::increment($voteKey);
原始问题
至于您的原始问题,Laravel使用单个连接实例进行Redis和Memcached的缓存查询.因此,如果同一请求获取100个不同的缓存项,它将不会启动100个连接 – 它将在单个缓存连接中完成工作