Reputation: 5277
I have a huge employee data in mysql with an attribute as parent id which stores the supervisor of each employee and is defined in a hierarchy. Each user is working under other employee and is handling team of 4-5 members. I frequently need the supervisor or subordinates tree for which i am using a recursive function to fetch an employ with its team. Please suggest me a method so that I don't have to call recursive function each time I need employee data. Is using "Views or stored procedure" a good idea?
Thanks.
Upvotes: 0
Views: 348
Reputation: 16569
Here's a non recursive stored procedure implementation which obviously only requires one call from your application code not n calls (one for each level of the tree). Would recommend staying well away from nested sets and stick with you adjacency list implementation - think connect by Oracle and CTE in sql server - say no more.
drop table if exists employees;
create table employees
(
emp_id smallint unsigned not null auto_increment primary key,
name varchar(255) not null,
boss_id smallint unsigned null,
key (boss_id)
)
engine = innodb;
insert into employees (name, boss_id) values
('f00',null),
('ali later',1),
('megan fox',1),
('jessica alba',3),
('eva longoria',3),
('keira knightley',5),
('liv tyler',6),
('sophie marceau',6);
drop procedure if exists employees_hier;
delimiter #
create procedure employees_hier
(
in p_emp_id smallint unsigned
)
begin
declare v_done tinyint unsigned default(0);
declare v_dpth smallint unsigned default(0);
create temporary table hier(
boss_id smallint unsigned,
emp_id smallint unsigned,
depth smallint unsigned
)engine = memory;
insert into hier select boss_id, emp_id, v_dpth from employees where emp_id = p_emp_id;
/* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */
create temporary table emps engine=memory select * from hier;
while not v_done do
if exists( select 1 from employees e inner join hier on e.boss_id = hier.emp_id and hier.depth = v_dpth) then
insert into hier select e.boss_id, e.emp_id, v_dpth + 1
from employees e inner join emps on e.boss_id = emps.emp_id and emps.depth = v_dpth;
set v_dpth = v_dpth + 1;
truncate table emps;
insert into emps select * from hier where depth = v_dpth;
else
set v_done = 1;
end if;
end while;
select
e.emp_id,
e.name as emp_name,
p.emp_id as boss_emp_id,
p.name as boss_name,
hier.depth
from
hier
inner join employees e on hier.emp_id = e.emp_id
left outer join employees p on hier.boss_id = p.emp_id;
drop temporary table if exists hier;
drop temporary table if exists emps;
end #
delimiter ;
-- call this sproc from your php
call employees_hier(1);
Upvotes: 2
Reputation: 31685
When you use stored procedures, you will still need recursion. You only move the recursion from the PHP source code to the database.
You can use nested sets to store hierarchical data. This gets rid of recursions at the price of higher costs for insertion, deletion and relocation. Basically, you create two additional fields left
and right
where left < right
and e1
is subordinate of e2
iff e1.left > e2.left && e1.right < e2.right
.
This makes SELECT queries hard to read, but efficient. Do this when all else fails.
Upvotes: 0