我没地方转弯。我希望这里有人能指引我正确的方向。
每个用户都有一个统计行,其中包含其好友计数、好友请求计数、新邮件计数和邮件计数。从这个表中选择一行要快得多,而不是执行一个包含连接等的大型查询来检索每个页面加载的用户统计信息。
这里的问题是,每一条新的对话消息都需要更新该行。如果我只是更新一行,这并不是真正的问题。一个对话可以有多个参与者(以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)遍历所有数据,并形成需要更新的所有内容的数组
2)迭代时,形成要更新行的另一个id数组。
3)使用这两个数组,使用where进行质量分配,并更新雄辩的。
像这样的:

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

这样做的好处是,现在只进行一个数据库查询来更新数据,而不是对每个记录进行更新查询。
请注意,我简化了你的例子。您必须找出如何扩展此逻辑以适应用户表更新。

关于php - 使用Laravel Eloquent处理对话,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31758592/

10-13 04:27