2017-08-03 2 views
1

Comment serais-je en mesure de récupérer un arbre complet à partir de la structure actuelle, ou de refactoriser la structure de table actuelle pour permettre une requête récursive optimisée?Restructuration de la table de fermeture transitive

Problème

Impossible de récupérer-arborescence complète des composants du composant de base sans itération.

Un seul composant peut avoir un nombre indéfini de connexions (profondeur).

Les composants n'ont pas de propriété parent, car chaque composant peut être associé à plusieurs composants.

Impossible de mettre à jour récursivement les valeurs d'attribut affectées d'un composant. Par exemple, si le prix d'un composant change, le prix est mis à jour pour tous les components_of associés.

Structure actuelle

composant

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   | 

résultant Graphique Modèle:

graph

Exemple requête:

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

Résultat souhaité (* indique les valeurs mises à jour récursive)

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

Je pense que je devrais stocker toute la relation d'arbre dans la table component_closure, de sorte que je serais capable de récupérer les relations component_of de tous les composants et d'utiliser une colonne de profondeur pour déterminer l'ordre des composants. Bien que cela semble inutile lorsque l'arbre complet n'est pas nécessaire, comme pour components_of immédiat.

Par exemple:

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

Répondre

1

Oui, si vous voulez stocker la fermeture transitive, vous devez stocker tous les chemins.

Pour certaines opérations, il est même utile de stocker le chemin de longueur 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  | 

En MySQL 8.0, rien de tout cela sera nécessaire. Nous serons enfin en mesure d'utiliser des requêtes récursives.

+0

Merci, j'ai mis à jour les balises pour refléter 'MySQL 5.7' puisque je suis actuellement coincé avec elle. J'envisageais de passer à MariaDB 10.2.2, qui prend également en charge les CTE récursifs. – fyrye