Laravel使用createMany批量插入event_speakers时如何避免created_at时间一致以保证排序正确性
解决批量插入后演讲者顺序错乱的问题
嘿,这个场景我之前处理过,其实不用非得靠延迟插入来搞定,给你几个更靠谱的思路:
1. 新增专门的排序字段(最推荐)
依赖created_at排序本来就不稳定——批量插入时数据库经常会把多条记录的时间设成完全一致。最稳妥的方式是给event_speakers表加一个**sort_order整数字段**,用来存储演讲者的展示顺序。
修改代码:
在组装数据的循环里,直接给每条记录分配排序值:
$data = []; for ($i = 0; $i < $numRecords; $i++) { if ($request->speaker_name_en[$i] != null) { $data[] = [ 'photo' => $this->uploadImage($livestream, $client, $request['speaker_image_en'][$i]), 'name_en' => $request->speaker_name_en[$i], 'name_fr' => $request->speaker_name_fr[$i], 'title_en' => $request->speaker_title_en[$i], 'subtitle_en' => $request->speaker_subtitle_en[$i], 'description_en' => $request->speaker_description_en[$i], 'title_fr' => $request->speaker_title_fr[$i], 'subtitle_fr' => $request->speaker_subtitle_fr[$i], 'description_fr' => $request->speaker_description_fr[$i], 'client_id' => $client->id, 'sort_order' => $i + 1 // 这里加上排序值,从1开始递增 ]; } } if (isset($data)) { $client->eventspeakers()->createMany($data); }
查询时排序:
之后查询演讲者时,直接按sort_order排序就能保证顺序正确:
$speakers = $client->eventspeakers()->orderBy('sort_order', 'asc')->get();
这个方法的好处是:完全不依赖时间字段,顺序可控,而且性能比延迟插入好太多。
2. 手动设置递增的时间戳(不用sleep)
如果一定要用created_at来排序,不用真的等待延迟,直接给每条记录分配一个递增的时间戳就行,效率更高:
$data = []; $currentTime = now(); for ($i = 0; $i < $numRecords; $i++) { if ($request->speaker_name_en[$i] != null) { // 每条记录的时间比上一条多50毫秒(可调整) $recordTime = $currentTime->copy()->addMilliseconds($i * 50); $data[] = [ 'photo' => $this->uploadImage($livestream, $client, $request['speaker_image_en'][$i]), 'name_en' => $request->speaker_name_en[$i], 'name_fr' => $request->speaker_name_fr[$i], 'title_en' => $request->speaker_title_en[$i], 'subtitle_en' => $request->speaker_subtitle_en[$i], 'description_en' => $request->speaker_description_en[$i], 'title_fr' => $request->speaker_title_fr[$i], 'subtitle_fr' => $request->speaker_subtitle_fr[$i], 'description_fr' => $request->speaker_description_fr[$i], 'client_id' => $client->id, 'created_at' => $recordTime, 'updated_at' => $recordTime ]; } } if (isset($data)) { $client->eventspeakers()->createMany($data); }
这样插入后,每条记录的created_at都会有细微差异,排序时用orderBy('created_at', 'asc')就能得到正确顺序,而且不用暂停请求,性能损失很小。
3. 循环单条插入+延迟(不推荐)
如果以上方法都不想用,也可以放弃createMany,改成循环单条插入,每次插入后暂停几毫秒。但这个方法会显著增加请求响应时间,尤其是记录多的时候,所以不建议用:
for ($i = 0; $i < $numRecords; $i++) { if ($request->speaker_name_en[$i] != null) { $record = [ 'photo' => $this->uploadImage($livestream, $client, $request['speaker_image_en'][$i]), 'name_en' => $request->speaker_name_en[$i], 'name_fr' => $request->speaker_name_fr[$i], 'title_en' => $request->speaker_title_en[$i], 'subtitle_en' => $request->speaker_subtitle_en[$i], 'description_en' => $request->speaker_description_en[$i], 'title_fr' => $request->speaker_title_fr[$i], 'subtitle_fr' => $request->speaker_subtitle_fr[$i], 'description_fr' => $request->speaker_description_fr[$i], 'client_id' => $client->id ]; $client->eventspeakers()->create($record); usleep(100000); // 暂停0.1秒(100000微秒) } }
内容的提问来源于stack exchange,提问作者Ryan Sacks
相关产品推荐
相关产品推荐

