SQL数据库 高效存储层次结构/目录树结构数据

1,098 阅读1分钟

一、预排序遍历树结构(MPTT,Modified Preorder Tree Traversal)

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

显示树状结构,子节点应该比他们的父节点稍微缩进一些。我们可以通过保存一个右值的一个栈。每次你从一个节点的子节点开始时,你把这个节点的右值添加到栈中。你也知道子节点的右值都比父节点的右值小,这样通过比较当前节点和栈中的前一个节点的右值,你可以判断你是不是在显示这个父节点的子节点。当你显示完这个节点,你就要把他的右值从栈中删除。要获得当前节点的层数,只要数一下栈中的元素。(按照 left排序)

PHP代码:

function toHierarchy($collection)
{
        // Trees mapped
        $trees = array();
        $l = 0;

        if (count($collection) > 0) {
                // Node Stack. Used to help building the hierarchy
                $stack = array();

                foreach ($collection as $node) {
                        $item = $node;
                        $item['children'] = array();

                        // Number of stack items
                        $l = count($stack);

                        // Check if we're dealing with different levels
                        while($l > 0 && $stack[$l - 1]['depth'] >= $item['depth']) {
                                array_pop($stack);
                                $l--;
                        }

                        // Stack is empty (we are inspecting the root)
                        if ($l == 0) {
                                // Assigning the root node
                                $i = count($trees);
                                $trees[$i] = $item;
                                $stack[] = & $trees[$i];
                        } else {
                                // Add node to parent
                                $i = count($stack[$l - 1]['children']);
                                $stack[$l - 1]['children'][$i] = $item;
                                $stack[] = & $stack[$l - 1]['children'][$i];
                        }
                }
        }

        return $trees;
}

其他参考文章:www.cnblogs.com/kissdodog/p… mat1.gtimg.com/hb/js/commo…

二、path 数据库结构(领接表增强,比较简单)

id name pid path level(非必要) order(非必要)
1 总裁办 0 /0/1/ 1
3 人事部 1 /0/1/3/ 2
8 行政部 1 /0/1/8/ 2
10 招聘一部 3 /0/1/3/10/ 3
11 招聘二部 3 /0/1/3/11/ 3
12 招聘专员 11 /0/1/3/11/12/ 4
2 财务部 0 /0/2/ 1
15 出纳 2 /0/2/15/ 2
16 会计 2 /0/2/16/ 2
9 技术部 0 /0/9/ 1
缺点:
  • 树的级别会受「path」字段长度的限制,但是应付一般tree足矣,如果「path」为「varchar(255)」,20级树完全没有问题;
  • 修改某节点父级时,其下属「path」、「level」均需要重新改变;
  • 查询子孙集时,通过「LIKE %/{$id}/%」查询比较低效,但是相对于递归查询来说,效率已经算是不错了。

这里写图片描述