Yii2中的线程数据

问题描述 投票:5回答:2

我正在寻找通过Active Record解决方案来获得单个查询中的分层数据。

我现在正在做的是首先获取所有数据,然后使用递归函数将数组转换为所需的数组。

$allUsers = User::find()
        ->asArray()
        ->all();
$arr = Yii::$app->TreeComponent->getUserChildren($allUsers, $userId, $userId);

并在TreeComponent中

public function getUserChildren($src_arr, $currentId, $userId, $parentFound = false)
{
    $cats = array();
    foreach ($src_arr as $row) {
        if ($row['id'] == $userId) {
            $row['parent'] = "";
        }
        if ((!$parentFound && $row['id'] == $currentId) || $row['parent'] == $currentId) {
            $rowData = array();
            foreach ($row as $k => $v)
                $rowData[$k] = $v;
            $cats[] = $rowData;
            if ($row['parent'] == $currentId) {
                $cats = array_merge($cats, $this->fetchRecursive($src_arr, $row['id'], true));
            }
        }
    }
    return $cats;
}

它的工作正常。但最近我通过CakePHPfind('threaded'),我认为它将节省递归函数执行时间和更少的代码。

我很好奇Active Record是否还有任何功能。

activerecord yii2 hierarchical-data
2个回答
2
投票

在Yii2中没有这样的功能。 CakePHP还将在后台执行多个查询,并将其包装在多线程调用中。如果您实际上只能执行一个查询,那么您将获得主要的速度优势。

有两种方法可以实现这一目标:

  • 您的方式...获取所有内容并将其合并到您的代码中
  • 上面的注释中提到的NestedSet模式

NestedSet

对于Yii2,我们有一个很好的扩展来实现嵌套的set模式。你可以在这里找到它:

https://github.com/creocoder/yii2-nested-sets

优点和缺点

显然,优点是您可以使用单个查询获取所有内容。您甚至可以在一个表中保存多个树。

主要缺点是根据列进行排序,同时仍保持树结构。嵌套集由两个属性组成:左和右。这意味着,所有数据都根据这两个属性进行排序。要获取按名称排序的树结构,您仍然必须实现代码端功能以在查询后更改接收的数据集。最干净的方法是在保存时对数据进行排序...意味着根据所需排序中的位置插入新记录

维基百科对嵌套集有很好的解释:qazxsw poi

此图显示了它的工作原理:

https://en.wikipedia.org/wiki/Nested_set_model

示例:'slacks'和'jacket'是'suit'的子项,因为它们的左右属性都在'suit'的left(3)和right(8)值之间。如果你想将一个孩子添加到'夹克',你会在6到7之间注入它...因此将所有值增加到大于或等于7乘以2。然后,新注入的“夹克”子项将接收左值7和右值8。

如您所见,您现在可以通过过滤左右属性轻松获取整个(子)树。如果您想要从“西装”向下的所有内容,您的查询将如下所示:

NestedSet illustration

最后回答你的问题

如果你的主要关注是舒适

不,没有这样的功能。如果您仍然希望数据库中有常规树,并且不想关心合并数据,则必须为CakePHPs方法编写similliar功能。这应该很容易,我想会有很多人对它感兴趣。

如果你主要担心的是速度

使用嵌套集。这是一个模式和地狱强大的地狱!


0
投票

这是另一种存储树并在没有递归的情况下获取树的方法。它需要2个表。

SELECT * FROM mytable WHERE left >= 3 AND right <= 8 ORDER BY left ASC

例:

tree_data

  Column   |  Type   |                                         
-----------+---------+
 id        | integer | 
 parent_id | integer |
 level     | integer |
 sort      | integer | 


tree_structure

 Column |  Type   |                          
--------+---------+
 parent | integer |
 child  | integer |

结果树:

select * from tree_data;

 id | parent_id | level | sort 
----+-----------+-------+------
  1 |         0 |     0 | 1000
  2 |         1 |     1 | 1000
  3 |         1 |     1 | 2000
  4 |         1 |     1 | 1500
  5 |         1 |     1 | 1750
  6 |         5 |     2 | 1000


select * from tree_structure order by parent, child;

 parent | child 
--------+-------
      1 |     1
      1 |     2
      1 |     3
      1 |     4
      1 |     5
      1 |     6
      2 |     2
      3 |     3
      4 |     4
      5 |     5
      5 |     6
      6 |     6

要查询树:

├── 1
│   ├── 2
│   ├── 4
│   ├── 5
│       ├── 6
│   ├── 3

这是SELECT tree_data.* FROM tree_data INNER JOIN tree_structure ON tree_data.id = tree_structure.child and tree_structure.parent = 1 ORDER BY level, sort; 的一组类

© www.soinside.com 2019 - 2024. All rights reserved.