Yii2中的线程数据

ank*_*itr 5 activerecord hierarchical-data yii2

我正在寻找一个解决方案Active Record来获取单个查询中的分层数据.

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

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

并在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;
}
Run Code Online (Sandbox Code Playgroud)

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

如果Active Record中也存在任何功能,我很好奇.

PLM*_*M57 2

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

有两种方法可以实现此目的:

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

嵌套集

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

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

优点和缺点

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

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

维基百科对嵌套集有很好的解释: https: //en.wikipedia.org/wiki/Nested_set_model

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

嵌套集图

示例:“slacks”和“jackets”是“suits”的子项,因为它们的左属性和右属性都在“suits”的左值 (3) 和右值 (8) 之间。如果您想将一个子项添加到“夹克”中,您可以将其注入 6 到 7 之间...因此,将所有大于或等于 7 的值增加 2。新注入的“jackets”子代将收到左值 7 和右值 8。

正如您所看到的,您现在只需过滤左侧和右侧属性即可轻松获取整个(子)树。如果您想要从“西装”向下的所有内容,您的查询将如下所示:

SELECT * FROM mytable WHERE left >= 3 AND right <= 8 ORDER BY left ASC
Run Code Online (Sandbox Code Playgroud)

最后回答你的问题

如果您主要关注的是舒适度

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

如果您主要关心的是速度

使用嵌套集。这是一个地狱般的模式,而且非常强大!