2017-08-03 30 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