【问题标题】:Laravel - query to join tables in Many to many relationLaravel - 查询以多对多关系连接表
【发布时间】:2021-12-10 02:15:23
【问题描述】:

我有下表

帖子 - ID - 姓名 类别 - ID - 姓名 category_post - post_id - 类别 ID

Post.php

public function Category()
{
    return $this->belongsToMany(Category::class);
}

Category.php

public function posts()
{
    return $this->belongsToMany(Post::class);
}

一篇文章可能包含许多类别。

我想以最少的数据库查询次数查询与任何给定帖子的类别相关的所有帖子。

例如,如果一个帖子属于三个类别,我想获取与这三个类别相关的所有帖子。我可以在下面的 4 个数据库查询中实现这一点。

$post = Post::find(1);

$categoryIds = $post->category()->pluck('id');

$postIds = DB::table('category_post')
    ->whereIn('category_id', $categoryIds)
    ->pluck('post_id')
    ->unique();

$relatedPosts = DB::table('posts')
    ->whereIn('id', $postIds)
    ->get();

非常感谢任何帮助以减少数据库查询或以 laravel 方式重构代码。 谢谢

【问题讨论】:

  • 就像一个注释。如果您这样做是因为您认为更少的查询意味着更好的性能,那么这是错误的。更重要的是查询的功能而不是查询的数量,但数据传输成本的显着例外仅适用于数据库位于虚拟本地网络的服务器本地网络之外。
  • @apokryfos 是的,我明白这一点。在这种特殊情况下,您是否认为我的代码和您的代码在性能上不会有任何差异,比如 25 个类别和 5000 个帖子?
  • 在这种特殊情况下,我认为主要优点是通过不加载部分数据来准备下一个查询来节省网络服务器上的内存,此外,如果您不必执行第一个查询来获取模型已经知道id了。我认为这两种方法所花费的时间将类似地扩展,因为主要耗时的过程是通过类别“加入”帖子表,这是一个不可避免的操作
  • @apokryfos 感谢您的详细说明

标签: php mysql sql laravel


【解决方案1】:

你给定的例子可以写成:

$postWithRelatedPosts = Post::whereHas('category.post', function ($q) {
    $q->where('id', 1);
})->get();

这是一个单一的查询,但其中有 2 个子查询。它会生成如下内容:

select * 
from `posts` 
where exists (
    select * 
    from `categories` inner join `category_post` on `categories`.`id` = `category_post`.`category_id` 
    where `posts`.`id` = `category_post`.`post_id` and exists (
         select * 
         from `posts` inner join `category_post` on `posts`.`id` = `category_post`.`post_id` 
         where `categories`.`id` = `category_post`.`category_id` and `id` = ?
    )

)

【讨论】:

  • 感谢@apokryfos 的回答。它完全按照我想要的方式工作。
猜你喜欢
  • 2018-11-02
  • 2015-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-15
相关资源
最近更新 更多