November 23, 2024, at 10:30 AM | Hala Skaf-Molli / Main / LecturesOn |
|
LecturesOnL’Orienté Objets dans les bases de données Pourquoi ? Modéliser des objets complexes, la réutilisation
ODL (Object Definition Langauge) c’est un standard pour les bases de données OO developpé par OMG. Il s’agit d’une extension de IDL (Interface definition Language). IDL est un component de CORBA Common Object Request Broker Architecture dont l’objectif est de faire la programmation OO distribuée. b. Langage de requêtes : OQL : Object Query Language : 1. un langage de requêtes standard pour les bases de données orientés objets. 2. SQL-Like Syntaxe. 3. ramène le meilleur de SQL dans le monde Orienté Objets..
a. faire une extension objets de SQL. L’extension est SQL-99 (SQL3?) b. le modèle de données est les relations et on ajoute des possibilités de définir de type complexe. c. On prend comme exemple l’extension objets dans Oracle.
a. faire correspondre les données contenue dans un modèle objet avec les données contenues dans une base de données relationnelle. b. quels sont les problèmes .. c. on prend comme exemple JPA (JAVA Persistence API) (Hibernate) Bases de données Orienté objets : Dans le modèle de données ODL, on a les classes. Une classe possède trois propriétés : Attribut, association, methodes. Exemple : Déclaration de classe : class <name> { liste de propriétés} Exemple 1: Class Film { Attribute String Titre ; attribute integer annee; attribute integer longueur; attribute enum Movie {couleur, BlancetNoir?} filmType ; } Un objet Film {« Gone with Wind »,1939,231,color) Exemple 2: Class Acteur { attribute String nom; attribute Struct addr {String rue, string ville} Adresse; }; le type d’adresse est record .. Les associations binaires dans ODL : Question : attacher à chaque film les acteurs de ce film ? Dans Film, j’ajoute : Class Film { Attribute String Titre ; attribute integer annee; attribute integer longueur; attribute enum Movie {couleur, BlancetNoir?} filmType ; relationship Set <Acteur> Stars; } Chaque objet de la classe Film référence un ensemble d’objets de la classe Acteur. L’association inverse : Dans Acteur : Class Acteur { attribute String nom; attribute Struct addr {String rue, string ville} Adresse; relationship set<Film> StarredIn? inverse Film::Stars; }; De manière générale, R(C,D) C D x1 y1 x2 y2 la relation inverse : D C y1 x1 y2 x2 Cardinalité des associations : comme dans le modèle E/A, il y 4 cardinalité : 1. many-many : 2. many-one 3. one-many 4. one-one Exemple: Les associations 3-ways: Schéma E/A, Diagram UML: Les types dans ODL: 1. type atomique : integer, stringe, float, 2. le nom d’une classe 3. constructeur de type : Set, List, Bag, Array, Dictionnary a. si T type alors Set<T>, Bag<T> Exemple : Bage<integer> : {1,2,1} le bag n’est pas un ensemble b. si T type alors List<T>, c. Array<T,i> Array<chat,10> String de longueur 10. d. Dictionnay<T,S> : key type et rang type… Set, list, bag, array, dictionnary sont de type collection.. Strcuture : if T1………Tn sont de types et f1….fn sont de champs alors strcut N{T f1,T2 f2 ..} Méthodes : une déclaration et une implantation.. la déclaration est comme la déclaration de fonction en C avec les paramètres (IN, INOUT, OUT) ..on traite les exceptions… Exemple : Class Film { Attribute String Titre ; attribute integer annee; attribute integer longueur; attribute enum Movie {couleur, BlancetNoir?} filmType ; relationship Set <Acteur> Stars; float starNames(out Set<String>); float lengthInHours() raises(noLengthFound); } On ajoute la signature des méthodes… Sous Classe dans ODL : Diagramme UML : exemple : class Cartoon extends Film{ relationship set <Acteur> voix; } Extent: Il permet de faire la distinction entre la classes et ses instances (l’ensemble d’objets de cette classe). En relationnel, on fait la différence entre relation et ses instances (ses tuples ..) Exemple : Class Film (extent Films) { attribute .. } On utilise Films dans OQL. Le langage de requêtes OQL : 1. Introduction: OQL : Object Query Language · C’est un langage de requêtes standard pour les bases de données OO. · Le modèle de données utilisé est ODL · OQL a les mêmes notations que SQL (SQL-Like requêtes). · Les types en OQL comme dans le ODL, · Set(Struct), Bag(Struct ) le role de relations · Il est possible de mixer de requêtes avec un langage hôte (c++, smalltalk, java) sans avoir les problème de conversion de type et les problèmes de paradigms différents comme c’est le cas avec JDBC. 2. Expressions de chemins : On utilise ‘.’ pour accéder aux components d’une classe. Soit x un objet de la classe C : 1. si a est un attribut de C, alors x.a est la valeur de cet attribut. 2. si r est une association de C alors, x.r est la valeur de l’association a. soit un objet ou un ensemble d’objets selon le type de r. 3. si m est une méthode de C, alors x.m(..) est le résultat de l’appel de la méthode m à x. Exemple : Extrait en ODL de la base de données Orienté Objets de film Class Film (extent Films key (titre, année)) { Attribute String titre ; attribute integer année; attribute integer longueur; attribute enum Movie {couleur, BlancetNoir?} filmType ; relationship Set <Acteur> stars inverse Acteur::filmographie; relationship Studio producteur inverse Studio::produit; float starNames(out Set<String>); float lengthInHours() raises(noLengthFound); } Class Acteur (extent Acteurs key nom) { attribute String nom; attribute Struct addr {String rue, string ville} adresse; relationship set<Film> filmographie inverse Film::stars; }; Class Studio (extent Studios key nom) { attribute string nom; attribute string Adresse; relationship set<Film> produit inverse Film::producteur; } L’expression de chemins: Soit monFilm un objet de la classe Film : a. monFilm.titre = le nom de l’objet monfilm. b. monFilm.producteur.nom : le nom du studio qui a produit monFilm. c. monFilm.stars.nom : pas légal , stars est un ensemble .. C’est possible si stars est un objet.. 3. OQL Select-From-Where Select <liste de valeurs> /* le résultat de la requête */ from <liste de collections et les noms de membres> /* l’extent d’un classe : Films où bien une expression dont l’évaluation donne une collection, e.g. monFilm.stars */ where <condition> Exemple 1 : afficher l’année de sortie du film ‘Gone with the Wind’. select f.annee /* le résultat de la requête */ from Films f /* Une collection, c’est l’extent de la classe Film, m c’est un alias */ where f.titre=”Gone With the Wind”; /* la condition, mêmes conditions que SQL */ attention: OQL utilise le double-quotes on fait une itération sur la collection Films … pour chaque f dans Films faire if f.titre=”Gone With the Wind” alors ajouter f.année au résultat autre syntaxe : select f.annee /* le résultat de la requête */ from f in Films where f.titre=”Gone With the Wind”; Le type d’un résultat : Par défaut, le type du résultat d’une requête est un bag (ensemble avec duplication ) type de résultat : bag<int> ; Exemple 2 : Afficher les noms d’acteurs ayant joué dans le film «Gone With the Wind ». select a.nom from f in Films , a in f.stars where f.titre=”Gone With the Wind”; type de résultat : bag<String> ; select a.nom from Films f, f.stars a where f.titre=”Gone With the Wind”; Exemple 3 : Trouver les noms d’acteurs ayant joué dans un film produit par « Disney » ? select a.nom from Films f, f.stars a where f.producter.nom=”Disney”; type de résultat : bag<String> ; Renommer le résultat : il suffit de précéder le nom de champ par le nom avec : Exemple 4 : select Star: a.nom from Films f, f.stars a where f.producter.nom=”Disney”; type de résultat : bag<String> Changement de type de résultat: · En ajoutant le mot clé DISTINCT ou UNIQUE : j’obtiens un ensemble. Exemple 5: select DISTINCT a.nom from Films f, f.stars a where f.producter.nom=”Disney”; Type de résultat: set<String> · En ajoutant ORDER BY : j’obtiens une liste Exemple 6: select f from Films f where f.producter.nom=”Disney”; order by f.longueur, f.titre ; Type de résultat: list<Film> Requête avec de résultat de type complexe : Exemple 7 : trouver les couples d’acteurs qui habitent à la même adresse. select DISTINCT Struct(acteur1 : a1, acrteur2 : a2) from Acteurs a1, Acteurs a2 where a1.adresse =a2.adresse and a1.nom < a2.nom Type de résultat : set<Struct{acteur1 : Acteur, acteur2 : Acteur}> Sous Requêtes : Une expression select-from-where peut être utilisée comme une sous requêtes : · dans from comme une collection · dans les expressions exists et FOR ALL Exemple 8: Trouver les acteurs des films produit par « Disney » . select DISTINCT a.nom from (select f frim Films f where f.producter.nom=”Disney”) d , d.stars a Quantificateurs : il existe deux expressions booléenne utilisable dans where : FOR ALL x in <collection> : <condition> /* vari si tous les membre de la collection vérifies la condition */ Exists x IN <collection>: condition /* vrai s’il existe un membre de la collection qui vérifie la condition */ Exemple 9 : Trouver les acteurs ayant joué dans les films produit par « Disney » . select a from Acteurs a where exists f in a.filmographie: f.producteur.nom=”Disney” Exemple 10: Trouver les acteur qui ayant joué seulement dans les films produit par « Disney ». select a from Acteurs a where for all f in a.filmographie : f.producteur.nom=”Disney” Fonctions d’agrégations : · AVG, SUM, MIN, MAX et count sont appliquées aux collections. Exemple 11: AVG(select f.longueur from Film f) Si le bag contient un seul élément, alors on a besoin de définir un opérateur ELEMENT tel que : ELEMENT(bag(x))= x Exemple 12 : donner le nom des acteurs ainsi que le nombre de films joués par ces acteurs. select struct (name: a.nom, filmcount :count(a.filmographie)) where Acteurs a order by name type de résultat : list<struct{name :String, filmcount :integer}> Extension Orienté Objet de SQL (Objet-relationnel SQL 99, SQL3?) Objet-Relationnel : 1. faire une extension objets de SQL. L’extension est SQL-99 (SQL3?) 2. le modèle de données est les relations et on ajoute des possibilités de définir de type complexe. 3. On prend comme exemple l’extension objets dans Oracle. On utilise deTypes définis par l’utlisateur UDT (User-Defined-types). Les classes de ODL sont transformées à de types définis par l’utilisateur en SQL. Modèle objet-relationnel
Pourquoi étendre le modèle relationnel ?
est très coûteuse car elle occasionne de nombreuses jointures
des données très volumineuses du multimédia en permettant leur partage simplement et à moindre coût (sans jointure)
de souplesse et une interface difficile avec les applications orientées objet
(User data type), avec des fonctions ou procédures associées comme dans les classes des langages objet
Les nouvelles possibilités de l’OR
Définition de types dans SQL99? : Nouveaux types prédéfinis Le relationnel objet ajoute des types prédéfinis à la norme SQL :
Type défini par l’utilisateur (UDT) : 2 types possibles :
create type poids as integer ; create type age as integer; create table Personne ( personneID varchar(20) primary key, personneAge age, personnePoids poids); ces types s’utilisent exactement avec les mêmes instructions que le type de base sous-jacent. je n’ai pu tester dans Oracle..
Ils peuvent contenir des constructeurs (chaque UDT a un constructeur de même nom que UDT) , attributs ( variables d’instances), fonctions et procédures (méthodes)
Création d’un type de données Create type T as <attributes and methode declarations> ; La syntaxe ressemble à l’ODL sauf que :
Plusieurs tables peuvent avoir les mêmes types avec de clés différentes
Les associations sont présentées par de tables séparées. Un UDT peut -être le type :
Exemple 1 : UDT est utilisé comme un type d’un attribut dans la déclaration un autre UDT '' create type personneTas ( nom varchar(20), rue varchar(30), ville varchar(20) ) ; '' Dans Oracle: CREATE OR REPLACE TYPE <type_name> lieu varchar(20)) ; \\'' ATTENTION: dans SQL standard pas OBJECT après le AS .. Attention, un type ne peut pas contenir de contrainte d’intégrité je peux utiliser la commande « create or replace ». create type departementT as Object ( SQL> desc user_source Name Null? Type ------------------------------- -------- ---------------- 1 NAME VARCHAR2?(30) 2 TYPE VARCHAR2?(12) 3 LINE NUMBER 4 TEXT VARCHAR2?(4000) SQL> SELECT * FROM user_source WHERE name = 'DEPARTEMENT'; Les méthodes dans UDT : Déclaration : On déclare les méthodes dans la définition de UDT : create type departementT as Object ( create type body personneType as member function getLieu return varchar is begin return lieu; end; end; Héritage (création de sous type) Les types supportent l’héritage multiple avec le mot-clé UNDER : CREATE OR REPLACE TYPE <type_name> UNDER <supertype_name> ( <attribute> <data_type>, <inheritance clause> <subprogram spec>, <pragma clause>) <FINAL | NOT FINAL> <INSTANTIABLE | NOT INSTANTIABLE>; / create type personT as Object ( nom varchar(20), rue varchar(30), ville varchar(20), Member Function getNom return varchar) not final; Le type est final par défaut. -- derive collection type from supertype CREATE OR REPLACE TYPE person_tab_typ AS TABLE OF person_typ; // derive object subtype from object supertype create or replace type etudiantT under personT ( note float) not final ; -- derive collection type from subtype CREATE OR REPLACE TYPE student_tab_typ AS TABLE OF student_typ; / -- create nested table from the two collection CREATE TABLE test ( regular_field DATE, person_nested_tab person_tab_typ, student_nested_tab student_tab_typ) NESTED TABLE person_nested_tab STORE AS per_tab NESTED TABLE student_nested_tab STORE AS stu_tab; desc test desc per_tab desc stu_ta Ajout d’un attribut dans un type : alter type etudiantType add attribute date_naissance date cascade ; // propager aux tables déjà construites à partir du type. SQL> desc etudiantType etudiantType extends SKAF.PERSONT etudiantType is NOT FINAL Name Null? Type ------------------------------- -------- --------------------- 1 NOM VARCHAR2?(20) 2 RUE VARCHAR2?(30) 3 VILLE VARCHAR2?(20) 4 NOTE FLOAT(126) 5 DATE_NAISSANCE DATE METHOD MEMBER FUNCTION GETNOM RETURNS VARCHAR2?
Ajout d’une méthode/fonction à un type : alter type etudiantType add member function age return integer cascade; Type de ligne: aux structures du C : c’est un ensemble non encapsulé d’attributs
Type de ligne non nommé create table EMP (nomE varchar(35), adresse ROW(numero integer, rue varchar(30))) ne marche pas dans Oracle Type de ligne nommé CREATE ROW TYPE adresse_t (numero integer, rue varchar(30))
d’attribut ou même pour créer une table à partir de ce type (comme pour les autres types) ne marche pas dans Oracle Vues du dictionnaire des données
Sous sqlplus de Oracle : describe etudiantType VALUE N SQL> SQL> desc user_types SQL> Name Null? Type ------------------------------- -------- ----------------------- 1 TYPE_NAME NOT NULL VARCHAR2?(30) 2 TYPE_OID NOT NULL RAW(16) 3 TYPECODE VARCHAR2?(30) 4 ATTRIBUTES NUMBER 5 METHODS NUMBER 6 PREDEFINED VARCHAR2?(3) 7 INCOMPLETE VARCHAR2?(3) 8 FINAL VARCHAR2?(3) 9 INSTANTIABLE VARCHAR2?(3) 10 SUPERTYPE_OWNER VARCHAR2?(30) 11 SUPERTYPE_NAME VARCHAR2?(30) 12 LOCAL_ATTRIBUTES NUMBER 13 LOCAL_METHODS NUMBER 14 TYPEID RAW(16) Tables Création d’une table à partir d’un type
Syntaxe : create table <table name> of <type name> ; create table etudiantTable of etudiantType; La table etudiantTable correspond à (extent) d’une classe dans un schéma ODL
'' create table etudiantTable of etudiantType (primary key(nom));'' on peut dooner un nom à la contrainte: '' create table etudiantTable of etudiantType (constraint pketud primary key(nom));'' Héritage de tables Une table peut hériter d’une ou plusieurs tables. pas supporté par Oracle 10g. ''' Caractéristiques d’une table objet-relationnelle'''
à partir d’un type (create table … OF)
des objets avec un identifiant (OID)
les lignes de ces tables (pas possible pour les autres tables) Vues du dictionnaire des données USER_OBJECT_TABLES pour les tables objet relationnelles Problème avec l’accès aux champs dans Oracle
''' Accès à un champ dans Oracle :''' select addr.rue from Acteurs ; Non select Acteurs.addr.rue from Acteurs; NON Juste: select aa.addr.rue from Acteurs aa; Insertion de données create table etudiantTable of etudiantType; insert into etudiantTable values(‘Dupond’, 'laxou',’nancy’,10,’22-dec-02’); Insertion avec constructeur
la table a été construite : Dans Oracle, on utilise la syntaxe d’insert avec le constructeur de type.. insert into etudiantTable values(etudiantType(‘Dupond’, 'laxou',’nancy’,10,’22-APR-02’)); Modifications update etudiantTable set etudiantTable.note= 12 where eudiantTable.nom = 'titi'; update etudiantTable set etudiantTable.adresse..numero = 12 where etudiantTable.nom = 'titi'; ''' Appel de procédure ou fonction''' select e.nom, age(e) // Le « this » est passé en paramètre from etudiantTablee where age(e) < 40 Sous Oracle : select e.nom, e.age() from etudiantTable e where e.age() < 40 ''' Références:'''
la syntaxe est « REF nom-du-type » : (C’est un pointeur vers un objet de type nom-du-type)
mais c’est de ‘gibberish’ ‘charabia’ create type employeType as Object ( nom varchar(20), rue varchar(30), ville varchar(20), dept REF depType); Exemple de select avec référence
select nom, e.dept.lieu from employe e En SQL99? : select nom, e.dept->lieu from employe e Attention, l’alias e est indispensable ''' Insertions avec référence''' insert into employe values ( 1230, 'Durand', …, NULL); pointeur NULL insert into employe(matricule, nom, dept) select 1240, 'Dupond', REF(d) from dept d where dept.numDept = 10; référence vers le dept de numéro 10 ''' Constructeur de type''' Exemple select * from TableActeurs? ; résultat: ActeurType?(‘jacjkson’,‘malibou’,’Los Engeles’)) L’accès à une valeur d’un RowType? 1. dans Oracle le point marche comme prévu . C’est une bonne habitude d’utiliser un alias quand on utilise les fonctionnalités O-R.. Exemple : select ta.name from TableActeurs? ta ;
Exemple : la même reqte en SQL-99 : select ta.name(), ta.rue(), ta.ville() from TableActeurs? ta; ''' Suivre le REF dans le style SQL-99''' A ->B a de sens si : 1. A est de type REF T 2. B est un attribut (component) d’objets de type T 3. donne la valeur du component B de l’objet pointé par A. Exemple : Acteur(name, addr) select aa.addr()->rue /use generator method pour accéder aux component et la fleche pour accèder aux champs référencé.. from Acteurs aa where aa->name =’Jackson’ ''' Suivre le REF Dans Oracle'''
Exemple : select aa.addr.rue from Acteurs aa where aa.name =’Jackson’ L’opérateur DEREF d’Oracle—Motivation Question : trouver l’adresse de ‘Jackson’ ? select aa.addr from Acteurs aa where aa.name=’Jackson’; c’est légal mais aa.addr c’est un REF, c’est de Charabia … on va utiliser DEREF.. pour voir l’objet AdresseType?, on écrit : select DEREF(aa.addr) from Acteurs aa where aa.name=’Jackson’; le résultat: AdresseType?(‘Malibou’, ‘Los Angeles’) Les méthodes-- Les classes sont plus qu’une structure de données, elles ont des méthodes. La définition de méthodes dans Oracle : 1. On déclare les méthodes dans create type. 2. on définit les méthodes in create type body : a. on utilise la syntaxe de PL/SQL b. la variable self fait référence à l’objet auquel j’applique la méthode. Exemple : la déclaration de méthode create type ActeurType? as object (name varchar(20), addr REF AdresseType?, salaire float, member function salaireInEuros(rate IN FLOAT) return FLOAT, PRAGMA RESTRICT_REFERENCES(salaireInEuros,WNDS)) ; ‘Write No Data State » : l’appel de la méthode ne change pas la base de données .. La définition de méthode (le style d’Oracle) CREATE TYPE BODY <type name> AS <method definitions = PL/SQL procedure definitions, using “MEMBER FUNCTION” in place of “PROCEDURE”> END; / Exemple: CREATE TYPE BODY ActeurType? AS MEMBER FUNCTION SalaireInEuros?(rate FLOAT) RETURN FLOAT IS BEGIN RETURN rate * SELF.salaire; END; END; / No mode (IN) in body, just in declaration Use parentheses only when there is at least one argument UTILIsation? de méthode: Exemple : select aa.salaire, aa.salaireInEuros(1.44) from Acteurs aa where aa.name=’Jackson’ ; Méthodes dans UDT: ‘123 rue de villers’ , NumberMaison? donne : 123 Déclaration de méthodes : create type AdresseType? as ( rue varchar (50); ville varchar(20) ) method NumeroMaison?() returns varchar(10); Définition de methods create method NumeroMaison? () returns varchar(10) for AdresseType? begin end; De modèle ODL au modèle relationnel : ODL est fait pour être implémenté dans une base de données OO. on va essayer de l’implémenter dans une base de données relationnelles. Transformer E/A vers relationnel.. Transformer ODL vers relationnel… Problèmes : 1. les classes n’ont pas de clé : solution transformer un attribut en une clé.. 2. type complexe, j’obtient de relations pas normalisé..il faut normaliser 3. et les méthodes ??? ici on suppose pas de méthodes .. Transformer les ODL en relations : 1. Solution simple : 1. chaque classe devient une relation.. 2. chaque propriété devient un attribut ça marche si : 1. les propriétés sont des attributs (pas des associations, pas de méthodes ..) 2. les types des attributs sont atomiques (pas de Set, Struct ..) Exemple : la classe Film Class Film (extents Films) { Attribute String Titre ; attribute integer annee; attribute integer longueur; attribute enum Movie {couleur, BlancetNoir?} filmType ; } Devient la realtion Films : Films(titre,annee,longueur, filmType) ; Pour chaque objet dans extents correspond un tuple dans la relation Films. Cas des attributs non atomiques : Cas simple : record (Struct) avec de champ dont les valeurs sont atomiques. Présenter chaque champ par un attribut dans la relation de la classe : Exemple : Class Acteur (extent Acteurs) { attribute String nom; attribute Struct addr {String rue, string ville} Adresse; relationship set<Film> StarredIn? inverse Film::Stars; }; Acteurs(nom,rue,ville) Cas des attributs de type Set : Idée : représenter les attributs non atomiques dans relations. Les valeurs de l’ attributs sont présentée par de tuples, Exemple 1: Class Acteur (extent Acteurs) { attribute String nom; attribute set < Struct addr {String rue, string ville} > Adresse; }; Exemple : j’obtiens de relations non normalisées ?? Pourquoi ?? |
Validate the XHTML and CSS of this page. | Page last modified on April 30, 2007, at 01:46 PM | Edit History Print Recent Changes |
Powered by PmWiki |