使用单个MySQL表的递归树CRUD PHP

时间:2010-08-06 06:16:57

标签: php mysql

我正在使用来自jesse price的教程,但它不适用于我,它只显示根元素,所以我想有人能给我一个线索递归树的CRUD如何工作的线索? 这是一个面试问题,不用说,我没有工作,但我仍然想知道它是如何工作的....使用单个MySQL表请帮忙!

3 个答案:

答案 0 :(得分:0)

一旦理解了READ / SELECT,CRUD的其余内容就变得非常简单了。

1)首先选择所有具有parent_id = 0又称根节点的节点:

$nodes = SELECT * FROM nodes WHERE parent_id = 0;

2)对于每个返回的节点,您运行另一个选择查询parent_id = node_id

3)重复步骤2直到无限期或直到没有更多子节点。


插入无需知道,您只需插入一个新行并指定parent_id

更新和删除有点复杂,有几种方法,我建议您查看以下演示文稿:http://www.slideshare.net/billkarwin/models-for-hierarchical-data

答案 1 :(得分:0)

BTW,我很久以前写过这篇博文。我将不得不基于模型(mvc)和递归模式为php5 oop创建更新的教程。

就像Alix Axel所说,你需要在mysql表中添加另一个列,你想要一个递归的层次结构。

以下是一些更好的例子

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

答案 2 :(得分:0)

这可能有助于您入门 - 只考虑如何在没有孤儿的情况下移除节点!!

http://i.imagehost.org/0934/product_hier.jpg

-- the table

drop table if exists product;
create table product
(
prod_id smallint unsigned not null auto_increment primary key,
name varchar(32) not null,
parent_id smallint unsigned null
)engine = innodb;

-- some test data

insert into product (name, parent_id) values
('Products',null), 
   ('Systems & Bundles',1), 
   ('Components',1), 
      ('Processors',3), 
      ('Motherboards',3), 
        ('AMD',5), 
        ('Intel',5), 
           ('Intel LGA1366',7);




-- the stored proc for returning a hierachy

drop procedure if exists product_hier;

delimiter #

create procedure product_hier
(
in p_prod_id smallint unsigned
)
begin

declare p_done tinyint unsigned default(0);
declare p_depth smallint unsigned default(0);

create temporary table hier(
 parent_id smallint unsigned, 
 prod_id smallint unsigned, 
 depth smallint unsigned default 0
)engine = memory;

insert into hier values (p_prod_id, p_prod_id, p_depth);

/* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */

create temporary table tmp engine=memory select * from hier;

while p_done <> 1 do

    if exists( select 1 from product p inner join hier on p.parent_id = hier.prod_id and hier.depth = p_depth) then

        insert into hier 
            select p.parent_id, p.prod_id,  p_depth + 1 from product p 
            inner join tmp on p.parent_id = tmp.prod_id and tmp.depth = p_depth;

        set p_depth = p_depth + 1;          

        truncate table tmp;
        insert into tmp select * from hier where depth = p_depth;

    else
        set p_done = 1;
    end if;

end while;

select 
 p.prod_id,
 p.name as prod_name,
 b.prod_id as parent_prod_id,
 b.name as parent_prod_name,
 hier.depth
from 
 hier
inner join product p on hier.prod_id = p.prod_id
inner join product b on hier.parent_id = b.prod_id
order by
 hier.depth, hier.prod_id;

drop temporary table if exists hier;
drop temporary table if exists tmp;

end #

delimiter ;


-- the table

select * from product;

-- call the stored proc passing in the root node you want to get a sub-tree for

call product_hier(1);

call product_hier(3);

call product_hier(5);