【问题标题】:How to efficiently insert an array as nested set model with Laravel/PHP and MySQL如何使用 Laravel/PHP 和 MySQL 有效地将数组作为嵌套集模型插入
【发布时间】:2019-08-22 07:44:53
【问题描述】:

我正在使用这个包来处理 Laravel 中的层次结构数据:https://github.com/lazychaser/laravel-nestedset

它们是一个已实现的功能,它提供了使用多维数组create 新数据的机会。所以我有以下示例数组(文件/目录层次结构):

array:3 [
  "name" => "Folder1"
  "type" => "folder"
  "children" => array:2 [
    0 => array:2 [
      "name" => "test1.txt"
      "type" => "txt"
    ]
    1 => array:3 [
      "name" => "Folder1.1"
      "type" => "folder"
      "children" => array:2 [
        0 => array:2 [
          "name" => "file.png"
          "type" => "png"
        ]
        1 => array:3 [
          "name" => "folder1.1.1"
          "type" => "folder"
          "children" => array:1 [
            0 => array:2 [
              "name" => "file.txt"
              "type" => "txt"
            ]
          ]
        ]
      ]
    ]
  ]
]

但是它们是具有超过 10GB 数据的目录,这意味着它们比所示示例具有更高的复杂性,并且具有较深的层次结构。数据库已经填充了超过一百万行。如果我尝试插入一个新数组,MySQL 会立即在 100% CPU 上运行,并且需要大约 20 分钟才能将新结构插入数据库。

原因是考虑到表中已经存在的数据,需要为嵌套集计算LEFT和RIGHT。

有没有更有效的方法将此类层次结构插入数据库?

【问题讨论】:

  • 我怀疑您使用的例程正在插入记录,然后在插入更多记录时更新数据库中的 LEFT 和 RIGHT 值。导致大量的SQL语句。如果是这样,那么在 PHP 中提前计算 LEFT 和 RIGHT(递归例程循环遍历树结构,通过引用传递结构和数字)可能会更有效。
  • @Kickstart 嗯,但是如果我事先计算 LEFT 和 RIGHT(在构建数组时),我必须执行与读取数组并计算 LEFT 和 RIGHT 时相同的查询来读取/计算它们那么。
  • 我不知道 Laravel(但使用过嵌套集)。您可能必须扩展功能才能执行此操作。但是使用递归函数,您应该能够以最少的计算来完成它。很重要。

标签: php mysql laravel nested-sets


【解决方案1】:

将左右项添加到各种数组的快速示例(假设数组的最低级别是一行项,因此无需为这些单独的项添加左右项)。

这样的东西可以用来添加值

<?php 

  function array_left_right (&$array, &$counter = 1)
  {
    if (is_array($array))
    {
      $array['left'] = $counter++;
      foreach($array as $array_key=>&$array_item)
      {
            array_left_right($array_item, $counter);
      }
      $array['right'] = $counter++;
    }
  }

  $fred = array(array(array('a', 'b'), array('c', 'd'), array('e', 'f'), array('g', 'h')),array(array('aa', 'ab'), array('ac', 'ad'), array('ae', 'af'), array('ag', 'ah')));

  array_left_right($fred);

  print_r($fred);

【讨论】:

  • 酷!如果我已经在数据库中有值,我需要添加哪个值作为开始计数器而不是 1?
  • @MangoD,取决于您添加它们的位置。但假设您将它们置于最低级别,请将其设置为现有的 max RIGHT,然后将现有的 max right 更改为 $counter 的最终值。
猜你喜欢
  • 2011-12-05
  • 1970-01-01
  • 2018-12-29
  • 1970-01-01
  • 1970-01-01
  • 2017-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多