一尘不染

有效而轻松地实现等级制,父母/子女关系

mysql

我有一张桌子

create table site
(
site_Id int(5),
parent_Id int(5),
site_desc varchar2(100)
);

领域的意义:

  • site_Id:网站的ID
  • parent_Id:站点的父ID
  • site_desc:尽管与问题无关,但是具有站点的描述

要求是,如果我有一个site_id作为输入,并且需要该网站下方标记的所有ID。例如:

                    A
                   / \
                  B   C
                / | \ /\
               D  E F G H
              /\
             I  J

所有节点都是site_Id。

该表包含如下数据:

Site_id  | Parent_ID  |  site_desc
_________|____________|___________
 A       |   -1       |   
 B       |    A       |
 C       |    A       |
 D       |    B       |
 E       |    B       |
 F       |    B       |
 I       |    D       |
 J       |    D       |

......

A是B和C的父代,依此类推。

如果B是给定的输入,则查询需要获取D,E,I,F,J

目前,它是通过循环中的多个查询来实现的,但我当时正在考虑以最少数量的查询来实现。

我目前正在做的是:

否决

该算法是这样的:

Initially create a data set object which you will populate, by fetching data from the data base. 
Create a method which takes the parent id as parameter and returns its child nodes if present, and returns -1, if it doesnt have a child. 
Step1: Fetch all the rows, which doesn't have a parent(root) node. 
Step2: Iterate through this result. For example if prod1 and prod2 are the initial returned nodes, in the resultset. 
Iterating this RS we get prod1, and we insert a row in our DataSET obj. 
Then we send the id of prod1 to getCHILD method, to get its child, and then again we iterate the returned resultset, and again call the getCHILD method, till we dont get the lowest node.

我需要在数据模型约束内的最佳优化技术。如有任何建议,请随时回答。
请提出任何建议。提前致谢。


阅读 278

收藏
2020-05-17

共1个答案

一尘不染

不幸的是,如果您无法更改数据模型,并且使用的是MySQL,则将陷入需要递归查询并且使用不支持递归查询的DBMS的局面。

Quassnoi写了一系列有趣的博客文章,展示了查询分层数据的技术。他的解决方案非常聪明,但是非常复杂。
http://explainextended.com/2009/03/17/hierarchical-queries-in-
mysql/

PostgreSQL是另一个开源RDBMS,它确实支持递归查询,因此您可以按照显示的方式获取整棵树。但是,如果您不能更改数据模型,则假定您无法切换到其他RDBMS。

有几种可供选择的数据模型,它们使得获取任意深的树变得更加容易:

  • 封闭表
  • 嵌套集又称为修改后的预序树遍历
  • 路径枚举又称实体化路径

我将在我的演示文稿“ 使用SQL和PHP的层次数据模型”中以及在《SQL反模式:避免数据库编程的陷阱》一书中介绍这些内容。

最后,在Slashdot的代码中,我看到了另一个解决方案,用于它们的注释层次结构:它们像在“邻接表”中一样存储“
parent_id”,但它们还存储“
root_id”列。给定树的每个成员具有相同的root_id值,root_id是其树中的最高祖先节点。然后,很容易在一个查询中获取整棵树:

SELECT * FROM site WHERE root_id = 123;

然后,您的应用程序将所有节点从数据库中取回一个数组,并且您必须编写代码以遍历该数组,将节点插入内存中的树数据结构中。如果您有许多单独的树,并且每棵树都有相对较少的条目,那么这是一个很好的解决方案。这对Slashdot的案子很有好处。

2020-05-17