2017-08-03 29 views
1

如何从当前结构检索完整树或重构当前表结构以允许优化的递归查询?传递闭包表重构

问题

无法检索从基础构件组件的全树,而无需重复。

单个组件可能具有未定义数量的连接(深度)。

组件没有父级属性,因为每个组件都可能与多个组件相关。

无法递归更新组件的受影响的属性值。 例如,如果某个组件的价格发生变化,则会更新所有相关组件的价格。

当前结构

部件

primary key (id) 
| id | price | 
|----|------ | 
| A | 1  | 
| B | 1  | 
| C | 1  | 
| D | 2  | 
| E | 2  | 

component_closure

unique index (component, component_of) 
index (component_of) 
FK (component) References component (id) 
FK (component_of) References component (id) 
| component | component_of | 
|--------------------------| 
|  D  | B   | 
|  D  | C   | 
|  B  | A   | 
|  E  | C   | 
|  E  | A   | 

结果图型号:

graph

实施例的查询:

UPDATE component 
SET price = 2 
WHERE id = 'A'; 

所需的结果(* 表示递归地更新的值

| id | price | 
|----|------ | 
| A | 2  | 
| B | 2  | * 
| C | 1  | 
| D | 3  | * 
| E | 3  | * 

我想我需要将整个树关系存储在component_closure表中,这样我才能够检索所有组件的component_of关系,并使用深度列来确定组件的顺序。尽管在不需要全树时,这看起来很浪费,比如直接components_of。

例如:

| component | component_of | depth | 
|-----------|--------------|-------| 
| D  | A   | 1  | 
| D  | B   | 2  | 
| D  | C   | 1  | 

回答

1

是的,如果你想存储的传递闭包,你需要存储的所有路径。

对于某些操作,它甚至有帮助的存储长度为0的路径:

| component | component_of | depth | 
|-----------|--------------|-------| 
| D  | D   | 0  | 
| D  | A   | 1  | 
| D  | B   | 2  | 
| C  | C   | 0  | 
| B  | B   | 0  | 
| B  | A   | 1  | 
| A  | A   | 0  | 

在MySQL 8.0,将需要

没有这。我们终于可以使用递归查询了。

+0

谢谢,我更新了标签,以反映'MySQL 5.7',因为我目前坚持使用它。我正在考虑切换到支持递归CTE的MariaDB 10.2.2。 – fyrye