Lorsqu'on veut représenter une hiérarchie (une arborescence), la méthode la plus couramment utilisée est la structure par auto-jointure, c'est à dire avec une relation parent/enfant.

Représentation graphique de l'arborescence
S'il est facile de trouver le parent d'un élément ou les élements enfants de premier niveau avec des requètes simples, ça se complique énormément sitôt que l'on veut aller à des niveaux plus bas, il faut utiliser des requètes récursives qui ne peuvent pas être mises en place partout.
Ce système de classification est donc à proscrire si au moins l'une des conditions ci-dessous est vérifiée:
- l'arbre est profond (plus de 5 niveaux)
- l'arbre est large (plus de 100 éléments sur un même niveau)
- l'arbre contient beaucoup de valeurs (à partir de 200 à 300 éléments)
- la majorité des requêtes sont des requêtes d'interrogation - SELECT (au moins 50% des requêtes)
Il existe une seconde méthode qui nécessite un peu plus de travail pour la modélisation mais qui s'avère payante sitôt qu'on en a pris l'habitude: la représentation
intervallaire.
Le principe est de donner à chaque élément ses bornes "gauche" et "droite". L'attribution des valeurs de ces bornes se fait en parcourant l'arbre comme si l'on traçait une ligne pour l'entourer au plus près sans jamais croiser cette ligne avec une branche et en numérotant séquentiellement chaque feuille ou nœud une première fois par le bord gauche et une seconde fois par le bord droit.

Représentation graphique de l'arborescence
On peut aussi représenter cette nouvelle arborescence sous forme de "tranches":

Représentation par tranches
Voici la requète de création (et de remplissage) de la table représentant cette structure:
CREATE TABLE NEW_FAMILLE (
NFM_BG INTEGER,
NFM_BD INTEGER,
NFM_LIB VARCHAR(16)
)
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (1, 44, 'Transport')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (2, 21, 'Aérien')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (3, 4, 'Planeur')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (5, 6, 'Parachute')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (7, 8, 'Hélico')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (9, 10, 'Fusée')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (11, 12, 'ULM')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (13, 20, 'Avion')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (14, 15, 'Militaire')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (16, 17, 'Tourisme')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (18, 19, 'Civil')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (22, 35, 'Terrestre')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (23, 24, 'Vélo')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (25, 26, 'Voiture')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (27, 28, 'Camion')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (29, 34, 'Moto')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (30, 31, 'Side-car')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (32, 33, 'Trail')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (36, 43, 'Marin')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (37, 38, 'Planche à voile')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (39, 40, 'Paquebot')
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (41, 42, 'Voilier')
Recherches dans l'arbre
Les requètes de recherche sont maintenant très simplifiées:
Recherche des "feuilles"
Une feuille est un élément final, donc l'écart entre sa borne gauche et sa borne droite est de 1:
SELECT *
FROM NEW_FAMILLE
WHERE NFM_BD - NFM_BG = 1
Recherche des feuilles d'une branche
Les bornes d'une branche indiquent les éléments précédents et suivant, il nous suffit donc de lister tous les éléments dont les bornes sont strictement comprises entre BG et BD de la branche pour avoir l'intégralité des sous-éléments.
Par exemple pour la famille "terrestre" donc BG=22 et BD=35:
SELECT *
FROM NEW_FAMILLE
WHERE NFM_BD - NFM_BG = 1
AND NFM_BG > 22
AND NFM_BD < 35
Recherche des noeuds
Un noeud se caractérise par le fait que BD-BG est supérieur à 1:
SELECT *
FROM NEW_FAMILLE
WHERE NFM_BD - NFM_BG > 1
Insertions
L'insertion d'un élément oblige bien évidemment à faire plusieurs requètes:
La première pour décaler les bornes droites des éléments suivants ainsi que du parent, la seconde pour décaler les bornes gauches des éléments suivants et enfin la dernière pour insérer le nouvel élément.
Ainsi, si l'on veut ajouter un élément "Roller" dans la famille terrestre, il va falloir:
- Augmenter de 2 la valeur de toutes les bornes droites dont la valeur initiale est supérieur ou égale à 35 (ce qui inclut le parent),
- Augnemter de 2 la valeur des toutes les bornes gauches dont la valeur initiale est supérieure ou égale à 35 (ce qui exclut le parent),
- Insérer le nouvel élément.
UPDATE NEW_FAMILLE SET NFM_BD = NFM_BD + 2 WHERE NFM_BD >= 35
UPDATE NEW_FAMILLE SET NFM_BG = NFM_BG + 2 WHERE NFM_BG >= 35
INSERT INTO NEW_FAMILLE (NFM_BG, NFM_BD, NFM_LIB) VALUES (35, 36, 'Roller')