Laravel model accessory benefiting from improved cache performance

I have a list of items in the database, and each item has the ability to vote up or down. These voices are stored in MySql along with other fields. For example, for example:

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(); }); 

User can vote up / down every day. When a user decides to vote, I save his memcached solution for one day and increase one of the fields (up_votes or down_votes), respectively.

 $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)); } 

Next, I want to get information about how a particular user voted. I created an accessor in the model:

 public function getVoteAttribute($value) { $voteKey = sprintf('%s-%s', Request::ip(), $this->id); return $this->attributes['vote'] = Cache::get($voteKey); } protected $appends = ['vote']; 

Is it smart or can there be a problem with long lists? If 100 items are returned, then 100 users are connected to memcached for each user. How can I improve this or is it something I should not worry about because the cache server can handle this number of connections without problems.

+7
php mysql caching eloquent laravel
source share
1 answer

Current cache and DB usage

  • You use the IP address to identify the v / s user as simple as possible than user_id . Is it intentional? If the same user logs in again from a different IP address, do you want to show a different number?
  • In the database, you save # up-votes & down-votes for the item , but in the cache that you store type of vote (vote / vote), a combination of item and IP address (or user id) . In addition, the cache expires after 24 hours.

    So, when you say Cache::get($voteKey) , it will return either a vote or a vote, but only if the user has voted for this item in the last 24 hours (otherwise returns null). Is this intended?

When to use Cache v / s DB

As a rule, you use the cache for frequent requests (when you need to frequently perform certain op reads, but write less often). If this is not the case, you usually abandon the database.

Now let's say you really wanted to save both # up-votes/down-votes by item and type of vote by combination of user and item . Think about it for a second, which request will be more frequent? # up-vote / down-votes for an item or type of vote by a combination of user and item? Of course, this will be the first scenario (if at all). However, you are doing the exact opposite.

You save the more frequently requested query in the database and the less frequently requested query in the cache

This will actually reduce the overall performance of your application!

What will be the right way?

Well, it depends on the use case. For example, let's say you want to save both the user identifier and the type of voting by the element identifier (a typical use case, because you would not want any user voting to be counted more than once per element when re-voting). Then I would like to save this in the database and save the total number of votes # up-vote / down-votes by item in the cache (only if they can often be accessed - for example, you can not store # votes for all items but only for more popular items with at least X views)

In the above usage example, I would suggest something like the following:

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(); }); 

Voting Control Logic

 $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); 

Original question

As for your initial question, Laravel uses a single connection instance for cache requests for Redis and Memcached . Thus, if the same request retrieves 100 different cache elements, it will not initiate 100 connections - it will perform the task in one cache connection

+6
source share

All Articles