2015-08-01 4 views
1

У меня нет места для поворота. Я надеюсь, что кто-то здесь укажет мне в правильном направлении.Обработка разговоров с использованием Laravel Eloquent

У каждого пользователя есть строка статистики, в которой содержится их счетчик друзей, количество запросов друзей, количество новых сообщений и количество сообщений. Гораздо быстрее выбрать 1 строку из этой таблицы, а не выполнять большой запрос, полный объединений и т. Д., Чтобы получить статистику пользователей при каждой загрузке страницы.

Проблема заключается в том, что эта строка должна обновляться при каждом новом сообщении разговора. На самом деле это не проблема, если я просто обновляю одну строку. В разговоре может быть несколько участников (например, возьмем 20).

Мне нужно будет обновить 20 строк в таблице статистики. Это считается плохой идеей, так как это вызовет блокировку для других пользователей, делающих запрос. Понятный. Мне нужно будет обновить 20 строк в таблице участников беседы (has_read flag, has_deleted flag и возможно created_at, поскольку участник «повторно установлен» для разговора). Хорошо, поэтому в целом я обновляю 40 строк на каждом новом сообщении ... звучит немного перебор, но это не останавливается на достигнутом.

Обновление строк в красноречиве не просто. Я не знаю, как вы можете сделать насыпное обновление в красноречивы либо так что код заканчивается так:

foreach ($conversation->participants as $participant) { 
    if ($participant->user_id == Auth::user()->id) { 
     continue; 
    } 

    $participant->has_read = 0; 

    if ($participant->has_deleted == 1) { 
     $participant->has_deleted = 0; 
     $participant->created_at = DB::Raw('NOW()'); 
    } 

    $participant->save(); 
    $participant->user->stats->new_messages += 1; 
    $participant->user->stats->save(); 
} 

Так уже, я выступаю по крайней мере 40 запросов. Не говоря уже о том, что пользователь сам не загружается ... не совсем уверен, как можно загружать их в отношениях, поэтому я выполняю по меньшей мере 60 запросов, делая это красноречиво каждый раз, когда отправляется новое сообщение. Я не знаю о вас, но для меня это смущает.

Так что, в основном, я не уверен, как обращаться со всей статистической стороной вещей и массовым обновлением. Мне кажется, что я попал в кирпичную стену, и я не уверен, что делать или куда обратиться. Пожалуйста, помогите, спасибо.

ответ

1

Как правило, это то, что делается для массового назначения:

1) перебрать все данные и сформировать массив из всех вещей, которые вам необходимо обновить

2) В то время как итерация, образуют другой массив идентификаторов строк для обновления.

3) С помощью этих двух массивов выполните массовое присвоение с использованием WhereIn и обновление красноречивого.

Что-то вроде этого:

ParticipantModel::whereIn('id',$array_of_id)->update($data_to_update); 

Ваш $ массив data_to_update должен содержать только те поля, которые присутствуют в таблице.

Упрощая свой пример, ради объяснения этого, как вы можете сделать вышеуказанные шаги:

$array_of_id = array(); 
$data_to_update = array(); 

foreach ($conversation->participants as $participant) { 
    $array_od_id[] = $participant['id'] //Pushing the ids into the array 
    $participant['has_read'] = 0; 
    if ($participant['has_deleted'] == 1) { 
     $participant['has_deleted'] = 0; 
     $participant['created_at'] = DB::Raw('NOW()'); 
    } 
    $data_to_update[] = $participant; //Pushing each participant into data_to_update 
} 

/* You can either use DB raw or model,if you have it */ 
ParticipantModel::whereIn('id',$array_of_id)->update($data_to_update); 

Преимущество заключается в том, что теперь вы делаете только один DB запрос для обновления данных, вместо того, чтобы обновить запрос для каждой записи.

Обратите внимание, что я упростил ваш пример. Вы должны выяснить, как вы можете расширить эту логику, чтобы приспособить свои обновления таблиц пользователей.

Смежные вопросы