1 Introduction
Pour les bases de données, quelque soit leur modèle, il existe trois types de langages de
manipulation de données (LMD) possibles: navigationnel, déclaratif et graphique.
• Langages navigationnels
Une interface navigationnelle d'un SGBD est constituée d'un ensemble d'instructions élémentaires
qui permettent à l'utilisateur de parcourir la base pas à pas: chaque instruction fournit en résultat à
l'utilisateur un objet unique (o) et positionne un pointeur système sur cet objet, permettant ainsi à
l'instruction suivante de chercher l'objet suivant de o ou l'objet (un des objets) lié à o selon tel lien.
Pour poser une requête, l'utilisateur écrit un programme à l'aide d'un langage de programmation et
des instructions de l'interface du SGBD. Les systèmes de fichiers et les SGBD réseaux et
hiérarchiques offrent des interfaces de type navigationnel.
Les SGBDO offrent tous une interface procédurale, constituée d'un langage de programmation (qui
en général est orienté-objets), des méthodes standard des classes prédéfinies de la racine de la
hiérarchie de généralisation, et des méthodes des classes définies dans le schéma de la base. Le jeu
de classes et de méthodes prédéfinies varie beaucoup d'un système à l'autre. Il contient au minimum
des méthodes permettant de naviguer dans la base d'objets en suivant les liens de composition.
Avantages des interfaces navigationnelles: leur puissance; les problèmes d'incompatibilité entre le
langage de programmation et l'interface du SGBDO sont minimisés.
Inconvénient : l'utilisateur doit écrire des programmes ... efficaces, ce qui est beaucoup plus long
qu'écrire des requêtes dans un langage déclaratif.
• Langages déclaratifs
Dans le cas d'un langage déclaratif, l'utilisateur écrit des requêtes qui spécifient uniquement ce qu'il
veut en résultat et non comment y accéder. Le résultat est un ensemble d'objets: l'ensemble des
objets qui satisfont la requête. SQL, QUEL sont des exemples de langages déclaratifs pour les
SGBD relationnels.
Avantage des langages déclaratifs: rapidité pour écrire des requêtes, l'optimisation est effectuée
par le SGBD.
Il existe encore peu de langages déclaratifs complets et formellement définis pour les SGBDO,
comme par exemple OQL proposé par ODMG et SQL3 proposé par l'ISO. Deux propositions
s'affrontent: OQL d'ODMG qui est issu du LMD de O2 et qui n'est pas compatible avec SQL, et
SQL3 qui est une vraie extension de SQL. En effet, pour passer d'un SQL (ou QUEL) relationnel à
un SQL orienté-objets (que nous appelerons SQLOO par la suite), les problèmes sont nombreux,
dus aux nouveaux concepts des modèles orenté-objets (OO). Par exemple, comment manipuler des
attributs complexes et multivalués à plusieurs niveaux, les liens de composition, les méthodes ?...
Ces problèmes et l'étude de leurs solutions font l'objet de ce chapitre.
1
• Langages graphiques ou visuels
Les SQLOO sont compliqués du fait que le modèle OO est complexe, et les utilisateurs ont du mal
à les maîtriser. Il faudra offrir aux utilisateurs des aides pour écrire leurs requêtes, tels des éditeurs
syntaxiques, ou mieux des langages visuels qui déchargent l'utilisateur du besoin de maîtriser un
langage. L'ancêtre des langages visuels est QBE en relationnel. L'idée de base de QBE est que
l'utilisateur "dessine" un exemple du résultat qu'il veut obtenir. Des valeurs exemples sont
employées pour montrer les liens entre relations (jointures).
Pour les langages visuels, le modèle OO a un avantage important sur le relationnel, car les liens
(liens de composition et de généralisation) existent dans le modèle et sont représentés
graphiquement dans les diagrammes des schémas.
Employer un langage visuel consiste à:
1/ désigner sur le diagramme (grâce à la souris) les types d'objets concernés et les liens à suivre,
2/ préciser les prédicats,
3/ désigner quels sont les types d'objets résultats.
Il existe deux types de langages visuels:
- langage visuel navigationnel : "browser", appelé parcoureur en français,
- langage visuel déclaratif: langage visuel de requêtes.
Avantage de ces langages visuels: l'utilisateur n'a plus à apprendre un langage. Il peut se consacrer
entièrement aux problèmes de son application.
2 Méthodes et encapsulation
Les SGBD classiques ont pour principe d'offrir à tous un libre accès à toutes les données. A
l'inverse, l'approche OO encapsule les données par des méthodes afin de rendre les programmes
utilisateurs indépendants des choix d'implémentation des objets. Les LMD OO de type déclaratif
suivent généralement l'approche des SGBD classiques et permettent l'accès direct aux données, ne
respectant pas l'encapsulation. Pour les LMD interactifs où les requêtes sont éphémères, ce choix se
justifie puisqu'il n'y a pas lieu de rendre indépendantes des requêtes qui ne sont pas conservées. Par
exemple dans le SGBD O2, l'encapsulation n'est pas respectée dans le mode interactif (mode
"query"), mais elle l'est dans le mode programmation.
2
Les méthodes de type fonction qui fournissent en résultat une valeur peuvent être utilisées dans les
requêtes partout où peut être cité un attribut ou une valeur. Par exemple, les deux requêtes:
Select p•age From p in Personne Where p•nom = "Dupont"
Select p•nom From p in Personne Where p•age <18
sont valables que age soit un attribut ou une fonction. Avoir la même syntaxe pour l'emploi des
attributs et des méthodes de type fonction est important. Cela permet de changer l'implantation des
attributs et fonctions sans affecter les requêtes et programmes utilisateurs existants. Par exemple,
l'attribut age peut être remplacé par un attribut date-de-naissance et par une méthode age, et vice-
versa.
En orienté objets il y a plus de concepts: objets, valeurs, oids, méthodes. Il faut choisir entre eux,
celui (ceux) qui sera le type du résultat: objets, valeur, oids ? Les requêtes portent sur des
collections d'objets de la base de données. Il faudrait donc, pour la fermeture du langage, avoir pour
résultat des collections d'objets (avec oid, valeur et méthodes associées). Ces objets doivent être,
comme les objets de la base, liés à d'autres objets par les graphes de composition et de
généralisation.
Soit, par exemple, la requête suivante (se reporter au schéma de la base FormaPerm en annexe):
Cbd: = sélection [nomC = "BD"] Cours
Si les objets du résultat (les cours de BD), contrairement aux cours de la base, ne sont pas composés
d'enseignants et d'étudiants, on ne peut pas se resservir de Cbd pour continuer une autre requête, par
exemple: chercher les professeurs qui donnent des cours Cbd (i.e. des cours de BD).
Le choix pour le résultat des requêtes, des collections d'objets est simple dans son principe, mais sa
mise en oeuvre est compliquée (voir § 6.2). Ce qui fait que peu de SGBDO ont actuellement une
solution complète.
En Orion le résultat est une collection d'objets ou une collection de tuples d'oids. En O2 le résultat
est une collection d'objets de la base ou une collection de valeurs complexes.
3
4 Structure complexe des objets
Le problème principal est comment manipuler les attributs complexes et multivalués à un ou
plusieurs niveaux. Il y a eu de nombreuses recherches: sur les modèles relationnels en non première
forme normale (NF2) et sur les modèles d'objets complexes. Des modèles ont été proposés avec des
algèbres et des calculs associés.
Personne
j m a type rappels
j m a
Exemple de représentation d'une occurrence d'objet complexe Personne (les attributs date et adr ont
été omis). L'étoile (*) dans l'entête du tableau indique un attribut multivalué.
4
Cette requête est ambiguë: les personnes qui ont transmis un (ou tous ?) de leurs prénoms à un (ou
tous ?) de leurs enfants. La requête suivante donne les personnes qui ont transmis au moins un de
leurs prénoms à au moins un de leurs enfants.
En algèbre OO:
sélection [∃prénoms (∃enfants (∃enfants•prénoms (prénoms = enfants•prénoms)))] Personne
En SQL de O2:
Select p From p in Personne
Where exists p1 in p•prénoms: exists e in p•enfant: exists p2 in e•prénoms: p1 = p2
Solution 2: Considérer les attributs complexes et/ou multivalués comme des types d'objets à part
entière, et écrire des expressions emboîtées: sur ces attributs complexes et multivalués on réutilise
les mêmes opérateurs que pour les types d'objets.
Résultat
prénoms
Il y a deux types de restructuration: avec ou sans perte de sémantique. Par exemple dans la figure 1,
supprimer le noeud adr (n°, rue, ville et codepostal deviennent attributs directs de Personne), ne
change rien à la sémantique des objets Personne. Par contre, supprimer le noeud enfants (prénoms,
dateN, sexe et vaccins deviennent attributs directs de Personne) change la sémantique des objets. Si
l'on ne veut pas perdre d'information (i.e. le fait que tel ensemble de prénoms, telle dateN, tel sexe
et tels vaccins représentent le même enfant), il faut multiplier les occurrences du résultat: créer un
objet résultat par personne et par enfant). Si l'on veut ensuite revenir aux objets initiaux (les
5
personnes) il faut regrouper les nouvelles occurrences, ce qui ne peut se faire que s'il existe un (des)
attribut(s) identifiant de Personne. S'il n'en existe pas la sémantique initiale est perdue: il y a perte
de sémantique.
Plus généralement, l'utilisateur peut vouloir, pour les besoins de son application, changer la
structure d'un objet, créer de nouvelles structures. Afin de permettre de structurer les résultats
comme le veut l'utilisateur des opérateurs ont été proposés pour effectuer ces
regroupements/dégroupements d'attributs.
Les deux opérateurs les plus fréquents sont Nest et Unnest. Nest crée un attribut complexe et
multivalué en regroupant plusieurs attributs. Il permet de passer d'une structure en première forme
normale (1NF) à une structure en NF2, ou de complexifier plus une structure déjà en NF2.
Définition :
Soit S une structure de type tuple (type d'objet complexe ou attribut complexe), d'attributs
composants A1, A2, ... Ap, alors l'opération:
nest [nom: A1, A2, ... Ai] S avec i<p
crée un nouvel attribut complexe multivalué de nom "nom", sous S, et d'attributs A1 ... Ai.
Les attributs Ai+1 ... A p deviennent la "clé" de S selon laquelle sont regroupées les valeurs de
A1 ... Ai.
Exemple: soit le type d'objet complexe Personne du tableau 1 sans les attributs date, adr et vaccins.
L'unnest de tous les attributs multivalués sera fait par l'expression suivante:
Personne1 := unnest[prénoms](unnest[enfants](unnest[enfants.prénoms]Personne))
Son résultat est donné ci-dessous (l'attribut prénoms de enfants a été renommé en
prénomE).
Personne1:
nom prénoms prénomE j m a sexe
Dupont Jean Annie 1 2 80 F
Dupont Jean Marinette 1 2 80 F
Dupont Alfred Annie 1 2 80 F
Dupont Alfred Marinette 1 2 80 F
Dupont Jean Marc 3 5 84 M
Dupont Jean André 3 5 84 M
Dupont Alfred Marc 3 5 84 M
Dupont Alfred André 3 5 84 M
Pour obtenir à nouveau le résultat initial, il faut regrouper les attributs de la façon suivante:
nest [enfants•prénoms:enfants•prénomE] nest [enfants: prénomE, j, m, a, sexe]
(nest [prénoms: prénoms] Personne1)
Attention:
Nest suivi de Unnest = identité
6
Unnest suivi de Nest ≠ identité
Par exemple, s'il existait deux objets complexes Personne de même nom mais de prénoms et
d'enfants différents, on ne retrouverait qu'un seul objet après le "renestage".
Exemple: O2 propose deux opérations, flatten et group, qui sont proches de unnest et nest.
flatten <collection de collections>
L'instruction flatten ne travaille pas sur un attribut d'un objet structuré comme nest mais sur une
collection de collections, qu'elle "aplatit" en supprimant un niveau. Le résultat est une collection à
un seul niveau.
group variable in <collection> by variable.attribut
De même l'instruction group travaille sur une collection, et non pas sur des attributs à un niveau
quelconque d'un objet structuré. L'instruction group regroupe les éléments d'une collection selon les
valeurs prises par un attribut.
Vaccin
Pour faire ce type d'opération, des algèbres emboîtées avec produit et jointure à tout niveau ont été
proposées. L'exemple précédent s'écrirait:
projection [nom, prénoms, projection [prénoms, vaccins jointure Vaccin] enfants] Personne
7
Exemple: supposons qu'il y ait dans la base, deux types d'objets, Personne de la figure 1 et
Entreprise décrit ci-dessous:
Entreprise
Si l'utilisateur demande les personnes avec les entreprises qui sont dans la même ville, veut-il/elle:
- des couples (une personne, une entreprise),
- des objets structurés (une personne, les entreprises de la ville) ?
En général, l'application a besoin d'une structure emboîtée. Pour cela, il faut des opérations de type
jointure et produit avec un objet de tête qui définit les occurrences du résultat et dans lequel sont
regroupés les objets du second opérande.
Définition: La jointure orientée de deux types d'objet, O1*O2, crée un nouveau type d'objet
complexe O, d'attributs: ceux de O1, plus un attribut complexe multivalué de nom "O2" et
d'attributs composants ceux de O2. La population de O est en bijection avec celle de O1. La valeur
des occurrences de O est composée de:
- la valeur de l'occurrence de O1 correspondante
- pour l'attribut complexe "O2": de l'ensemble des valeurs des occurrences de O2 qui satisfont le
prédicat avec l'objet de O1.
attributs de O1 O2
attributs de O2
Exemple: La réponse à la requête : "liste des personnes, avec pour chaque personne la liste des
entreprises de sa ville", sera obtenue par la jointure orientée:
Personne * [adr.ville = adr.ville] Entreprise
Attention: les opérateurs de produit et jointure orientés ne sont pas symétriques.
La jointure orientée:
Entreprise * [adr.ville = adr.ville] Personne
fournirait une liste des entreprises avec pour chacune d'elles les personnes de la ville de
l'entreprise.
5 Liens de composition
Le problème essentiel est ici de savoir si les objets composants font partie de l'objet composite. La
réponse dépend de ce qu'on veut faire de l'objet composite.
8
- soit constitué uniquement des attributs propres de la classe (uniquement les attributs de Cours);
- soit constitué des attributs propres de la classe et récursivement de ceux de ses classes
composantes (les attributs de cours et récursivement ceux de Enseignant, Etudiant, Cours,
…).
Le problème est de savoir où s'arrêter, car le graphe de composition est souvent très dense et
peut être cyclique.
La solution est de fournir en résultat uniquement les attributs propres de la classe (ici les attributs de
Cours). Si l'utilisateur veut aussi les attributs des objets composants, il doit le préciser explicitement
dans sa requête. Par exemple, en SQLOO, la requête "liste des cours":
Select c•All From c in Cours
fournit uniquement les attributs de Cours. La requête "liste des cours avec leurs enseignants"
s'écrirait:
Select c•All, c•prof•All From c in Cours
La solution retenue est alors de considérer que les objets composants font partie de l'objet
composite, comme des attributs complexes. On utilise, comme vu ci-dessus pour les objets à
structure complexe, une notation pointée pour descendre dans les attributs complexes, ou pour
passer par un attribut référence, avec des quantificateurs chaque fois que le lien (attribut valeur ou
attribut référence) est multivalué.
6 Hiérarchie de généralisation
La présence de la hiérarchie de généralisation génère deux problèmes:
- Quand une requête cite une classe d'objets, est-ce la population propre (sans celle de ses sous-
classes) ou la population globale (avec les sous classes) qui doit intervenir ?
- Le résultat d'une requête est une classe d'objets. Où la mettre dans la hiérarchie de
généralisation ?
9
1. pris dans la population propre de la classe: uniquement les personnes qui ne sont ni
enseignante ni étudiante et qui habitent à Lausanne ?
2. pris dans la population globale de la classe: toutes les personnes de Lausanne (enseignantes,
étudiantes et autres) ?
Dans ce dernier cas, sous quel format obtient-on ces personnes ?
2.1 sous leur format spécialisé (d'Etudiant, d'Enseignant ou de Personne). On obtient alors en
résultat un ensemble hétérogène. Le résultat constitue un arbre de classes.
2.2 sous leur format de Personne.
Selon les requêtes les utilisateurs peuvent vouloir obtenir l'un ou l'autre de ces résultats. Le système
Orion par exemple, offre les deux possibilités. Il permet à l'utilisateur de préciser explicitement
dans sa requête s'il/elle veut la population propre ou globale. La requête:
Select p From p in Personne Where p.adr.ville="Lausanne"
fournit la population propre de la classe Personne.
La requête:
Select p From p in Personne* Where p.adr.ville="Lausanne"
fournit la population globale; le résultat est une collection d'objets hétérogènes.
• Les langages du premier type sont dits "générateurs d'objets". Les propriétés de la nouvelle classe
sont déduites de celles des opérandes de la requête.
Exemple: pour la requête suivante qui cherche la personne Dupont:
d: = sélection [nom = "Dupont"] Personne
la nouvelle classe d a les mêmes attributs et méthodes que la classe Personne. Cependant l'objet (ou
les objets) de d ne sont pas des objets de la classe Personne. L'objet Dupont de d a un oid différent
de l'objet correspondant, Dupont, dans Personne.
Root Class
Personne d
NP nom … NP nom …
Exemple: Orion
10
Certains langages générateurs d'objets, pour pallier à cet inconvénient de duplication des objets,
créent leurs classes résultat comme des renvois sur la classe opérande. Pour l'exemple précédent, la
classe d ne contiendra qu'un seul attribut: un attribut référence pointant l'objet correspondant de la
classe Personne.
Root Class
Personne d
NP nom … personne
• Les langages du second type sont dits "à conservation d'objets". Les propriétés de la classe
résultat sont dérivées de celles des opérandes par le mécanisme d'héritage. Par exemple, pour la
requête précédente, sélection de la (les) personne(s) Dupont, le résultat est une sous-classe de
Personne.
Root Class
Personne
select (Personne)
L'opération de différence crée aussi une sous-classe (du premier opérande). Cependant tous les
opérateurs ne créent pas tous aussi naturellement une sous-classe de l'opérande.
L'opération de projection crée plutôt une surclasse, de même que l'union. Par exemple, la requête
"liste des noms des personnes":
projection [nom] Personne
crée en résultat une classe ayant le même ensemble d'oids que la classe Personne, mais avec moins
d'attributs.
11
Root Class
nom proj[nom](Personne)
Personne
NP …
Quant aux produits et jointures, cela dépend de leur type:
- produits et jointures orientés peuvent créer des sous-classes (couvrantes) de l'opérande
principal;
- produits et jointures plats qui multiplient les objets, créent forcément de nouveaux objets dont
l'identité est différente de celle de tous les objets existants dans la base. Ce dernier type
d'opération ne peut pas faire partie d'un pur langage à conservation d'objets.
Le fait que l'emplacement de la classe résultat dépende de l'opérateur, interdit de traiter de manière
uniforme toutes les requêtes, notamment les expressions comprenant plusieurs opérateurs.
Par exemple, où placer le résultat de la requête suivante qui recherche l'adresse de Dupont:
projection[adr] sélection[nom="Dupont"] Personne
Cette classe résultat a moins d'oids et moins d'attributs que la classe Personne. Ce n'est ni une sur-
classe, ni une sous-classe de Personne:
Root Class
Personne ? proj.select(Personne)
select (Personne)
Solutions:
− Séparer la notion d'héritage de la notion d'inclusion de population (solution qui a été adoptée
dans quelques prototypes tels que COCOON et DUAL)
− Assouplir les règles d'héritage: non toujours automatique
− Avoir un autre type de lien: lien de dérivation.
Solution mixte
Les opérateurs créent des sous-classes de l'opérande, sauf le produit et la jointure plate qui créent
une nouvelle classe sous la racine et génèrent de nouveaux oids.
7 Plusieurs égalités
L'introduction des oids a donné naissance à plusieurs égalités:
- le test d'identité (même oid)
- le test d'égalité de valeur au premier niveau (égalité de surface)
- le test d'égalité de valeur au niveau des feuilles (égalité en profondeur)
Pour les prédicats, les LMDs proposent en général les deux premiers comparateurs.
12
7.1 Impact sur la gestion des doubles
En relationnel, un opérateur "crée" des doubles, c'est la projection. Dans la théorie relationnelle ces
doubles sont aussitôt éliminés, car une relation est un ensemble de tuples. Par contre, en OO on
gère des collections qui permettent en général les doubles (multi-ensemble, liste, tableau,…).
En OO, qu'est-ce qu'un double: deux occurrences de la même classe avec même valeur, ou deux
références au même objet ? Orion, par exemple, a deux mots-clés différents pour permettre à
l'utilisateur de supprimer les doubles d'une collection:
Select UNIQUE p From p in <collection>
qui signifie ne garder qu'une fois chaque objet
Select UNIQUE VALUE p From p in <collection>
qui signifie supprimer les objets qui ont même valeur au premier niveau: n'en garder qu'un (au
hasard).
La comparaison portant sur les oids, les valeurs de deux représentations du même objet dans les
deux classes peuvent être différentes, quelle est alors la valeur de l'objet résultat? Quel est sont
type?
Pour la différence,
C1 différence C2
le résultat est défini comme étant l'ensemble des objets de C1 qui ne sont pas dans C2. Le type du
résultat est donc celui de C1, et les objets ont pour valeur, leur valeur dans C1.
Pour l'union,
C1 union C2
le type résultat doit permettre de décrire les objets provenant de C1 et C2. La solution la plus
fréquente est de créer une sur-classe commune à C1 et C2, ayant pour propriétés celles communes à
C1 et C2. Cela pose le problème des objets de même oid qui ont pour le même attribut (même nom
et même domaine) des valeurs différentes.
Pour l'intersection,
C1 intersection C2
le résultat est une sous-classe commune à C1 et C2. Il faut alors gérer dynamiquement les conflits
d'héritage qui peuvent ainsi avoir été créés.
8. Mises à jour
13
Pour les mises à jour les problèmes sont semblables à ceux rencontrés pour les requêtes
d'interrogation:
- mises à jour d'objets de structure complexe: comment accéder aux attributs composants pour
les modifier ?
- mise à jour d'objet appartenant à une hiérarchie de généralisation: mises à jour induites par les
insertions et suppressions d'objets, migrations d'objets d'une classe à une autre;
- mise à jour d'objets composites ou composants: manipulation des attributs référence en
SQLOO, maintient de l'intégrité référentielle.
Exemple format d'instruction de mise à jour d'attribut avec notation pointée et variables implicites:
Update c in nom-classe
[ Where <prédicat sur c> ] /* choix des occurrences c de la classe à mettre à jour */
< valeur > (si att n monovalué)
< ensemble de valeurs > (si att multivalué)
n
Set att1•att2• ... • attn =
add < valeur > (si att n multivalué)
delete (si att n multivalué)
[Where <prédicat sur att1 • ...• attn>] /*choix de la/les valeurs de attn à mettre à jour */
14
Exemple:
Personne
type dates j m a
De même supprimer un objet peut signifier soit supprimer complètement l'objet de la base, soit en
supprimer une représentation (son appartenance à telle classe).
Personne
Etudiant Enseignant
Une même personne, par exemple Annie, peut au cours de sa vie changer plusieurs fois de classe, et
conduire au cycle de vie suivant pour l'objet Annie:
15
Personne
Etudiant
Etudt1
Etudt2
Etudt3
temps
Enseignant
Attention: La plupart des SGBO actuels ne permettent pas encore ces changements de classe
(newrepr, deleterepr) car ils peuvent impliquer de changer le format de l'enregistrement décrivant
l'objet et de le changer de place physiquement.
Pratiquement pour un SGBDO, cela consiste à vérifier lors des mises à jour de la base que les
attributs référence pointent toujours des objets existants :
16
Lors de l'affectation d'un attribut référence, le mécanisme de typage du système effectuera
automatiquement la vérification que la "valeur" affectée soit bien du bon type, i.e. un oid de la
classe (ou d'une sous-classe) qui est le domaine déclaré pour cet attribut - ou la valeur nulle -.
Lors de la suppression d'un objet composant, le système doit (devrait) rechercher dans la base tous
les attributs référence pointant cet objet, pour les mettre à "nul". La réalisation de cette dernière
fonction est coûteuse. Une solution est que le système conserve en interne les références inverses
(aux objets composites pointant l'objet composant). C'est la solution d'ONTOS. Une alternative est
de ne pas offrir d'instruction de destruction d'objet dans l'interface utilisateur. Un objet est
implicitement détruit quand il n'est plus référencé. C'est la solution d'O2.
Un autre type de mise à jour induite par les liens de composition arrive lors de la destruction d'un
objet composite dont un (des) composant a été déclaré dépendant pour son existence. Par exemple,
la classe composite Immeuble a pour classe dépendante Appartement. Lors de la destruction d'un
objet composite (d'un immeuble), les objets composants dépendants (les appartements de
l'immeuble) sont détruits automatiquement par le SGBDO. Cette destruction induite est récursive.
Le cas inverse est celui de la création d'un objet composite dont un attribut référence est obligatoire
(valeur nulle interdite), par exemple dans la classe Cours de FormaPerm, l'attribut référence prof.
Dans ce cas l'utilisateur ne peut créer un objet composite (un cours) qu'après avoir créé son (ses
objets composants (son prof).
9 Conclusion
Ces nouveaux SQLOO ont a leur actif d'être très puissants (en quelques lignes l'utilisateur peut
écrire une requête très complexe) et d'être compatibles (presque complètement) avec les langages
de programmation hôtes. Mais il reste des problèmes ouverts qui sont essentiellement:
- ces langages n'utilisent que partiellement les méthodes. Notamment les méthodes associées au
type résultat sont très rarement définies;
17
- ces langages ne permettent pas toutes les utilisations qui sont possibles en relationnel,
notamment la définition de vues ou la modification de schéma;
- il y a actuellement une forte bataille pour la définition d'un SQLOO standard, et pas encore de
consensus.
18