在数据库中实现分层数据结构
我知道有两种方法:邻接列表和嵌套树。 据说由于许多查询,邻接列表在遍历中可能会变得很慢。 但我不知道这个现实的数字。 我正在制作的网站将有200页的区域。 是否遍历生成(例如)一个站点地图需要超过约0.3秒?
在LAMP堆栈上运行MySQL(innoDB)。
由于更简单的设计,如果可能的话,我宁愿实现邻接关系。
谢谢。
有更多的选择,而不仅仅是你提到的两个。 有:
请参阅我的回答:“将一张平板分析成树的最有效/最优雅的方式是什么?”
或者几本书:
文章管理MySQL中的分层数据详细介绍了这一点。
我会推荐“嵌套集合”技术,因为它可以让你在一个查询中获得整棵树(及其子)。 基本读取便宜,但写入很昂贵,因为整棵树必须重新平衡。 但是,如果你有99%的读数,那么它是完全合理的。
解析邻接列表的天真方法需要大量查询,而对于大型列表而言,可能需要大量时间才能构建内存。 作为参考,我指的天真方法可以概括为:选择所有没有父项的项目,然后对每个项目递归地获取它的子项。 这种方法需要n + 1个数据库查询。
我用下面的方法用1个查询构建一个邻接表。 从数据库中选择所有项目。 将所有项目转移到按键进行索引的数组中。 遍历数组并将父对象的引用分配给它的每个子对象。 再次遍历数组并删除所有仅留下根级别对象的子对象。
由于您提到了LAMP堆栈,因此执行此操作的PHP代码大致如下所示:
<?php
// Assumes $src is the array if items from the database.
$tmp = array();
// Traverse the array and index it by id, ensuing each item has an empty array of children.
foreach ($src as $item) {
$item['children'] = array();
$tmp[$item['id']] = $item;
}
// Now traverse the array a second time and link children to their parents.
foreach ($tmp as $id => $item) {
if ($item['parent_id'] != 0 || $item['parent_id'] !== NULL) {
$tmp[$item['parent_id']]['children'][$id] = &$tmp[$id];
}
}
// Finally create an array with just root level items.
$tree = array();
foreach ($tmp as $id => $item) {
if ($item['parent_id'] == 0 || $item['parent_id'] === NULL) {
$tree[$id] = $item;
}
}
// $tree now contains our adjacency list in tree form.
?>
请注意,此代码旨在说明从单个数据库查询构建邻接列表的技术。 它可能可以针对更少的内存消耗进行优化,等等。它还没有经过测试。
吉姆
链接地址: http://www.djcxy.com/p/35033.html上一篇: Implementing a hierarchical data structure in a database
下一篇: How to define a TVirtualStringTree with dynamic data structure