当前位置: 首页 > 知识库问答 >
问题:

PHP-保存到foreach循环外部的数据库

曾翰飞
2023-03-14

我有下面的Foreach循环,它迭代了一堆不同的自定义规则,我的用户可以应用。

public function parse(Document $document)
{
        $content = $document->text;
        $rules = $document->stream->fieldrules;

        foreach ($rules as $rule) {
            $class = $this->getClass($rule);
            $content = $class->apply($content);

            //Save to database.
            $fieldresult = new FieldRuleResult();
            $fieldresult->create([
                'field_rule_id' => $rule->field_id,
                'document_id' => $document->id,
                'content' => $content
            ]);
        }
}

如您所见,我在每次迭代中调用数据库。一些用户可能定义了多达50条规则,这将导致50条insert查询。因此,我相信我可能遇到了n1问题。

我想知道-这里的最佳实践是什么?我尝试搜索了Laravel文档,找到了createMany方法。因此,我尝试将迭代重构为以下内容:

$result = [];
foreach($rules as $rule)
{
  $class = $this->getClass($rule);
  $content = $class->apply($content);
  $fieldresult = new FieldRuleResult();

  $result[] = [
     'field_rule_id' => $rule->field_id, 
     'document_id' => $document->id, 
     'content' => $content];
}

return $rules->createMany($result);

这给我下面的错误:

Method Illuminate\Database\Eloquent\Collection::createMany does not exist.

现在我想这是因为$rules返回一个集合。我试着把它改成:

return $document->stream->fieldrules()->createMany($result);

这给我下面的错误:

Call to undefined method Illuminate\Database\Eloquent\Relations\HasManyThrough::createMany()

共有2个答案

卫仲卿
2023-03-14

如果出于任何原因需要触发有说服力的事件,并且您希望针对n1问题进行优化,我建议使用事务。这仍然会产生n查询,但数据库可以通过批量插入(因为事务)对此进行优化。它还有数据一致性的额外好处(要么所有插入都成功,要么没有成功)。

$result = getResult();

\DB::transaction(function() use ($result) {
    foreach($result as $item) {
        FieldRuleResult::create($item);
    }
});

如果您不关心有说服力的事件被触发,您只想“批量插入”,您可以使用Fabian提到的insert方法。不过,为了数据的一致性,我仍然建议使用数据库事务。

$result = getResult();

\DB::transaction(function() use ($result) {
    FieldRuleResult::insert($result);
});

在后一种情况下,如果要插入的条目数量可能是“大的”,那么您可能还希望将这些插入分块。(例如一次100,而不是一次全部)

史懿轩
2023-03-14

illumb/Database/Query/Builder中有一个名为insert的方法可用。此方法允许您在一个查询中插入多个模型。值得注意的是,这不会像所有多合一查询方法那样触发雄辩的事件。

与前面一样,将数据存储在数组中,并在循环完成后执行查询。但是,这次您可以使用insert

$content = 'your content here...';

$data = [];

foreach($rules as $rule) {

    $class = $this->getClass($rule);

    $content = $class->apply($content);

    $data[] = [
        // ...
        'content' => $content
    ];
}

FieldRuleResult::insert($data);

不能100%确定这直接适用于模型。然而,在留档中,您可以找到一个带有DB外观的示例。

 类似资料:
  • 问题内容: 我正在运行此数据库调用以获取多维数组,我试图获取每个数组的键,但是当我尝试将其显示为空白或数组时。 这是我的PHP循环遍历: 另外,当我运行一个仅将数组吐出的测试时,这就是结果,我想要呈现的是 [费城] 问题答案: 您可以这样访问数组键:

  • 问题内容: 我第一次不了解PHP。我一直在脚本中使用for循环,while循环,foreach循环。我想知道 哪一个性能更好? 选择循环的标准是什么? 当我们在另一个循环中循环时应该使用哪个? 我一直想知道要使用哪个循环的代码。 很明显,我可以使用while编写上面的代码。希望有人能帮助我找出哪个循环更适合使用。 问题答案: 哪一个性能更好? 没关系 选择循环的标准是什么? 如果只需要遍历对象或数

  • 我想我这样做是完全错误的,但是我想在foreach循环运行的数组的末尾添加一个数组。 例如,这是开始结果 这是im使用的代码 期望的最终结果

  • 对于range(),我有一个非常奇怪的问题;根据文件: 但当我这样做时: 甚至 输出奇怪地以一系列的方式重复 这意味着它将返回到每个循环后的第一个ID。 当我只是放置一个手动数组时,它的工作非常有序,没有重复: 我做错了什么(又一次??) 编辑I 下面是整个脚本: http://pastebin.com/zhm3ub6n 它实际上是simplehtmldom脚本中包含的slashdot刮取示例的稍

  • 我正在迭代JSON数据,获取数据并将其赋值给一个全局变量,当我在循环内打印变量时,我得到了所有数据,然而,当我在循环外打印变量时,我只得到了JSON对象的最后一些数据。我的目标是获取数据并将其作为函数的参数传递。我如何获取循环之外的所有数据?

  • foreach循环遍历列表值并将控制变量(var)依次设置为列表的每个元素 - 语法 (Syntax) Perl编程语言中foreach循环的语法是 - foreach var (list) { ... } 流程图 (Flow Diagram) 例子 (Example) #!/usr/local/bin/perl @list = (2, 20, 30, 40, 50); # foreach lo