我无处可去。我希望有人能指出我正确的方向。
每个用户都有一个统计信息行,其中包含他们的朋友数,朋友请求数,新消息数和消息数。从这个表中选择1行要快得多,而不是执行大量连接等大查询,只是为了检索每个页面加载的用户统计信息。
这里的问题是,需要在每个新的会话消息上更新该行。如果我只是更新一行,这不是一个真正的问题。对话可以有多个参与者(例如,让我们拿20个)。
我需要在统计信息表中更新20行。这被认为是一个坏主意,因为它会导致阻止其他用户发出请求。可以理解的。 我将需要更新对话参与者表中的20行(has_read标志,has_deleted标志和可能created_at,因为参与者被“重新设置”到对话中)。好的总而言之,我在每条新消息上都更新了40行...听起来有点矫枉过正,但并不止于此。
在eloquent中更新行并不简单。我不知道你怎么能在eloquent中进行批量更新,所以代码最终会像这样:
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次查询。我不了解你,但对我来说是畏缩的。
所以基本上,我不确定如何处理事物的整个统计方面和批量更新。我觉得好像我撞到了一堵砖墙,我不知道该做什么或转向哪里。请帮助,谢谢。
答案 0 :(得分:1)
通常这是为质量分配所做的:
1)迭代所有数据并形成一个需要更新的所有内容的数组
2)迭代时,形成另一个要更新的行的id数组。
3)使用这两个数组,使用WhereIn进行质量分配并更新eloquent。
这样的事情:
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);
优点是,现在您只进行一次数据库查询来更新数据,而不是为每条记录进行更新查询。
请注意,我已经简化了您的示例。您必须弄清楚如何扩展此逻辑以适应用户表更新。