【问题标题】:Laravel relationships - are there multiple *unnecessary* database calls?Laravel 关系 - 是否有多个*不必要的*数据库调用?
【发布时间】:2017-10-20 07:50:09
【问题描述】:

我有 2 个模型:PostUser,其中每个 Post 有一个 User,每个 User 有很多 Posts。

用户.php:

// User.php

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

Post.php:

// Post.php

public function user()
{
    return $this->hasOne(User::class);
}

我通过我的PostsController 加载帖子:

// PostsController.php

public function show($id)
{
    $post = Post::find($id);

    return view('posts.show', compact('post'));
}

在视图中,我调用了我在中加载的帖子和与帖子相关的用户。我多次调用用户对象:

// views/posts/show.blade.php

<h1>{{ $post->title }}</h1>
<p>{{ $post->user->name }}</p>
<p>{{ $post->user->email }}</p>

这 2 次对 $post-&gt;user 资源的调用会对数据库进行 2 次调用吗?

Eloquent 关系在后端是如何工作的?当我获得post 对象时,关系是否总是返回整个user 对象,还是懒惰地获得user 数据?

我担心将我的数据库托管给一个提供商,该提供商根据从数据库传输的数据 (GCP) 收费,我不明白 Eloquent 关系将如何调用数据库。

【问题讨论】:

  • From docs:动态属性是“延迟加载”,这意味着它们只会在您实际访问它们时加载它们的关系数据
  • 它只会运行一次$post-&gt;user
  • 我觉得这个问题太笼统了。您的问题在文档和源代码中都有介绍。

标签: php mysql laravel laravel-5.5


【解决方案1】:

Laravel 提供了一个名为 Eager Loading 的功能,可让您通过优化查询来加载模型和任何关系:

Post::with('user')->find($id);

急切加载也适用于许多关系。无论用户拥有多少帖子,以下内容也只会产生两个查询:

User::with('posts')->find($id);

这将加载 Post 实体的用户模型,以便访问它不需要第二次查询。您可以在docs 中阅读有关预加载和其他性能增强的更多信息。

【讨论】:

  • 预加载将执行 2 个查询:... 幸运的是,我们可以使用预加载将此操作减少到仅 2 个查询。查询时,您可以使用 with 方法指定应该预先加载哪些关系 ...
  • 我会稍微更新一下答案,以涵盖问题 这 2 次对 $post->user 资源的调用是否会对数据库进行 2 次调用? 。查看问题下方的我的 cmets,并对此进行扩展;)
  • 文档中深入介绍了任何其他问题。我可以复制粘贴文档或只是链接到它们,因为我已经有了:)
  • 这确实是一个问题这两个电话会...。在他的示例中,有 2 个查询,1 个用于帖子,1 个用于用户。他想知道是否执行了 3 个查询以及它是如何工作的?
猜你喜欢
  • 1970-01-01
  • 2018-11-08
  • 1970-01-01
  • 2014-01-04
  • 2023-04-10
  • 1970-01-01
  • 2013-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多