php - 以有效和简单的方式实现层次结构、父/子关系

标签 php mysql sql algorithm hierarchical-data

我有一张 table

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

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

我目前正在做的是::

反对票

算法是这样的:

  • 首先创建一个数据集对象,您将通过从数据库中获取数据来填充该对象。
  • 创建一个方法,该方法将父 id 作为参数并返回其子节点(如果存在),如果没有子节点则返回 -1。
  • 第 1 步:获取所有没有父(根)节点的行。
  • 第 2 步:遍历此结果。例如,如果 prod1 和 prod2 是结果集中的初始返回节点。
  • 迭代此 RS,我们得到 prod1,并在我们的 DataSET obj 中插入一行。
  • 然后我们将prod1的id发送给getCHILD方法,得到它的child,然后我们再次迭代返回的结果集,再次调用getCHILD方法,直到我们没有得到最低节点。

我需要在我的数据模型约束范围内获得最佳优化的技术。

最佳答案

不幸的是,如果您不能更改数据模型,并且您使用的是 MySQL,那么您将陷入需要递归查询并且您使用的 DBMS 不支持递归查询的情况。

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

PostgreSQL 是另一个开源 RDBMS,它执行 support recursive queries ,因此您可以按照显示的方式获取整棵树。但是,如果您无法更改数据模型,我认为您也无法切换到不同的 RDBMS。

有几种可供选择的数据模型可以更容易地获取任意深度的树:

  • Closure Table
  • 嵌套集又名修改后的预序树遍历
  • 路径枚举又名物化路径

我在我的演示文稿中介绍了这些 Models for Hierarchical Data with SQL and PHP , 在我的书中 SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming .

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

SELECT * FROM site WHERE root_id = 123;

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

关于php - 以有效和简单的方式实现层次结构、父/子关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11064913/

相关文章:

php - 检查 Instagram 个人资料是否私密,无需身份验证

php - 我怎样才能确保我在特定时间在 php 中发生某些事情,并且它发生在每个时区的那个时间?

mysql - case,if/else 语句计算超出规范值直到在值范围内

mysql - 如何像这样调整mysql中的自连接表?

SQL 查询给出一个数据值的总和并计算它超过 60 的次数

java - 在 Javafx 中实现 sql 查询的问题

php - WordPress 子主题包括包含文件

php - 带有 LinQ 过滤器和 jQuery tmpl 示例的 jQuery AJAX 请求

php - 原始 MySQL 中 Laravel Eloquent 的 ownTo 等价于什么

php - 哪个 CMS 可以混合启用 CMS 的页面和我的 PHP 程序?