当前位置: 首页 > 面试题库 >

MySQL最佳实践:SELECT子级尽可能地递归执行?

华展鹏
2023-03-14
问题内容

我想选择一个根项,它是尽可能多的孩子。我更喜欢使用嵌套集模型,但是这次表结构遵循 邻接模型
。有关嵌套集和邻接模型的更多信息。

我有一个dependencies-table,一个items-table

依赖表

dependency_id | item_id | child_id 
            1 |       1 |        4
            2 |       2 |        5
            3 |       4 |        7
            4 |       7 |        3
            5 |       9 |        3
            6 |       1 |        2

项目表

item_id | name   | info
      1 | Item A | 1st Item
      2 | Item D | 2nd Item
      3 | Item C | 3rd Item
      4 | Item D | 4th Item
      5 | Item E | 5th Item
      6 | Item F | 6th Item

SQL,先尝试

# selecting children (non-recursive)
# result: 4, 2
SELECT 
   child_id AS id 
  FROM `dependencies_table`
 WHERE item_id = 1

我需要此SELECT递归。

所需的输出

# children of item #1
dependency_id | item_id | child_id
            1 |       1 |        4 // 1st level
            6 |       1 |        2 // 1st level
            2 |       2 |        5 // 2nd level, 1->2->5

这种情况应该很常见,但是我想知道我现在找不到最佳实践。请注意:它是MySQL,所以我 无法使用CTE

您将如何解决这个问题?提前致谢!


问题答案:

作为NoSQL人员,我不得不说多数民众赞成在使用什么图形。但是,是的,我明白了。使用SQL是有原因的,但是这个特定示例并不是这些数据库的用途,特别是当您可以拥有n个子级时,mysql的执行速度会非常慢,实际上存在一个查询为此,即使是n级,但这也有些疯狂。(如果我没记错的话,大约有42个内部联接)

所以,是的,您想获取表并使用php来处理子项。

一旦您获取了整个Dependencies Table,下面就是您如何在php中获得结果的方法,

$dep = array();
$dep[] = array('item_id' =>'1', 'child_id' =>'4');
$dep[] = array('item_id' =>'2', 'child_id' =>'5');
$dep[] = array('item_id' =>'4', 'child_id' =>'7');
$dep[] = array('item_id' =>'7', 'child_id' =>'3');
$dep[] = array('item_id' =>'9', 'child_id' =>'3');
$dep[] = array('item_id' =>'1', 'child_id' =>'2');

function getchilds($dependencies, $id) {

    $ref = array();
    foreach($dependencies as $dep){
        $item_id = $dep['item_id'];
        $child = $dep['child_id'];
        if(!is_array($ref[$item_id])) $ref[$item_id] = array('id' => $item_id);
        if(!is_array($ref[$child])) $ref[$child] = array('id' => $child);
        $ref[$item_id]['children'][] = &$ref[$child];
    }
    return $ref[$id];
}

getchilds($dep,1);

这使用引用仅对每个项目进行一次检查,我无法对任何性能更高的图像进行成像,并且它适用于无数个级别。实际上,我敢打赌,对于固定数量的级别,这比任何SQL查询都快。

对于第一个项目,这基本上会给你

1 - 2 - 5
 \ 
  4 - 7 - 3


 类似资料:
  • Overview This article discusses performance and reliability best practices for Express applications deployed to production. This topic clearly falls into the “devops” world, spanning both traditional

  • 性能与体验是前端的核心竞争力,是最直观反应页面是否好用、易用的标准。用户花在页面上的时间不应该是在等待页面加载和响应,而是使用和顺畅浏览的时间,因此如何提升页面性能和体验,让页面更快的可交互、浏览滚动更顺畅,是需要你持续的研究、优化、推进的。在 Rax 不断应用发展以及成熟的过程中,沉淀总结了一系列的性能体验的措施和最佳实践,通过这些,可以帮助你大幅提高页面的各项性能。 加载性能 统计口径 加载性

  • 我正在使用redis pub/sub 编写两个或多个节点进程之间的p2p通信,使用的是lib。 我将发布不同类型的消息,如: 您好:通知其他订阅者新进程已连接 我不知道是否它是更好的为redis订阅许多通道(一个消息类型)或创建一个单一的通道,并发送一个属性,定义消息的类型,如: 提前谢谢

  • 这里有些给使用和编写 Ansible playbook 的贴士. 你能在我们的 ansible-example repository.找到展示这些最佳实践的 playbook 样例.(注意: 这些示例用的也许不是最新版的中所有特性,但它们仍旧是极佳的参考.) Topics 最佳实践 接下来的章节将向你展示一种组织 playbook 内容方式. 你对 Ansible 的使用应该符合你的需求而不是我们

  • 处理后台任务与常规调用方法有很大的不同。本指南旨在帮助让您的后台任务平稳有效地运行。本文基于 这篇博客文章。 使任务参数小而简单 方法(任务)在调用之前会被序列化。使用 TypeConverter 类将参数转换为 JSON 字符串。如果您有复杂的实体和 / 或大对象; 包括数组,最好将它们放入数据库,然后只将其标识 (id) 传递给后台任务。 错误例子: public void Method(En

  • VR设计 VR设计不同于平面体验设计。作为一种新的媒介,有新的最佳实践需要遵循,特别是保持用户的舒适性和存在性。这在如下指南中已经写得很透彻了: Oculus VR最佳实践 Leap Motion VR最佳实践指南 一些值得注意的事情: 公共的金科玉律是永远不要意外地把相机控制权从用户手中剥夺。 单位(比如对于位置)应该考虑使用米(m)。这是因为WebVR API以米为单位返回姿势数据,进而传送给