【问题标题】:When to use foreach loop for retrieving data from relational database and when not to何时使用 foreach 循环从关系数据库中检索数据,何时不使用
【发布时间】:2021-07-24 15:17:46
【问题描述】:

目前我已经使用 Laravel 8 完成了我的电影存储项目,对于这个项目,我尝试应用这些关系:

Movie AND Actor : Many To Many

Movie AND Director : Many To One

Movie AND IMDB : One To One

Movie AND Genre : Many To Many

我也将关系应用到他们的模型中,并且可以正确地从数据库中获取数据:

@foreach(\App\Models\Movie::all() as $movie)
<tr>
    <th scope="row">{{ ++$menuCounter }}</th>
    <td><a href="{{ $movie->link }}">{{ $movie->name }}</a></td>
    <td>{{ $movie->year }}</td>
    <td>
        @foreach($movie->actors as $actor)
            {{ $actor->name }}
        @endforeach
    </td>
    <td>
        @foreach($movie->genres as $genre)
            {{ $genre->name }}
        @endforeach
    </td>
    <td>{{ $movie->imdb->rate }}</td>
    <td>{{ $movie->director->name }}</td>
</tr>
@endforeach

但我有一个问题在我脑海中盘旋:

什么时候和什么情况下我必须使用foreach循环来获取数据,什么时候不使用foreach

例如,如果我说{{ $movie-&gt;genres-&gt;name }} 而不是使用foreach 循环,我会得到这个错误:

异常此集合实例上不存在属性 [名称]

但是如果我尝试$movie-&gt;genres,这个数组已经存在:

[
    {
        "id": 2,
        "name": "Thriller",
        "created_at": "2021-05-01T11:17:24.000000Z",
        "updated_at": "2021-05-01T11:17:24.000000Z",
        "pivot": {
            "movie_id": 9,
            "genre_id": 2
        }
    }
]

那么对于多对多关系我是否需要使用foreach?什么情况下可以直接使用Model中写的方法,调用$movie-&gt;genres-&gt;name这样的属性?

我知道这个问题有点奇怪,但我需要在脑海中说清楚这件事......

【问题讨论】:

  • 我不太明白这个问题。当你有集合时,你需要迭代它们。如果您确定一个集合只有一个元素,则获取第一个元素并访问其属性。
  • 因为$movie-&gt;genres 不是您的流派模型的实例。它是 Collection 对象的一个​​实例,其 elements 是 Genre 的实例。把它想象成一个对象数组。您无法访问数组本身的对象属性。您需要先获取特定对象才能访问其属性。
  • 简单地说..你想访问与其他模型有很多或多对多关系的数据..那么你需要使用foreach,因为你正在检索有很多关系(数据) ,,, 电影演员示例
  • 取决于您如何定义关系。如果它是*对一,您将获得模型的实例。如果它是*对多,你会得到一个集合。
  • 我还要补充一些提示:永远不要使用\App\Models\Movie::all(),你可以拥有10000,这会炸毁任何人的电脑(查看内容时),尤其是你的服务器,你应该使用@ 987654321@ 并且每次调用不超过 100,此外,因为您有关系,您遇到查询问题,您运行的查询比您应该运行的要多,要解决此问题,您可以使用 with(称为 @987654338 @)。

标签: php laravel foreach relational-database laravel-8


【解决方案1】:

我知道这个问题有点奇怪,但我需要在脑海中说清楚这件事......

这个问题是一个简单直接的问题,但由于 (a) 错误的数据模型或错误的 DDL,以及 (b) 多个级别的实现问题,它变得复杂了。让我从上往下回答,而不是从下往上回答,这就是你的看法。

RDBMS • 设置处理

Codd 的关系模型完全基于集合。 SQL(真正的,标准的)是RM中定义的Data Sublanguage的再现,它完全是基于集合的。集合处理速度极快。

  • 因此,应该始终且仅在 SQL 中使用 Set Processing 命令

RDBMS • 程序处理

又名逐行处理;又名foreach 处理。在极少数情况下,允许针对关系数据库进行此类处理,例如。银行的 MonthEnd 程序,当月的所有帐户都被统计并确定月末数字时。程序处理非常缓慢。

  • 任何其他程序处理都会使编码器回到 1960 年代
  • cursor 是程序处理。

非关系型数据库

通常,免费软件 (a) 滥用术语“sql”,并且 (b) 没有架构,因此没有适当的功能分离,更不用说这些功能的深度和成熟度了。因此:

  • 当给定的表超过几个时,它无法执行集合处理,或者
  • 它无法弄清楚如何解析多个表的 JOIN,并构造一个高效的QueryPlan

一些程序员通过调整 SQL 以获得更好的性能,或者诉诸foreach 处理来解决这个问题。

错误的数据模型/DDL/附加层

第二个典型问题是在建模或 DDL(好的模型,坏的 DDL)或层(好的 DDL,坏的层规范)上的表规范不正确。例如。错误如:

此集合实例上不存在异常属性 [名称]

这导致 Set Processing 尝试失败,开发人员求助于程序处理。

正确的修正当然是修复Model/DDL/Layer,从而获得Set Processing和速度。

那么对于多对多关系我需要使用foreach 吗?什么情况下可以直接使用Model中写的方法,调用$movie-&gt;genres-&gt;name这样的属性?

我不是 Laravel 专家(从来没有需要,因为我使用商业 SQL 平台),但这是附加层的典型限制。你可以通过理解层和修改代码来绕过它,直到它工作。根据 cmets。

我不知道 Laravel 是否可以做真正的 Set Processing(从这个例子看来不太可能)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-22
    • 1970-01-01
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多