多对多关联如何把abc三张表的请求数据用更优雅的语句合并在一起,提高获取数据的速度
1. 运行环境
1). 当前使用的 Laravel 版本?
laravel 10.9
2. 问题描述?
当前有三张表以及两张中间表:
apps
App相关信息navigations
App操作系统分类。例如:安卓、电脑、Iosapp_navigation
主要字段有app_id
和navigation_id
classifications
主要字段有navigation_id
App的应用场景分类。例如:游戏、影视、音乐app_classification
主要字段有app_id
和classification_id
现在需要根据navigations
操作系统的分类,获取到所有属于当前navigations
操作系统分类的apps
信息,以及包含每个App的classifications
应用场景的分类。
App Model代码:
public function navigations():BelongsToMany{
return $this->belongsToMany(Navigation::class)->withPivot('version','size','newdate','url','download','content','log','operatingsystem');
}
public function classifications():BelongsToMany{
return $this->belongsToMany(Classification::class);
}
Navigation Model代码:
public function apps():BelongsToMany{
return $this->belongsToMany(App::class)->withPivot('version','size','newdate')->orderByPivot('newdate', 'desc');
}
Classification Model代码:
public function apps():BelongsToMany{
return $this->belongsToMany(App::class);
}
在这个问题提出前,我尝试过两种方法,获取数据的速度特别慢。
- 先获取到用户访问的
navigations
分类,再遍历每一个App模型的classifications()
方法,按照 10000条数据计算,这个方式我需要等待 20秒才能获取到数据。 - 分别获取
navigations
和classifications
共同的apps()
模型方法。再通过循环进行数据拼接,这个方式我需要等待 6秒才能获取到数据。代码如下所示:$navigation=Navigation::where('id',$navigation->id)->first(); $apps=$navigation->apps()->get(['apps.id','good','author','name','popular','weights'])-toArray();//获取当前操作系统所有的app $classifications=Classification::where('navigation_id',$navigation->id)->get();//获取当前操作系统所有的分类 foreach($classifications as $classification){ foreach($classification->apps()->get(['apps.id'])->toArray() as $app){ $temp[]=$app; } } foreach($apps as $app){ $classificationId=[]; for($i=0;$i<count($temp);$i++){ if($temp[$i]['pivot']['app_id']===$app['id']){ $classificationId[]=$temp[$i]['pivot']['classification_id']; unset($temp[$i]); $temp = array_values($temp); } } $app['classifications']=$classificationId; $data['apps'][]=$app; }
请求到的数据:
如何才能通过更加优雅的方法让速度提升上去,谢谢大佬赐教
使用
with()
关联,只需要触发一次数据库连接。时间从本地的 6秒钟降到1.2秒。如果在服务器的话,用时更低。下面的代码注释是之前尝试过的方法2。