【问题标题】:Best way to manage hierarhical data in MySQL to keep track of tiers在 MySQL 中管理分层数据以跟踪层级的最佳方法
【发布时间】:2021-08-13 18:23:28
【问题描述】:

我正在开展一个项目,该项目处理与招聘相关的层级分层数据。场景如下:

  • A 雇用 B。B 现在是 A 的第 1 层
  • B 雇用 C。C 现在是 A 的第 2 层,B 的第 1 层
  • C 雇用 D。D 现在是 A 的第 3 层、B 的第 2 层和 C 的第 1 层
  • D 雇用 E。E 现在是 A 的第 4 层、B 的第 3 层、C 的第 2 层和 D 的第 1 层。
  • B 雇佣了 F。F 现在是 A 的第 2 层,B 的第 1 层
  • 删除层级中的某个人不会使任何人上移,这意味着层级结构在删除后保持不变

我将使用他们的等级来分配特定的百分比,以将它们全部指定和总计。在 MySQL 8+ 中解决这个问题的最佳方法是什么,尤其是在引入 CTE 时?我正在考虑沿袭列/路径枚举,因为我过去在 SQL Server 中使用 hierarchyid 做过类似的事情,但我想听听您对 MySQL8+ 中最佳实践/方法的看法,因为我也想要一个如果可能的话,作为参照完整性的选项。

【问题讨论】:

  • 哪个版本的 MySQL? 8.0 具有用于处理分层数据的递归 CTE。
  • 我不想成为那个人......但我说“..MySQL 8+ 尤其是引入了 CTE?”并在我最后的声明中再次提到了 MySQL8+,哈哈。您对递归 CTE 的实现想法是否与下面列出的 The Impaler 相同?

标签: mysql sql database-design hierarchical-data


【解决方案1】:

一个简单的层次结构就可以了。如果您想在删除员工后保留原始层级,则需要软删除行,而不是从表中删除它们。

例如,你可以这样做:

create table employee (
  id int primary key not null,
  name varchar(10) not null,
  active int1 default 1 check (active in (0, 1)),
  hired_by int references employee (id)
);

insert into employee (id, name, hired_by) values (1, 'A', null);
insert into employee (id, name, hired_by) values (2, 'B', 1);
insert into employee (id, name, hired_by) values (3, 'C', 2);
insert into employee (id, name, hired_by) values (4, 'D', 3);
insert into employee (id, name, hired_by) values (5, 'E', 4);
insert into employee (id, name, hired_by) values (6, 'F', 2);

update employee set active = 0 where id = 4; -- "Soft-delete" of D

然后,您可以从特定员工开始获取所有相关员工。例如,如果你想从ID = 1开始,你可以这样做:

with recursive
e as (
  select *, 0 as tier from employee where id = 1
 union all
  select r.*,
    e.tier + 1
  from e
  join employee r on r.hired_by = e.id
)
select * from e;

结果:

 id  name  active  hired_by  tier 
 --- ----- ------- --------- ---- 
 1   A     1       null      0    
 2   B     1       1         1    
 3   C     1       2         2    
 6   F     1       2         2    
 4   D     0       3         3    
 5   E     1       4         4    

您可以将上面的查询修改为反向运行(从雇用的员工开始向上层级)或横向运行(如果需要)。使用递归 CTE 很容易走图,而不仅仅是层次结构。

请参阅DB Fiddle 的运行示例。

【讨论】:

  • 谢谢!为了确保我的花生大脑正确理解这一点,您的“选择 *,0 作为 id = 1 的员工的层级”我可以指定我想要的任何 id,它总是将层级设置为 0,然后为每个雇员添加 1观点?这意味着如果我在您的示例中设置 id = 3,C 将是第 0 层,然后 D 将是第 1 层?
  • @MarlonBrando 是的,更改 WHERE 谓词以定义您想要的起点。
猜你喜欢
  • 1970-01-01
  • 2011-03-09
  • 2012-01-31
  • 2022-01-13
  • 2017-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多